使用 Terraform 部署时 GKE Autopilot 无法调度
Posted
技术标签:
【中文标题】使用 Terraform 部署时 GKE Autopilot 无法调度【英文标题】:GKE Autopilot unschedulable when deploying with Terraform 【发布时间】:2022-01-11 05:19:06 【问题描述】:首先,我使用浏览器中的 GCP GUI 控制台创建了一个 GKE Autopilot 集群,并使用默认设置,因此我尝试使用 kubectl apply -f thisfile.yaml
应用我的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
run: my-app
template:
metadata:
labels:
run: my-app
spec:
containers:
- name: hello-app
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
之后,我一直将其重写为 Terraform 文件,结果如下:
resource "google_container_cluster" "my_gke"
name = "my-gke"
enable_autopilot = "true"
location = "southamerica-east1"
data "google_client_config" "default"
provider "kubernetes"
host = "https://$google_container_cluster.my_gke.endpoint"
token = data.google_client_config.default.access_token
cluster_ca_certificate = base64decode(google_container_cluster.my_gke.master_auth[0].cluster_ca_certificate)
resource "kubernetes_deployment" "my_deployment"
metadata
name = "my-app"
spec
replicas = 2
selector
match_labels =
run = "my-app"
template
metadata
labels =
run = "my-app"
spec
container
image = "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0"
name = "hello-app"
lifecycle
ignore_changes = [
metadata[0].annotations,
metadata[0].resource_version,
spec[0].template[0].spec[0].container[0].security_context
]
问题如下:
当我将它与kubectl apply -f thisfile.yaml
一起应用时,使用 YAML 表示法,一切都可以正常部署。
当我删除集群并使用 Terraform 应用所有内容时,第一个修订版在一段时间后可以正常应用,但部署的下一个修订版继续导致 GCP 控制台打印“不可调度”错误,声称“cpu 不足”和/或“内存不足”
PS。我之前已经尝试在 PodSpec 中设置资源的限制和请求,但没有任何改变。
我是 GKE 的新手,现在对我来说一切看起来都很不可靠。我做错了什么?
【问题讨论】:
也许你必须先删除旧的部署。 kubectl get deployment --all-namespaces 或 kubectl get pods --all-namespaces #获取概览,然后删除不需要的。 【参考方案1】:我可以确认这是一个持续存在的问题。我们向 GCP 开具了支持票证,以调查相同的行为。
第一次部署工作正常,但新修订版的部署失败。 Pod 的创建和删除速度很快(每秒几个),而 ReplicaSet 很快达到数百个。
从日志中我们可以看到相同的 Unschedulable 错误,有时我们会看到 Pod 因节点中缺少卷而无法启动(大部分时间是我们自己的卷,但也有“kube-api-access”卷)。
日志中也有这样的错误:
message: "Operation cannot be fulfilled on replicasets.apps "deploytest-747c54b87d": the object has been modified; please apply your changes to the latest version and try again"
只有当我们尝试通过 terraform 重新部署时才会发生这种情况。如果我们直接用 kubectl 给 yaml 打补丁,新版本通过替换策略可以正常运行,没有错误。
完全相同的 terraform 代码适用于 GKE 常规集群。问题似乎仅限于自动驾驶仪。已经在一个全新的项目中进行了测试,一切都是开箱即用的默认设置。
Google 目前正在通过内部工单调查此问题。我会尝试在这里报告我们还能弄清楚的其他内容。
--编辑:
Pod 似乎需要 pod.securityContext.seccompProfile 参数,但 Terraform 尚不支持该参数。出于某种原因,相同的 terraform 代码可以实例化一个新的部署,如果它还不存在的话。但它无法更新部署。
下面的补丁添加了缺失的配置,但这不是解决方案。我想我们需要等待 securityContext 被添加到 TF 中。 (ps.有一个不推荐的注解方法来添加这个配置,但我没有尝试)。
kubectl patch deployment deploy-test -p='["op": "replace", "path": "/spec/template/spec/securityContext", "value":"seccompProfile":"type":"RuntimeDefault"]' --type='json'
我们刚刚决定从 TF 迁移到 K8S 部署。我们的 TF 只上升到集群创建。工作负载将在其他地方进行管理。
【讨论】:
【参考方案2】:可能 Kubernetes 集群没有可用资源的节点。尝试将 Kubernetes 应用程序的部署和集群的部署分开。 通常,发生像您这样的错误是因为节点尚未准备好,并且 Kubernetes 无法为 Deployment 分配资源。
【讨论】:
这是 GKE Autopilot,Google 管理集群的节点。以上是关于使用 Terraform 部署时 GKE Autopilot 无法调度的主要内容,如果未能解决你的问题,请参考以下文章
需要帮助 GKE 入口与 terraform 进行 n8n 部署
在 GKE 集群上使用 Terraform 部署 Helm 工作负载
将现有 GKE 集群添加到 terraform stat 文件