K8s Pod 拓扑传播在推出后不受尊重?

roi*_*oim 5 kubernetes

我正在尝试传播我的ingress-nginx-controller豆荚,以便:

  • 每个可用区都有相同的 Pod 数量 (+- 1)。
  • Pod 更喜欢当前运行 Pod 最少的节点。

根据此处的其他问题,我在 Pod 部署中设置了 Pod 拓扑扩展约束:

      replicas: 4
      topologySpreadConstraints:
      - labelSelector:
          matchLabels:
            app.kubernetes.io/name: ingress-nginx
        maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
      - labelSelector:
          matchLabels:
            app.kubernetes.io/name: ingress-nginx
        maxSkew: 1
        topologyKey: kubernetes.io/hostname
        whenUnsatisfiable: DoNotSchedule
Run Code Online (Sandbox Code Playgroud)

我目前有 2 个节点,每个节点位于不同的可用区:

$ kubectl get nodes --label-columns=topology.kubernetes.io/zone,kubernetes.io/hostname
NAME                            STATUS   ROLES                  AGE    VERSION   ZONE         HOSTNAME
ip-{{node1}}.compute.internal   Ready    node                   136m   v1.20.2   us-west-2a   ip-{{node1}}.compute.internal
ip-{{node2}}.compute.internal   Ready    node                   20h    v1.20.2   us-west-2b   ip-{{node2}}.compute.internal

Run Code Online (Sandbox Code Playgroud)

运行kubectl rollout restart该部署后,我在一个节点中获得 3 个 pod,在另一个节点中获得 1 个 pod,其偏差为2 > 1

$ kubectl describe pod ingress-nginx-controller -n ingress-nginx | grep 'Node:'
Node:         ip-{{node1}}.compute.internal/{{node1}}
Node:         ip-{{node2}}.compute.internal/{{node2}}
Node:         ip-{{node1}}.compute.internal/{{node1}}
Node:         ip-{{node1}}.compute.internal/{{node1}}
Run Code Online (Sandbox Code Playgroud)

为什么我的约束不被遵守?如何调试 pod 调度程序?

我的 kubectl 版本:

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"21+", GitVersion:"v1.21.0-beta.0.607+269d62d895c297", GitCommit:"269d62d895c29743931bfaaec6e8d37ced43c35f", GitTreeState:"clean", BuildDate:"2021-03-05T22:28:02Z", GoVersion:"go1.16", Compiler:"gc", Platform:"darwin/arm64"}
Server Version: version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.2", GitCommit:"faecb196815e248d3ecfb03c680a4507229c2a56", GitTreeState:"clean", BuildDate:"2021-01-13T13:20:00Z", GoVersion:"go1.15.5", Compiler:"gc", Platform:"linux/amd64"}
Run Code Online (Sandbox Code Playgroud)

小智 3

kubectl rollout restart启动新 pod,然后在所有新 pod 启动并运行后终止旧 pod。

从 Pod 拓扑扩展约束已知限制部分来看,当 Pod 被删除时,约束不再满足,建议的缓解措施现在是使用Descheduler,您似乎已经在评论中使用了它。