Afinidad de Nodos en Kubernetes
En esta nueva entrada de Afinidad de Nodos en Kubernetes vamos a ver como aplicar y trabajar con la afinidad de nodos. Este artículo es una continuación del anterior sobre Selector de Nodos en Kubernetes.
¿Qué es la afinidad de Nodos en Kubernetes?
Tanto la afinidad de nodos como el selector de nodos buscan una misma finalidad pero de maneras diferentes, mientras en el Selector de Nodos se restringe en qué nodos va a funcionar haciendo uso de etiquetas. En la afinidad de nodos se establecen una serie de reglas para determinar donde establecer y asignar esos Pods. Es decir, permite especificar una «afinidad» para colocar un grupo de pods en un nodo. Y en ningún momento el nodo tendrá control sobre ese Pod.
Configuración de Afinidad de Nodos en Kubernetes
La mejor manera de ver el funcionamiento de la afinidad de Nodos en Kubernetes es ver la configuración de un Pod.
Para realizar la afinidad de nodos podemos utilizar dos tipos de reglas «preferred rule» (o preferida) o «required rule» (o requerida) o ambas. Teniendo en cuenta que si usamos la opción de ambas, primero se configurará la opción de «preferred rule». A continuación vamos a ver un ejemplo con required rule:
apiVersion: v1 kind: Pod metadata: name: node-affinity spec: affinity: nodeAffinity: 1 requiredDuringSchedulingIgnoredDuringExecution: 2 nodeSelectorTerms: - matchExpressions: - key: size operator: NotIn 4 values: - very-big 3 - very-small 3 containers: - name: node-affinity image: nginx
- Se establece la propiedad nodeaffinity.
- Definición de una required rule.
- Clave/valor que debe conincidir para aplicar la regla
- El operador que se va a aplicar y representa la relación entre la etiqueta del nodo y el cojunto de valores que harán match en la especificación del Pod. Este valor puede ser
In
,NotIn
,Exists
, orDoesNotExist
,Lt
, orGt
.
Tipos de afinidad de Nodo
Anteriormente hemos hablado de dos tipos de afinidad de nodo diferentes preferred y required.
Estos tipos de nodo sirven para decirle como se tiene que programar el Pod. En el caso de Required la regla debe ser conocida antes de que un pod pueda ser planificado en un nodo.
Configurar un nodo Required
En el ejemplo anterior hemos definido un nodo de este tipo, a continuación vamos a describir los pasos con más detalle:
spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: size operator: NotIn values: - very-big - very-small containers: - name: node-affinity image: nginx
En el pode anterior especificamos el tipo de afinidad de nodo añadiendo el parámetro requiredDuringSchedulingIgnoredDuringExecution
.
Una vez específicamos el tipo de nodo, debemos de asignar la clave y el valor, que se puede ver en el ejemplo con key: size y values.
Finalmente, asignamos el operador que queremos utilizar en este caso hemos dicho NotIn, para decir que no este en el nodo.
Si esta clave/valor que hemos definido, no se encontrará en el nodo, este Pod no será programado en el Nodo. Es decir, el estado será erróneo.
Configurar un Nodo Preferred
En este tipo de Nodos se específica que el programador intentará hacer cumplir la regla, pero en ningún momento garantiza su cumplimiento.
A continuación vamos a ver un ejemplo de configuración:
preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: e2e-az-name operator: In values: - e2e-az3
En este nodo añadimos el parámetro preferredDuringSchedulingIgnoredDuringExecution
.
A continuación definimos un weight, es decir, un peso al nodo. Este número va de 1 a 100, siendo el valor más alto el más preferido.
Una vez definido el peso añadimos al igual que en el nodo tipo required la clave y el valor.
Si al hacer uso de preferredDuringSchedulingIgnoredDuringExecution, no hiciese match con la etiqueta del nodo, el pod se ejecutará ya que prevalece la carga del pod.
Ejemplo de Afinidad de Nodos en Kubernetes
Una vez hemos explicado los diferentes nodos y como funcionan vamos a ver un ejemplo paso a paso. En el que tendremos un nodo en el que las etiquetas van a coincidir
- Listar nodos:
kubectl get nodes
- Asignar etiqueta al nodo seleccionado:
kubectl label nodes <node-name> <label-key>=<label-value>
En nuestro caso vamos a trabajar sobre el siguiente nodo:
Labels: alpha.eksctl.io/cluster-name=eks-dev-cluster alpha.eksctl.io/instance-id=i-0100bdd9c9bd76461 alpha.eksctl.io/nodegroup-name=mixed-instances-stateless beta.kubernetes.io/arch=amd64 beta.kubernetes.io/instance-type=c5.2xlarge beta.kubernetes.io/os=linux failure-domain.beta.kubernetes.io/region=us-east-1 failure-domain.beta.kubernetes.io/zone=us-east-1c kubernetes.io/arch=amd64 kubernetes.io/hostname=ip-192-168-143-94.ec2.internal kubernetes.io/os=linux node.kubernetes.io/instance-type=c5.2xlarge nodegroup-instances=mixed-instances-stateless nodegroup-type=microservices topology.kubernetes.io/region=us-east-1 topology.kubernetes.io/zone=us-east-1c
Y a este nodo le vamos a asignar una afinida de nodos a un deployment con la etiqueta microservices:
apiVersion: apps/v1 kind: Deployment metadata: name: locations namespace: microservices spec: selector: matchLabels: app: locations replicas: 1 template: metadata: labels: app: locations spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: nodegroup-type operator: In values: - microservices containers: - name: locations image: locations:latest resources: requests: memory: "512Mi" cpu: "500m" limits: memory: "512Mi" cpu: "500m" ports: - containerPort: 8080 livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 240 periodSeconds: 5
Con el deployment anterior lo que vamos a hacer es asginar una afinidad de nodos por la etiqueta microservices.
¿Qué pasaría si la etiqueta en la afinidad de nodo no existe?
Al haber elegido la opción requiredDuringSchedulingIgnoredDuringExecution, entonces al no hacer match con la etiqueta, se quedaría en estado de pending al crear el pod. Si por el contrario hubiesemos elegido la etiqueta referredDuringSchedulingIgnoredDuringExecution, aunque no haga match daría preferencia a la carga del Pod y se asingaría al nodo.
Conclusión
En esta entrada sobre Afinidad de Nodos en Kubernetes, hemos visto como podemos hacer que un pod se despliegue en uno o en otro nodo en función una etiqueta. Esta suele ser una práctica muy utilizada dentro de kubernetes ya que los nodos suelen tener diferentes características y nos ayudará a distribuir nuestros Pods.
Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com y te ayudaremos encantados!
No te olvides de seguirnos en nuestras redes sociales Facebook o Twitter para estar actualizado.
2 pensamientos sobre “Afinidad de Nodos en Kubernetes”