等待条件时地形头盔释放超时

时间:2019-07-13 12:44:26

标签: terraform kubernetes-helm nginx-ingress azure-aks terraform-provider-azure

我正在使用terraform在azure中提供一些资源,我似乎无法掌舵安装nginx-ingress,因为它等待条件超时

  
      
  • helm_release.nginx_ingress:发生1个错误:

  •   
  • helm_release.nginx_ingress:rpc错误:代码=未知desc =发布nginx-ingress失败:等待条件超时

  •   
     

面对错误,Terraform不会自动回滚。   相反,您的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,但是似乎没有提供资源。

编辑:经过一些测试,我发现在helm版本中指定loadbalancerIP时存在问题。如果我对此表示满意,那就很好了。

编辑:通过更多测试,我发现创建的负载均衡器无法创建。控制器:在资源组MC_xxxxxxxx中找不到用户提供的IP地址52.xxx.x.xx

所以我想问题是我如何允许从其他资源组指定IP?

3 个答案:

答案 0 :(得分:2)

最佳做法是在集群中启用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}"
  }

}

答案 1 :(得分:2)

要通过Terraform的头盔将Nginx-ingress安装在AKS集群中,这里我展示一种可用的方法。这样,您需要在要运行terraform脚本的机器上安装头盔。然后,您还需要为AKS集群配置头盔。 Configure the helm to AKS中的步骤。您可以通过在AKS上安装一些东西来检查头盔是否配置为AKS。

一切准备就绪。您只需要设置舵机提供程序并使用资源helm_release。安装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

这只是要通过头盔在Terraform中安装nginx-ingress。如果要创建kubernetes的资源。您可以在Terraform中使用kubernetes。

更新

好的,要在另一个资源组中使用静态公共IP进行入口,您需要再执行两个步骤。

  1. AKS群集使用的服务主体必须具有对公共IP所在的其他资源组的委派权限。该权限至少应为“网络贡献者”。
  2. 使用公共IP所在的资源组的值设置入口服务注释。

yaml文件中的注释如下:

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

有关更多详细信息,请参见Use a static IP address outside of the node resource group

答案 2 :(得分:2)

我遇到了同样的问题(helm_release超时)。在进一步调查中,我发现由于错误的RBAC权限,未将公共IP分配给负载均衡器(kubectl描述svc nginx-ingress -n ingress-basic)。

我使用的是Azure AKS托管身份功能,Azure通过该功能自动创建仅具有非常有限的权限(对AKS自动创建的托管群集资源组的只读权限)的托管身份服务主体。我的公共IP在另一个资源组中,而负载均衡器在AKS群集的托管资源组中。

最后,我能够通过使用“服务主体”选项而不是AKS群集中具有“贡献者”访问服务主体订阅权限的托管身份来解决此问题。

因此,如果任何人在管理身份方面遇到问题,请尝试使用具有提供者对订阅的访问权限的服务主体,这将解决此问题