Utilizar la afinidad de nodos en Kubernetes
La afinidad de nodos es un conjunto de reglas. Lo utiliza el programador para decidir dónde puede colocarse un pod en el clúster. Las reglas se definen utilizando etiquetas en los nodos y selectores de etiquetas especificados en la definición de los pods. La afinidad de nodos permite a un pod especificar una afinidad hacia un grupo de nodos en los que puede programarse. Podemos limitar un pod para que sólo pueda ejecutarse en un nodo o nodos concretos.
nodeSelector es la forma más sencilla de restricción de selección de nodos. nodeSelector es una propiedad de PodSpec. Para que el pod pueda ejecutarse en un nodo, éste debe tener cada una de las etiquetas indicadas.
La afinidad de nodos es conceptualmente similar a nodeSelector — nos permite limitar en qué nodos puede programarse nuestro pod, basándonos en las etiquetas del nodo.
Actualmente hay dos tipos de afinidad de nodo,
- requiredDuringSchedulingIgnoredDuringExecution y
- preferredDuringSchedulingIgnoredDuringExecution.
Qué es DuringScheduling
- Aquí, el pod aún no está creado y se va a crear por primera vez.
- Normalmente, cuando se crea el pod se aplican las reglas de afinidad.
Qué es DuranteLaEjecución
- Aquí, el pod se ha estado ejecutando y se realiza el cambio en el entorno que afecta a nodeAffinity.
Para conocer en detalle la Afinidad de Nodos, visita kubernetes.io la documentación oficial de Kubernetes.
En este artículo, veremos cómo asignar un Pod de Kubernetes a un nodo concreto utilizando la Afinidad de Nodo «requiredDuringSchedulingIgnoredDuringExecution» en un clúster Kubernetes.
Requisitos previos
- Clúster Kubernetes con al menos 1 nodo trabajador.
Si quieres aprender a crear un Clúster Kubernetes, haz clic aquí. Esta guía te ayudará a crear un clúster Kubernetes con 1 Maestro y 2 Nodos en Instancias EC2 Ubuntu de AWS.
¿Qué haremos?
- Configurar Node-Affinity
Configurar Node-Affinity
En primer lugar, vamos a obtener una lista de los nodos disponibles en el clúster.
kubectl get nodes #Get all the nodes in the cluster
Comprueba si los nodos tienen Manchas.
kubectl describe node node01 | grep Taints #Describe the node node01 and grep Taints
kubectl describe node master | grep Taints #Describe the node master and grep Taints
Añade una etiqueta a un nodo trabajador nodo01.
kubectl label node node01 app=qa #Add a label
Crea un archivo de definición de despliegue y añade la siguiente definición en él.
vim my-deployment-without-affinity.yml
apiVersion: apps/v1 kind: Deployment metadata: name: app-without-affinity spec: replicas: 20 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: nginx imagePullPolicy: Always name: nginx
Obtén una lista de Pods y Despliegues.
kubectl get pods #Get pods in the default namespace
kubectl get deployment #Get deployments in the default namespace
Crea un despliegue a partir de la definición que hemos creado.
kubectl create -f my-deployment-without-affinity.yml #Create a deployment object
kubectl get deployment #Get deployments in the default namespace
kubectl get pods #Get pods in the default namespace
Obtén los detalles de los Pods creados por el despliegue.
Aquí se puede ver que los Pods se están colocando también en el nodo maestro. La razón de esto es que los nodos no tienen Taints en ellos, por lo que los pods pueden obtener plazas en cualquiera de los nodos disponibles.
kubectl get pods -o wide #Get pods in the default namespace with more information about them using -o wide
Ahora, crea una definición de despliegue con afinidad de nodo definida.
vim my-deployment-with-affinity.yml
apiVersion: apps/v1 kind: Deployment metadata: name: app-with-afiinity spec: replicas: 6 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: nginx imagePullPolicy: Always name: nginx affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: app operator: In values: - qa
Obtén una lista de los despliegues existentes y crea un nuevo despliegue con afinidad en el espacio de nombres predeterminado utilizando el archivo creado en el paso anterior.
kubectl get deployments #Get deployments in the default namespace
kubectl create -f my-deployment-with-affinity.yml #Create a deployment object
kubectl get deployments #Get deployments in the default namespace
Ahora, se puede ver que los Pods esta vez sólo se han colocado en el nodo trabajador nodo01. La razón es que hemos definido una afinidad de nodo en la definición del despliegue, lo que garantiza que los pods se desplieguen en los nodos que coincidan con la condición/etiqueta definida.
kubectl get pods -o wide | grep app-with-afiinity #Get pods in the default namespace with more information about them using -o wide and grep app-with-afiinity
Conclusión
En este artículo hemos aprendido a añadir etiquetas a los nodos y hemos visto cómo se puede restringir la programación de los pods a los nodos necesarios mediante la Afinidad de Nodos. También hemos visto que los pods pueden desplegarse incluso en el nodo maestro si no tiene ninguna Mancha.