Estoy tratando de difundir mis pods ingress-nginx-controller tal manera que:
Siguiendo otras preguntas aquí, configuré Restricciones de distribución de topología de pod en mi implementación de 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: DoNotScheduleActualmente tengo 2 Nodos, cada uno en una zona de disponibilidad diferente:
$ 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 Después de ejecutar el reinicio del kubectl rollout restart para esa implementación, obtengo 3 pods en un nodo y 1 pod en el otro, que tiene un sesgo de 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}}¿Por qué no se respeta mi restricción? ¿Cómo puedo depurar el programador de pods?
Mi versión de 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"}Dando más visibilidad al comentario:
Daemonset funcionó y fue bastante fácil. No funcionará para nuestras implementaciones con varios pods por nodo, pero hay mitigaciones allí (desprogramador) y debería resolverse automáticamente a medida que crece el clúster.
Considere esta respuesta como una solución alternativa :
Un DaemonSet garantiza que todos (o algunos) Nodos ejecuten una copia de un Pod. A medida que se agregan nodos al clúster, se les agregan pods. A medida que se eliminan los nodos del clúster, esos pods se recolectan como elementos no utilizados. Eliminar un DaemonSet limpiará los Pods que creó.
-- Kubernetes.io: Documentos: Conceptos: Cargas de trabajo: Controladores: Daemonset
Un ejemplo de ello podría ser el siguiente:
apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx spec: selector: matchLabels: name: nginx template: metadata: labels: name: nginx spec: #nodeSelector: #schedule: here tolerations: # this toleration is to have the daemonset runnable on master nodes # remove it if your masters can't run pods - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: nginx image: nginx Esta definición generará un Pod en cada Node del clúster. Puede limitar aún más la programación de nodeSelector Pod
Suponiendo que tiene algún controlador/lógica responsable de etiquetar los nodos con una etiqueta específica, puede programar Pods en nodos específicos. La parte responsable de ello se comenta en el manifiesto anterior:
nodeSelector: schedule: here Los nodos ( raven-sgdm y raven-xvvw están etiquetados): :
NAME STATUS ROLES AGE VERSION raven-6k6m Ready <none> 159m v1.20 raven-sgdm Ready <none> 159m v1.20 raven-xvvw Ready <none> 159m v1.20 El Daemonset :
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE nginx 2 2 2 2 2 schedule=here 99mRecursos adicionales:
En cierto momento en el tiempo, el sesgo será adecuado.
Pero cuando se eliminen las vainas que se eliminarán, el sesgo podría estar sesgado :)
Esencialmente, se enfrenta a la limitación descrita aquí :
Scaling down a Deployment may result in imbalanced Pods distribution.Una solución sencilla que aplico es reducir la escala + reiniciar/implementar + escalar hacia arriba .
¡Entonces el sesgo está perfectamente bien!
kubectl rollout restart nuevos pods y luego finaliza los antiguos una vez que todos los nuevos están en funcionamiento.
En la sección de limitaciones conocidas de restricciones de distribución de topología de pod, las restricciones no quedan satisfechas cuando se eliminan los pods y la mitigación recomendada ahora es usar Descheduler , que parece que ya ha estado usando en su comentario.