본문 바로가기

개발하자

조건을 기다리는 동안 테라폼 조타 장치 해제 시간 초과

반응형

조건을 기다리는 동안 테라폼 조타 장치 해제 시간 초과

나는 테라폼을 사용하여 몇 가지 자원을 애저에 프로비저닝하고 있는데 조건을 기다리는 동안 시간이 초과되어 nginx-ingress를 설치할 조타 장치를 구할 수 없는 것 같다

  • helm_release.nginx_messages: 1개의 오류가 발생했습니다:

  • helm_release.nginx_filename: rpc 오류: 코드 = 알 수 없는 설명 = 릴리스 nginx-filename 실패: 조건을 기다리는 동안 시간 초과됨

테라포름은 오류가 발생해도 자동으로 롤백되지 않습니다. 대신 Terraform 상태 파일이 성공적으로 완료된 리소스로 부분적으로 업데이트되었습니다. 위의 오류를 해결하고 인프라를 점진적으로 변경하려면 다시 신청하십시오. main.tf

data "azurerm_public_ip" "nginx_ingress" {
    name                = "xxxx-public-ip"
    resource_group_name = "xxxx-public-ip"
}

resource "azurerm_resource_group" "xxxx_RG" {
  name     = "${var.name_prefix}"
  location = "${var.location}"
}

resource "azurerm_kubernetes_cluster" "k8s" {
    name                    = "${var.name_prefix}-aks"
    kubernetes_version      = "${var.kubernetes_version}"
    location                = "${azurerm_resource_group.xxxx_RG.location}"
    resource_group_name     = "${azurerm_resource_group.xxxx_RG.name}"
    dns_prefix              = "AKS-${var.dns_prefix}"

    agent_pool_profile {
        name                = "${var.node_pool_name}"
        count               = "${var.node_pool_size}"
        vm_size             = "${var.node_pool_vmsize}"
        os_type             = "${var.node_pool_os}"
        os_disk_size_gb     = 30
    }

    service_principal {
        client_id           = "${var.client_id}"
        client_secret       = "${var.client_secret}"
    }

    tags = {
        environment = "${var.env_tag}"
    }
}

provider "helm" {
  install_tiller = true

  kubernetes {
    host                   = "${azurerm_kubernetes_cluster.k8s.kube_config.0.host}"
    client_certificate     = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate)}"
    client_key             = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_key)}"
    cluster_ca_certificate = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate)}"
  }
}

# Add Kubernetes Stable Helm charts repo
resource "helm_repository" "stable" {
  name = "stable"
  url  = "https://kubernetes-charts.storage.googleapis.com"
}

# Install Nginx Ingress using Helm Chart
resource "helm_release" "nginx_ingress" {
  name       = "nginx-ingress"
  repository = "${helm_repository.stable.metadata.0.name}"
  chart      = "nginx-ingress"
  wait       = "true"

  set {
    name  = "rbac.create"
    value = "false"
  }

  set {
    name  = "controller.service.externalTrafficPolicy"
    value = "Local"
  }

  set {
    name  = "controller.service.loadBalancerIP"
    value = "${data.azurerm_public_ip.nginx_ingress.ip_address}"
  }
}

그런 다음 이 기능을 사용하여 내 응용프로그램

provider "kubernetes" {
    host                    = "${azurerm_kubernetes_cluster.k8s.kube_config.0.host}"
    username                = "${azurerm_kubernetes_cluster.k8s.kube_config.0.username}"
    password                = "${azurerm_kubernetes_cluster.k8s.kube_config.0.password}"
    client_certificate      = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate)}"
    client_key              = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_key)}"
    cluster_ca_certificate  = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate)}"
}

resource "kubernetes_deployment" "flask_api_deployment" {
    metadata {
        name = "flask-api-deployment"
    }

    spec {
        replicas = 1
        selector {
            match_labels {
                component = "api"
            }
        }

        template {
            metadata {
                labels = {
                    component = "api"
                }
            }

            spec {
                container {
                    image = "xxxx.azurecr.io/sampleflask:0.1.0"
                    name = "flask-api"
                    port {
                        container_port = 5000
                    }
                }
            }
        }
    }
}

resource "kubernetes_ingress" "flask_api_ingress_service" {
    metadata {
        name = "flask-api-ingress-service"
    }

    spec {
        backend {
            service_name = "flask-api-cluster-ip-service"
            service_port = 5000
        }
    }
}

resource "kubernetes_service" "flask_api_cluster_ip-service" {
    metadata {
        name = "flask-api-cluster-ip-service"
    }

    spec {
        selector {
            component = "api"
        }

        port {
            port = 5000
            target_port = 5000
        }
    }
}

나는 그것이 어떤 조건을 기다리고 있는지 확실하지 않다. 시간 제한을 더 크게 설정할 수는 있지만 도움이 되지 않는 것 같습니다. 또한 조타 장치 릴리스에서 wait = false를 설정할 수 있지만 리소스가 프로비저닝되지 않는 것 같습니다.

편집: 일부 테스트를 수행한 결과 로드 밸런서를 지정할 때 문제가 발생했습니다IP가 조타 장치 해제 상태입니다. 만약 내가 그것을 논평한다면 그것은 아주 잘 완성된다.

편집: 추가 테스트를 통해 생성된 로드 밸런서가 생성되지 않는 것을 확인했습니다. 컨트롤러: 사용자가 제공한 IP 주소 52.xxx.x.xx가 리소스 그룹 MC_xxxxxxxxxxxxxxxxxxxx에서 찾을 수 없습니다

그렇다면 다른 리소스 그룹에서 IP를 지정하는 것을 어떻게 허용할 수 있을까요?




클러스터에서 RBAC를 사용하도록 설정하는 것이 가장 좋습니다. Terraform을 사용하여 Helm을 설치하는 방법의 예는 다음과 같습니다:

…
resource "azurerm_kubernetes_cluster" "k8s" {
…

  role_based_access_control {
    enabled = "true"
  }

}

provider "kubernetes" {
  host                   = "${azurerm_kubernetes_cluster.k8s.kube_config.0.host}"
  client_certificate     = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate)}"
  client_key             = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_key)}"
  cluster_ca_certificate = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate)}"
}

resource "kubernetes_service_account" "tiller_sa" {
  metadata {
    name      = "tiller"
    namespace = "kube-system"
  }
}

resource "kubernetes_cluster_role_binding" "tiller_sa_cluster_admin_rb" {
  metadata {
    name = "tiller-cluster-role"
  }
  role_ref {
    kind      = "ClusterRole"
    name      = "cluster-admin"
    api_group = "rbac.authorization.k8s.io"
  }
  subject {
    kind      = "ServiceAccount"
    name      = "${kubernetes_service_account.tiller_sa.metadata.0.name}"
    namespace = "kube-system"
    api_group = ""
  }
}

# helm provider
provider "helm" {
  debug           = true
  namespace       = "kube-system"
  service_account = "tiller"
  install_tiller  = "true"
  tiller_image    = "gcr.io/kubernetes-helm/tiller:v${var.TILLER_VER}"
  kubernetes {
    host                   = "${azurerm_kubernetes_cluster.k8s.kube_config.0.host}"
    client_certificate     = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_certificate)}"
    client_key             = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.client_key)}"
    cluster_ca_certificate = "${base64decode(azurerm_kubernetes_cluster.k8s.kube_config.0.cluster_ca_certificate)}"
  }
}

data "helm_repository" "stable" {
  name = "stable"
  url  = "https://kubernetes-charts.storage.googleapis.com"
}

resource "helm_release" "datadog" {
  name       = "datadog"
  namespace  = "datadog"
  repository = "${data.helm_repository.stable.metadata.0.name}"
  chart      = "stable/datadog"

  set {
    name  = "datadog.apiKey"
    value = "${var.datadog_apikey}"
  }

}



테라포름의 조타 장치를 통해 AKS 클러스터에 nginx-ingress를 설치하기 위해 여기서 사용 가능한 한 가지 방법을 보여줍니다. 이러한 방식으로, 당신은 테라폼 스크립트를 실행할 기계에 조타 장치를 설치해야 합니다. 그런 다음 AKS 클러스터에 대한 조타 장치를 구성해야 합니다. 의 단계입니다. AKS에 무언가를 설치하여 조타 장치가 AKS로 구성되었는지 확인할 수 있습니다.

모든 것이 준비되면. 키 공급자를 설정하고 리소스를 사용하기만 하면 됩니다. nginx-ingress를 설치하기 위한 Terraform 스크립트는 다음과 같습니다:

provider "helm" {
  version = "~> 0.9"
}

resource "helm_release" "ingress" {
    name = "application1"
    chart = "stable/nginx-ingress"
    version = "1.10.2"
    namespace = "ingress-basic"

    set {
        name = "controller.replicaCount"
        value = "1"
    }

    ...

}

프로세스는 다음과 같습니다:

enter image description here

이것은 단지 테라포름의 조타 장치를 통해 nginx-ingress를 설치하기 위한 것이다. 만약 당신이 쿠버네티스의 자원을 만들고 싶다면. 테라포름에서 쿠버네티스를 사용할 수 있습니다.

:

다른 리소스 그룹의 정적 공용 IP를 입력에 사용하려면 두 단계를 더 수행해야 합니다.

  1. AKS 클러스터에서 사용하는 서비스 주체는 공용 IP가 속한 다른 리소스 그룹에 사용 권한을 위임해야 합니다. 권한은 "네트워크 기여자" 이상이어야 합니다.
  2. 공용 IP가 속한 리소스 그룹의 값으로 입력 서비스 주석을 설정합니다.

yaml 파일의 주석은 다음과 같습니다:

annotations:
    service.beta.kubernetes.io/azure-load-balancer-resource-group: myResourceGroup

자세한 내용은 을 참조하십시오.

업데이트 1:

"helm_release"의 코드는 다음과 같다:

resource "helm_release" "ingress" {
    name = "application1223"
    chart = "stable/nginx-ingress"
        version = "1.10.2"
    namespace = "ingress-basic"

    set {
        name = "controller.replicaCount"
        value = "1"
    }

    set {
      name = "controller.service.annotations.\"service\\.beta\\.kubernetes\\.io/azure-load-balancer-resource-group\""
      value = "v-chaxu-xxxx"
    }

    set {
      name = "controller.service.loadBalancerIP"
      value = "13.68.175.40"
    }

}

성공적으로 배포되면 입력 서비스는 다음과 같이 표시됩니다:

enter image description here

다른 리소스 그룹에 있는 공용 IP의 정보:

enter image description here




저는 같은 문제에 직면해 있었습니다(helm_release 시간 초과). 추가 조사를 통해 RBAC 권한이 잘못되어 Public IP가 로드 밸런서에 할당되지 않았다는 것을 알게 되었습니다(kubectl 설명 svcnginx-ingress-n ingress-basic).

Azure가 매우 제한된 권한(AKS에서 자동으로 생성되는 관리 클러스터 리소스 그룹에 대한 읽기 전용 권한)만 가진 관리 ID 서비스 주체를 자동으로 생성하는 Azure AKS 관리 ID 기능을 사용하고 있었습니다. 내 공용 IP가 다른 리소스 그룹에 있고 로드 밸런서가 AKS 클러스터에서 관리되는 리소스 그룹에 있습니다.

마지막으로 서비스 주체에 대한 구독에 대한 '기여자' 액세스 권한이 있는 AKS 클러스터에서 관리되는 ID 대신 '서비스 주체' 옵션을 사용하여 문제를 해결할 수 있었습니다.

따라서 Managed Identity와 관련된 문제에 직면한 사용자가 있다면 구독에 대한 기여자 액세스 권한을 가진 서비스 주체를 사용해 보십시오. 그러면 문제가 해결됩니다




내가 경험한 바에 따르면, 헬름 차트의 일부가 무엇인지에 대한 매우 일반적인 시나리오는 다음과 같습니다.

더 명확한 경우, 서비스 계정, 역할, atc' 또는 심지어 CRD까지 설치하지 못한 경우, 명백한 오류가 발생할 수 있습니다.

배포/상태 저장 세트/DaemonSet 등'이 올바르게 설치되었지만 어떤 이유(리소스, 오염 등)로 인해 설치되었습니다.




나의 경우, had 유형과 MiniKube에서 제공하지 않는 외부 IP를 얻으려고 시도했기 때문에 조타 장치 배포(traefik 배포 중)가 시간 초과되었습니다. 해결 방법으로 서비스 유형을 수동으로 편집하고 t로 변경하여 배포를 즉시 완료했습니다.


반응형