我在 GKE 上有一个由 Helm 管理的 Kubernetes 集群,最近部署开始失败,因为 pod 不会离开Pending
状态。检查我看到的待处理的 pod:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 50m default-scheduler Successfully assigned default/my-pod-6cbfb94cb-4pzl9 to gke-staging-pool-43f2e11c-nzjz
Warning FailedValidation 50m (x6 over 50m) kubelet, gke-staging-pool-43f2e11c-nzjz Error validating pod my-pod-6cbfb94cb-4pzl9_default(8e4dab93-75a7-11e9-80e1-42010a960181) from api, ignoring: spec.priority: Forbidden: Pod priority is disabled by feature-gate
具体来说,这个警告似乎是相关的:Error validating pod my-pod-6cbfb94cb-4pzl9_default(8e4dab93-75a7-11e9-80e1-42010a960181) from api, ignoring: spec.priority: Forbidden: Pod priority is disabled by feature-gate
将新的、Pending
的 pod 与当前正在运行的 pod 进行比较,我看到的唯一区别(除了时间戳等)是:
$ kubectl get pod my-pod-6cbfb94cb-4pzl9 -o yaml > /tmp/pending-pod.yaml
$ kubectl get pod my-pod-7958cc964-64wsd -o yaml > /tmp/running-pod.yaml
$ diff /tmp/running-pod.yaml /tmp/pending-pod.yaml
…
@@ -58,7 +58,8 @@
name: default-token-wnhwl
readOnly: true
dnsPolicy: ClusterFirst
- nodeName: gke-staging-pool-43f2e11c-r4f9
+ nodeName: gke-staging-pool-43f2e11c-nzjz
+ priority: 0 // <-- notice that the `priority: 0` field is added
restartPolicy: Always
schedulerName: default-scheduler
…
这似乎在 2019 年 5 月 1 日至 2019 年 5 月 6 日之间的某个时间开始发生。
我在这里用作示例的集群是一个暂存集群,但我注意到在两个配置相似的生产集群上存在相同的行为,这让我相信 Google Kube 方面发生了变化。
Pod 由 Helm 通过cloudbuild.yaml
部署,并且在 5 月 1 日至 5 月 6 日期间,当回归似乎被引入时,该设置(Helm 版本或云构建文件)没有任何变化。
掌舵版本:
Client: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}
如果您看到 Pod 优先级和抢占的文档,该功能在<= 1.10
中alpha
(默认禁用,由 GKE 在控制平面上不执行的功能门启用,afaik),那么它在>= 1.11
中变得beta
(默认启用)。
可以是其中之一或组合:
-
你有一个 GKE 控制平面
>= 1.11
,你的 Pod 尝试启动的节点(由 kube-scheduler 调度)正在运行一个 kubelet<= 1.10
。有人可以在不升级节点(或实例组)的情况下升级控制平面 -
有人将控制平面升级到 1.11 或更高版本,并且默认情况下启用了优先级准入控制器,这会阻止设置了
spec.priority
字段的 Pod 启动(或重新启动)。如果您看到 API 文档(优先级字段),它说启用优先级准入控制器时,您无法设置该字段,并且该字段只能由 PriorityClass/PriorityClassName 设置。