¿Cómo ver los taints aplicados a un nodo de Kubernetes?

KubernetesBeginner
Practicar Ahora

Introducción

Kubernetes, la popular plataforma de orquestación de contenedores, proporciona una poderosa función llamada "taints" (manchas) para controlar la programación de pods en los nodos. En este tutorial, exploraremos cómo ver los taints aplicados a los nodos de Kubernetes, una habilidad esencial para gestionar eficazmente su clúster de Kubernetes.

Los taints le permiten marcar nodos con atributos específicos que pueden repeler ciertos pods, asegurando que las cargas de trabajo se programen apropiadamente en función de las capacidades y los recursos del nodo. Comprender cómo ver y trabajar con los taints le ayuda a mantener una asignación óptima de recursos en su entorno Kubernetes.

Configuración de un Entorno Kubernetes para Pruebas

Antes de poder ver los taints en los nodos de Kubernetes, necesitamos un entorno Kubernetes funcional. Para este tutorial, usaremos Minikube, que proporciona un clúster Kubernetes local y ligero para fines de desarrollo y pruebas.

Comencemos instalando Minikube:

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
rm minikube-linux-amd64

Ahora que Minikube está instalado, iniciemos un clúster Kubernetes:

minikube start --driver=docker

Debería ver una salida similar a esta:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Using the docker driver based on user configuration
📌  Using Docker driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.26.1 on Docker 23.0.1 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: default-storageclass, storage-provisioner
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

Verifiquemos que el clúster se está ejecutando comprobando el estado del nodo:

kubectl get nodes

Debería ver una salida similar a esta:

NAME       STATUS   ROLES           AGE    VERSION
minikube   Ready    control-plane   1m     v1.26.1

¡Genial! Ahora tenemos un entorno Kubernetes funcional para explorar los taints. El comando kubectl ya está configurado para funcionar con nuestro clúster Minikube.

Comprensión de los Taints de Kubernetes

Antes de comenzar a ver los taints, comprendamos qué son y cómo funcionan en Kubernetes.

¿Qué son los Taints?

Los taints son propiedades aplicadas a los nodos de Kubernetes que permiten a un nodo repeler ciertos pods. Piense en los taints como etiquetas que marcan los nodos como inadecuados para tipos específicos de cargas de trabajo.

Los taints funcionan junto con un concepto llamado "tolerations" (tolerancias). Mientras que los taints se aplican a los nodos, las tolerancias se aplican a los pods. Un pod con una toleración que coincida con el taint de un nodo puede ser programado en ese nodo con taint.

Estructura del Taint

Los taints constan de tres componentes:

  1. Key (Clave): Una cadena que identifica el taint (por ejemplo, gpu, disk, network)
  2. Value (Valor): Una cadena opcional asignada a la clave (por ejemplo, true, high-performance)
  3. Effect (Efecto): Define cómo se tratan los pods sin tolerancias coincidentes

Los efectos de taint más comunes son:

  • NoSchedule: Los nuevos pods sin tolerancias coincidentes no se programarán en el nodo
  • PreferNoSchedule: El sistema intentará evitar colocar pods sin tolerancias coincidentes en el nodo, pero no está garantizado
  • NoExecute: Los nuevos pods sin tolerancias coincidentes no se programarán en el nodo, y los pods existentes sin tolerancias coincidentes serán desalojados

Aquí está la sintaxis de un taint:

  • Con un valor: key=value:effect
  • Sin un valor: key:effect

Algunos nodos en un clúster de Kubernetes tienen taints predeterminados. Por ejemplo, los nodos del plano de control (control plane) a menudo están manchados con node-role.kubernetes.io/control-plane:NoSchedule para evitar que las cargas de trabajo regulares se programen en ellos, preservando los recursos para los componentes del sistema.

Examinemos nuestro nodo Minikube para ver si tiene algún taint predeterminado:

kubectl describe node minikube | grep -A3 Taints

Probablemente verá una salida similar a:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  minikube

Esta salida muestra que nuestro nodo Minikube tiene un taint que impide que los pods regulares se programen en él, ya que es un nodo del plano de control.

Visualización de Taints en Nodos de Kubernetes

Ahora que entendemos qué son los taints, exploremos los diferentes métodos para ver los taints aplicados a los nodos de Kubernetes.

Método 1: Uso de kubectl describe

La forma más detallada de ver los taints en un nodo es usando el comando kubectl describe node:

kubectl describe node minikube

Este comando genera información completa sobre el nodo. Para enfocarse solo en los taints, puede usar grep:

kubectl describe node minikube | grep -A1 Taints

Ejemplo de salida:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false

Método 2: Uso de kubectl get con columnas personalizadas

Puede usar el comando kubectl get nodes con columnas de salida personalizadas para mostrar solo los taints:

kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

Ejemplo de salida:

NAME       TAINTS
minikube   [map[effect:NoSchedule key:node-role.kubernetes.io/control-plane]]

Método 3: Uso de kubectl get con JSONPath

Otro enfoque es usar JSONPath para extraer información de taint:

kubectl get nodes minikube -o jsonpath='{.spec.taints}'

Ejemplo de salida:

[{"effect":"NoSchedule","key":"node-role.kubernetes.io/control-plane"}]

Para una mejor legibilidad, puede formatear la salida como JSON:

kubectl get nodes minikube -o jsonpath='{.spec.taints}' | jq .

Si no tiene jq instalado, puede instalarlo con:

sudo apt-get update && sudo apt-get install -y jq

Ejemplo de salida formateada:

[
  {
    "effect": "NoSchedule",
    "key": "node-role.kubernetes.io/control-plane"
  }
]

Método 4: Uso de kubectl get con salida YAML

También puede ver la especificación completa del nodo en formato YAML y buscar taints:

kubectl get node minikube -o yaml | grep -A5 taints:

Ejemplo de salida:

  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/control-plane
  unschedulable: false
status:
  addresses:

Cada uno de estos métodos proporciona la misma información en diferentes formatos. Elija el que mejor se adapte a sus necesidades en función de la legibilidad y de cómo planea usar la información.

Agregar y Eliminar Taints

Ahora que sabemos cómo ver los taints, aprendamos cómo agregarlos y eliminarlos. Esta es una operación común cuando necesita controlar la programación de pods o preparar nodos para el mantenimiento.

Agregar Taints a Nodos

La sintaxis para agregar un taint a un nodo es:

kubectl taint nodes <nombre-del-nodo> <clave>=<valor>:<efecto>

Agreguemos un taint a nuestro nodo Minikube para marcarlo como que tiene una GPU:

kubectl taint nodes minikube gpu=true:NoSchedule

Debería ver una salida como:

node/minikube tainted

Ahora, verifiquemos que el taint se agregó:

kubectl describe node minikube | grep -A3 Taints

Ejemplo de salida:

Taints:             gpu=true:NoSchedule
                    node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:

Como puede ver, nuestro nodo ahora tiene dos taints: el taint original del plano de control y nuestro nuevo taint de GPU.

Eliminar Taints de Nodos

Para eliminar un taint, debe agregar un signo menos (-) a la misma definición de taint:

kubectl taint nodes <nombre-del-nodo> <clave>=<valor>:<efecto>-

Eliminemos el taint de GPU que acabamos de agregar:

kubectl taint nodes minikube gpu=true:NoSchedule-

Debería ver una salida como:

node/minikube untainted

Verifiquemos que el taint se eliminó:

kubectl describe node minikube | grep -A3 Taints

Ejemplo de salida:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  minikube

Ahora nuestro nodo vuelve a tener solo el taint del plano de control.

Cuándo Usar Taints

Los taints son particularmente útiles en varios escenarios:

  1. Hardware especializado: Tainting nodos con hardware especial (como GPUs) para asegurar que solo las cargas de trabajo que requieren ese hardware se programen allí
  2. Mantenimiento de nodos: Agregar un taint antes de realizar el mantenimiento para evitar que se programen nuevos pods
  3. Aislamiento de seguridad: Mantener ciertas cargas de trabajo separadas de otras por razones de seguridad
  4. Optimización de recursos: Dedicar nodos a tipos específicos de cargas de trabajo para una utilización óptima de los recursos

Al comprender cómo ver, agregar y eliminar taints, ha adquirido conocimientos fundamentales para administrar la programación de pods en su clúster de Kubernetes.

Trabajando con Tolerancias

Ahora que entendemos cómo funcionan los taints, exploremos las tolerancias, el mecanismo que permite que los pods se programen en nodos con taints coincidentes.

Entendiendo las Tolerancias

Las tolerancias se especifican en las especificaciones de los pods y permiten que los pods se programen en nodos con taints coincidentes. Una tolerancia consta de:

  • key: Coincide con la clave del taint
  • operator: Ya sea Equal (coincide con la clave y el valor) o Exists (coincide solo con la clave)
  • value: El valor a coincidir (cuando se usa el operador Equal)
  • effect: El efecto a coincidir, o vacío para coincidir con todos los efectos
  • tolerationSeconds: Duración opcional durante la cual el pod puede permanecer en un nodo con un taint NoExecute coincidente

Creando un Pod con Tolerancias

Creemos un pod que tolera nuestro taint del plano de control. Primero, creemos un archivo YAML para nuestro pod:

nano ~/project/toleration-pod.yaml

Ahora, agregue el siguiente contenido al archivo:

apiVersion: v1
kind: Pod
metadata:
  name: toleration-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
  tolerations:
    - key: "node-role.kubernetes.io/control-plane"
      operator: "Exists"
      effect: "NoSchedule"

Esta especificación de pod incluye una tolerancia que coincide con el taint del plano de control en nuestro nodo. Guarde y salga del archivo (en nano, presione Ctrl+O, Enter, luego Ctrl+X).

Ahora, creemos el pod:

kubectl apply -f ~/project/toleration-pod.yaml

Debería ver una salida como:

pod/toleration-pod created

Verifiquemos si el pod se programó en nuestro nodo:

kubectl get pods -o wide

Ejemplo de salida:

NAME             READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
toleration-pod   1/1     Running   0          12s   10.244.0.5   minikube   <none>           <none>

El pod se está ejecutando en nuestro nodo minikube porque tiene una tolerancia que coincide con el taint del plano de control.

Probando con un Pod sin Tolerancias

Para comparar, creemos un pod sin tolerancias:

nano ~/project/no-toleration-pod.yaml

Agregue el siguiente contenido:

apiVersion: v1
kind: Pod
metadata:
  name: no-toleration-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest

Guarde y salga del archivo, luego cree el pod:

kubectl apply -f ~/project/no-toleration-pod.yaml

Ahora, verifiquemos el estado del pod:

kubectl get pods -o wide

Es posible que observe que el pod permanece en estado Pendiente:

NAME               READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
no-toleration-pod  0/1     Pending   0          12s   <none>       <none>     <none>           <none>
toleration-pod     1/1     Running   0          2m    10.244.0.5   minikube   <none>           <none>

Verifiquemos por qué el pod está pendiente:

kubectl describe pod no-toleration-pod

En la sección de eventos, debería ver algo como:

Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  45s   default-scheduler  0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.

Esto confirma que el pod no pudo programarse porque no tolera el taint del plano de control.

Limpieza

Limpiemos los pods que creamos:

kubectl delete pod toleration-pod no-toleration-pod

Debería ver:

pod "toleration-pod" deleted
pod "no-toleration-pod" deleted

¡Felicidades! Ahora comprende cómo los taints y las tolerancias trabajan juntos para controlar la programación de pods en Kubernetes.

Resumen

En este laboratorio práctico, aprendió a trabajar con taints y tolerancias de Kubernetes, características clave para controlar la programación de pods en su clúster. Esto es lo que logró:

  1. Configuró un entorno de Kubernetes utilizando Minikube
  2. Comprendió el concepto de taints y sus efectos en la programación de pods
  3. Exploró diferentes métodos para ver los taints en los nodos de Kubernetes
  4. Agregó y eliminó taints de los nodos utilizando comandos kubectl
  5. Creó pods con y sin tolerancias para ver cómo interactúan con los nodos con taints

Estas habilidades son esenciales para administrar la ubicación de la carga de trabajo y la asignación de recursos en los clústeres de Kubernetes. Al usar correctamente los taints y las tolerancias, puede asegurarse de que los pods se programen en los nodos apropiados en función de los requisitos de hardware, las características de la carga de trabajo y las restricciones de recursos.

A medida que continúa su viaje en Kubernetes, puede basarse en este conocimiento para implementar estrategias de programación más sofisticadas, como la afinidad y la anti-afinidad de nodos, para optimizar aún más los recursos de su clúster.