Kubernetes Scheduling Parte 5
Kubernetes Scheduling parte 5 es la continuación del tema referente a cómo asignar Pods en los nodos. Si eres nuevo en el tema, te recomiendo que primero leas estos artículos previos:
- Kubernetes Scheduling parte 1
- Kubernetes Scheduling Parte 2
- Kubernetes Scheduling Parte 3
- Kubernetes Scheduling Parte 4
En esta ocasión, te explicaré cómo es que un Pod puede tener preferencias por elegir nodos específicos en donde ejecutarse o no ejecutarse, solo si encuentra otros Pods específicos ya ejecutándose ahí.
1. Introducción: Afinidad de Pods
Como lo expliqué ya en mi post anterior, existen estos 3 tipos de afinidad:
- Afinidad de Nodos
- Afinidad de Pods (afinidad positiva)
- Anti-afinidad de Pods (afinidad negativa)
1.1. Concepto
La «Afinidad de Pods», «Afinidad positiva» o «podAffinity» consiste en que un Pod debe estar en el mismo nodo o zona que otros Pods que cumplan con ciertos criterios. Esto es útil para aplicaciones que necesitan estar cerca una de la otra por razones de rendimiento o comunicación.
Fuente de imagen
https://blog.kubecost.com/blog/kubernetes-node-affinity
De modo contrario, la anti-afinidad de Pods en Kubernetes es un mecanismo que permite evitar que ciertos Pods se programen en el mismo nodo, zona o dominio topológico.
1.2. Importancia
La «Afinidad de Pods» se utiliza, normalmente, para agrupar Pods que están estrechamente relacionados para mejorar el rendimiento y la comunicación.
En cambio, la «Anti-afinidad de Pods» es útil para mejorar la tolerancia a fallos, distribuir cargas de trabajo de manera equilibrada o evitar conflictos entre Pods.
Ejemplo de Afinidad de Pods:
Imagina que tienes una aplicación de base de datos y una aplicación web. Puedes configurar la afinidad de Pods para que ambas se ejecuten en el mismo nodo, lo que reducirá la latencia entre ellas.
Ejemplo de Anti-afinidad de Pods:
Supongamos que tienes una aplicación con múltiples réplicas de un Pod y quieres asegurarte de que no se ejecuten en el mismo nodo para mejorar la tolerancia a fallos. En caso de caída de uno de los nodos, solo afectará a algunos Pods que ahí corrían, mientras que los demás no se verán afectados.
2. Especificación de podAffinity
Si te fijas, en especificación de podAffinity (kubectl explain pod.spec.affinity.podAffinity), y podAntiAffinity
(kubectl explain pod.spec.affinity.podAntiAffinity
) verás que existen dos tipos posibles:
- preferredDuringSchedulingIgnoredDuringExecution: Similar a la afinidad de Nodos, es una afinidad suave y preferente. Es una regla de afinidad en Kubernetes que permite expresar preferencias sobre cómo se deben o no programar los Pods en relación con otros Pods que ya están en ejecución en el clúster. A diferencia de las reglas obligatorias (
requiredDuringSchedulingIgnoredDuringExecution
), esta regla es flexible: Kubernetes intentará cumplirla, pero si no es posible, el Pod se ejecutará igual en otro nodo inclusive si no cumple las reglas. - requiredDuringSchedulingIgnoredDuringExecution: Es una regla de afinidad en Kubernetes que se utiliza con podAffinity para garantizar que un Pod se programe solo si se cumplen ciertas condiciones relacionadas con la presencia de otros Pods en el clúster. Esta regla es obligatoria durante la fase de programación (scheduling), pero una vez que el Pod está en ejecución, Kubernetes ignora cualquier cambio en las condiciones de afinidad.
De forma similar a la afinidad de Nodos, las reglas de configuración basadas en etiquetas (labels) y campos (fields) permite configurar criterios de programación de Pods en nodos juntos o separados. Los ejemplos lo mostrarán más claro.
3. Ejemplos de PodAffinity
Este artículo “Kubernetes Scheduling Parte 5” también comparto unos 5 ejemplos sencillos sobre los dos tipos de afinidad de Pods para facilitar la comprensión.
3.1. podAffinity fuerte: ejecutar Pod junto a otro
Asegura que un Pod se programe en el mismo nodo donde ya esté corriendo un Pod con la etiqueta app=backend
apiVersion: v1 kind: Pod metadata: name: ejemplo-1 spec: containers: - name: main image: alpine affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - backend topologyKey: kubernetes.io/hostname
3.2. podAntiAffinity fuerte: evitar que dos Pods compartan un nodo
Evita que dos Pods con la etiqueta app=frontend
se programen en el mismo nodo.
apiVersion: v1 kind: Pod metadata: name: ejemplo-2 spec: containers: - name: main image: alpine affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - frontend topologyKey: kubernetes.io/hostname
3.3. podAffinity fuerte: ejecutar un Pod en la misma zona que otro
Asegura que un Pod se programe en la misma zona de disponibilidad donde ya esté corriendo un Pod con la etiqueta app=database. Podría coincidir en el mismo nodo, o quizá no, pero con certeza correrá en un nodo que está dentro de la misma zona de disponibilidad. Esto es más apropiado para entornos de nube pública.
apiVersion: v1 kind: Pod metadata: name: ejemplo-3 spec: containers: - name: main image: alpine affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - database topologyKey: topology.kubernetes.io/zone
3.4. podAffinity suave: ejecutar Pod junto a otro
Intenta programar un Pod en el mismo nodo donde ya esté corriendo un Pod con la etiqueta app=cache
, pero no es obligatorio.
apiVersion: v1 kind: Pod metadata: name: ejemplo-4 spec: containers: - name: main image: alpine affinity: podAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - cache topologyKey: kubernetes.io/hostname
3.5. podAntiAffinity suave: evitar que dos Pods compartan un nodo
Intenta evitar que un Pod se programe en el mismo nodo donde ya esté corriendo un Pod con la etiqueta app=logging
, pero no es obligatorio.
apiVersion: v1 kind: Pod metadata: name: ejemplo-5 spec: containers: - name: main image: alpine affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - logging topologyKey: kubernetes.io/hostname
Conclusión
“Kubernetes Scheduling Parte 5” es otro artículo algo denso, pero lo suficientemente corto para enfocarme solo en los conceptos clave de afinidad de Pods.
Si revisas la documentación sobre estos dos tipos de afinidad de Pods que expliqué hoy, verás que hay muchos más campos de configuración los cuales no he cubierto en este artículo. Y es mejor así, de modo que el lector promedio se centre primero en asimilar lo esencial de reglas de afinidad y anti-afinidad para ponerlos en práctica sin mucho problema.
Comparte este artículo si te ha sido de utilidad.
Deja un comentario