使用 Terraform 部署时 GKE Autopilot 不可调度
GKE Autopilot unschedulable when deploying with Terraform
首先,我在浏览器中使用 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" and/or "内存不足"
PS。我之前已经尝试在 PodSpec 中设置资源的限制和请求,但没有任何改变。
我是 GKE 的新手,现在一切对我来说都很不可靠。我做错了什么?
可能 Kubernetes 集群中没有可用资源的节点。尝试将 Kubernetes 应用的部署和集群的部署分开。
通常,像您这样的错误发生是因为节点尚未准备好并且 Kubernetes 无法为 Deployment 分配资源。
我可以确认这是一个持续存在的问题。我们已通过 GCP 开立支持票以调查相同的行为。
第一次部署工作正常,但新修订版的部署失败。 Pods 快速创建和删除(每秒几个)并且 ReplicaSets 很快达到数百个。
从日志中我们可以看到相同的不可调度错误,有时我们会看到 pods 由于节点中缺少卷而无法启动(大部分时间是我们自己的卷,但也有“kube-api-访问“那些”。
日志中也有这样的错误:
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 目前正在调查内部票证上的问题。我会试着在这里报告我们还能弄清楚什么。
-- 编辑:
似乎 pods 需要 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 只上升到集群创建。工作负载将在其他地方管理。
首先,我在浏览器中使用 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" and/or "内存不足"
PS。我之前已经尝试在 PodSpec 中设置资源的限制和请求,但没有任何改变。
我是 GKE 的新手,现在一切对我来说都很不可靠。我做错了什么?
可能 Kubernetes 集群中没有可用资源的节点。尝试将 Kubernetes 应用的部署和集群的部署分开。 通常,像您这样的错误发生是因为节点尚未准备好并且 Kubernetes 无法为 Deployment 分配资源。
我可以确认这是一个持续存在的问题。我们已通过 GCP 开立支持票以调查相同的行为。
第一次部署工作正常,但新修订版的部署失败。 Pods 快速创建和删除(每秒几个)并且 ReplicaSets 很快达到数百个。
从日志中我们可以看到相同的不可调度错误,有时我们会看到 pods 由于节点中缺少卷而无法启动(大部分时间是我们自己的卷,但也有“kube-api-访问“那些”。
日志中也有这样的错误:
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 目前正在调查内部票证上的问题。我会试着在这里报告我们还能弄清楚什么。
-- 编辑:
似乎 pods 需要 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 只上升到集群创建。工作负载将在其他地方管理。