等待条件时terraform helm释放超时
Posted
技术标签:
【中文标题】等待条件时terraform helm释放超时【英文标题】:terraform helm release timeout while waiting for condition 【发布时间】:2019-11-22 22:45:56 【问题描述】:我正在使用 terraform 在 azure 中配置一些资源,但我似乎无法让 helm 安装 nginx-ingress,因为它等待条件超时
helm_release.nginx_ingress:发生 1 个错误:
helm_release.nginx_ingress: rpc error: code = Unknown desc = release nginx-ingress failed: timed out waiting for the condition
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
我不确定它在等待什么条件。我可以将超时设置得更大,但这似乎没有帮助。我也可以在 helm release 中设置 wait = false ,但似乎没有配置资源。
编辑:从我所做的一些测试中,我发现在 helm 版本中指定 loadbalancerIP 时存在问题。如果我注释掉它就可以了。
编辑:通过更多测试,我发现创建的负载均衡器无法创建。控制器:在资源组 MC_xxxxxxxx 中找不到用户提供的 IP 地址 52.xxx.x.xx
所以我想问题是如何允许指定来自不同资源组的 IP?
【问题讨论】:
我怀疑它正在等待服务完成设置并没有这样做,您能否确认已提供服务并且公共 ip 可用? 如果你尝试重新运行terraform apply?
,你会得到同样的错误吗
您是否有意关闭 RBAC?你最好启用它。
这个问题有什么更新吗?对你起作用吗?如果您还有其他问题,请告诉我。
不要保持沉默。请让我知道它是否有帮助!
【参考方案1】:
要通过 Terraform 中的 helm 在 AKS 集群中安装 nginx-ingress,我在这里展示了一种可用的方法。这样,您需要在要运行 terraform 脚本的机器上安装 helm。然后,您还需要将 helm 配置到您的 AKS 群集。 Configure the helm to AKS 中的步骤。您可以通过向 AKS 安装一些东西来检查 helm 是否配置为 AKS。
当一切准备就绪时。您只需要设置 helm 提供程序并使用资源 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"
...
流程如下:
这只是为了在 Terraform 中通过 helm 安装 nginx-ingress。如果你想创建 Kubernetes 的资源。您可以在 Terraform 中使用 kubernetes。
更新:
好的,要将另一个资源组中的静态公共 IP 用于您的入口,您需要再执行两个步骤。
-
AKS 群集使用的服务主体必须将权限委派给公共 IP 所在的其他资源组。权限至少应为“网络参与者”。
将入口服务注解设置为公网IP所在资源组的值。
yaml 文件中的注解是这样的:
annotations:
service.beta.kubernetes.io/azure-load-balancer-resource-group: myResourceGroup
更多详情请见Use a static IP address outside of the node resource group。
更新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"
部署成功后,入口服务显示如下:
另一个资源组中的公网IP信息:
【讨论】:
【参考方案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"
【讨论】:
很酷,这有助于更好地与最佳实践保持一致,但我仍然遇到我所写的超时问题。 实际上这给了我一个更好的错误。我现在得到 helm_release.nginx_ingress: timeout while waiting state to become 'Running' 表示图表安装失败并超时。您是否看到 Pod 处于运行状态? 我看到我的 pod 正在运行,当我获得该 kube-system 命名空间的 pod 时,我看到以下内容:coredns-7fbf4847b6-6mcx8、coredns-7fbf4847b6-fxfxs、coredns-autoscaler-657d77ffbf-78rww、kube -proxy-79v7w,kube-proxy-dgrsk,kubernetes-dashboard-6f697bd9f5-76x8n,metrics-server-58699455bc-pf6lq,tiller-deploy-8485766469-hbqmw,tunnelfront-bb9b87486-6rtm8。所有这些 pod 都在运行。我不确定我还要寻找哪些其他 pod?【参考方案3】:我遇到了同样的问题(helm_release 超时)。经过进一步调查,我发现公共 IP 没有被分配给负载均衡器(kubectl describe svc nginx-ingress -n ingress-basic),因为 RBAC 权限不正确。
我使用的是 Azure AKS 托管标识功能,Azure 通过该功能自动创建一个托管标识服务主体,该主体只有非常有限的权限(对由 AKS 自动创建的托管集群资源组的只读权限)。我的公共 IP 位于另一个资源组中,负载均衡器位于 AKS 群集的托管资源组中。
最后,我能够通过使用“服务主体”选项而不是 AKS 群集中的托管标识以及“参与者”访问服务主体的订阅来解决此问题。
因此,如果有人在托管身份方面遇到问题,请尝试使用具有订阅者访问权限的服务主体,这将解决问题
【讨论】:
我投了赞成票,因为 IMO 这最直接地回答了原始问题。人们似乎遇到的普遍问题是 helm 提供者需要将公共 IP 分配给入口控制器才能成功完成。以上是关于等待条件时terraform helm释放超时的主要内容,如果未能解决你的问题,请参考以下文章
卡在 Terraform 到 Kubernetes 的部分 helm 版本中
在 GKE 集群上使用 Terraform 部署 Helm 工作负载
通过 helm / terraform 安装自定义 grafana 数据源
通过 Terraform Helm 提供程序和 Azure DevOps 部署 helm 图表,同时从 ACR 获取 helm 图表