Home » Kubernetes Scheduling Parte 1
Kubernetes scheduling

Kubernetes Scheduling Parte 1

Kubernetes es una plataforma de orquestación compleja, pero magnífica. Entre sus funcionalides más básica está la de ofrecer diferente formas de asignación de Pods en los nodos. Aquí verás la forma más sencilla de hacerlo.

Kubernetes Scheduling parte 1 es el primero de una serie de artículos en los que trataré todo lo referente a cómo el cluster asigna los Pods en uno o más nodos.

Si te has topado con la necesidad de trabar con un cluster de múltiples nodos y deseas controlar cuáles de ellos deben o no deben correr ciertos Pods, entonces este artículo es para ti.

Acerca del Scheduling

El término scheduling se puede traducir al castellano como “programación” o “asignación”. La idea principal es el criterio de cómo organizar y/o distribuir ciertas cargas de trabajo sobre un grupo de recursos disponibles.

Kubernetes Scheduler

El Kubernetes Scheduler es un componente fundamental de Kubernetes que se encarga de asignar los pods a los nodos adecuados dentro de un clúster.

Proceso de Scheduling

El scheduling en Kubernetes es el proceso automático de asignar pods a los nodos adecuados dentro de un cluster.

Esta tarea, aparentemente simple, es fundamental para garantizar un uso eficiente de los recursos, un alto rendimiento y una alta disponibilidad de las aplicaciones desplegadas.

Un scheduling eficaz es esencial para evitar cuellos de botella, maximizar el aprovechamiento de los recursos y garantizar la escalabilidad de las aplicaciones en entornos dinámicos y complejos.

Cómo funciona

  1. Creación de un pod: Cuando se crea un nuevo pod, el scheduler lo evalúa.
  2. Selección de nodos candidatos: El scheduler busca en el clúster todos los nodos que cumplen los requisitos del pod (recursos disponibles, etiquetas, tolerancias, etc.).
  3. Clasificación de nodos: Los nodos candidatos se clasifican según una serie de prioridades y ponderaciones.
  4. Asignación del pod: El scheduler selecciona el nodo con la puntuación más alta y asigna el pod a él.

Cluster de pruebas

Antes de iniciar con la parte práctica sobre Scheduling, es importante contar con acceso a un cluster que tenga dos o más nodos Worker.

Hay muchas opciones para probar Kubernetes, ya sea en la nube (EKS, AKS, GKE, etc.) o localmente (Minikube, Kind, k3d, microk8s, etc.). De hecho, tengo dos artículos introductorios sobre las opciones que prefiero:

En mi caso personal, optaré por trabajar con k3d en este artículo, pero el lector puede usar cualquier otra alternativa de su preferencia.

Por ello, empezaré con la creación de un cluster de 3 nodos:

k3d cluster create demo -a 3

Mi cluster se llama “demo”. El nombre es lo de menos.

Ahora listo los nodos:

kubectl get node

Verifico que tengo 3 nodos worker:

Lista de 3 nodos worker en el cluster

Scheduling manual de Pods

Esta es la forma más básica de asignar un único Pod hacia un nodo particular. Esto es posible a través del atributo spec.nodeName en el objeto Pod.

Crear un Pod

Primero, veamos cómo se crea un Pod manualmente con un archivo de manifiesto:

# pod-manual.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx:latest
    name: nginx

Si la memoria te falla al recordar la estructura y atributos del manifiesto YAML, esta otra puede ser una alternativa:

kubectl run nginx --image nginx:latest --dry-run=client -o yaml > pod-cli.yaml

Ahora solo nos toca editar el archivo pod-cli.yaml creado con el comando anterior.

Especificaciones del Pod

Los atributos de un Pod son muchos, pero solo unos pocos los mínimos requeridos. Es necesario revisar la documentación extensa sobre la especificación de Pods en Kubernetes, pero esta es una tarea que algo laboriosa.

Otra opción más a nuestro alcance está en la misma línea de comandos, como sigue:

kubectl explain pod.spec

Al navegar sobre la documentación mostrada, podemos ver el atributo nodeName:

Documentacion de nodeName sobre un Pod

Entonces, ahora consultamos más detalles sobre ese atributo específico:

kubectl explain pod.spec.nodeName
Atributo nodeName del Pod explicado

La explicación es clara: “NodeName es una petición para asignar este pod en un nodo específico. Si este campo no está vacío, el scheduler simplemente asigna este pod en ese nodo, asumiendo que cumple con los requisitos de recursos.”

Pruebas de creación de Pod con asignación manual

Primero, probemos crear el pod desde el archivo de manifiesto pero sin usar el atributo spec.nodeName:

kubectl apply -f pod-manual.yaml

Ahora reviso la lista de Pods en ejecución para ver en qué nodo se asignó automáticamente:

kubectl get pods -o wide

Verifico que mi único pod está corriendo en el primer nodo worker:

Pod asignado a primer nodo worker por defecto

Ahora, eliminaré el pod antes de realizar la segunda prueba. Hago esto porque spec.nodeName no es un atributo que pueda ser modificado en un pod existente.

kubectl delete -f pod-manual.yaml

Esta vez voy a probar la asignación del pod al tercer nodo worker k3d-demo-agent-2, para lo cual debo editar el manifiesto YAML como sigue:

# pod-manual.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  nodeName: k3d-demo-agent-2 # Agrego esta linea
  containers:
  - image: nginx:latest
    name: nginx

Luego, procedo a aplicar los cambios y ver la lista detallada de pods:

kubectl apply -f pod-manual.yaml
kubectl get pods -o wide

Aquí se verifica que el Pod fue ejecutado en el nodo que le indiqué:

Pod asignado a tercer nodo worker

Conclusión

En este artículo he mostrado la primera y más básicas de las formas de asignar un Pod a cierto nodo específico, el cual lo tuve que definir por su nombre dentro del archivo de manifiesto.

Si bien se hizo pruebas con la creación de un Pod, lo mostrado líneas arriba es aplicable de igual manera para otros objetos como Deployments o DaemonSets. Aquí un ejemplo:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeName: k3d-demo-agent-2 # Nodo especifico deseado
      containers:
        - image: nginx
          name: nginx

Esta manera de asignar Pods en base al atributo spec.nodeName es la más sencilla de comprender, pero también la más limitada de todas. No es posible reasignar el Pod a otro nodo si el primero al cual fue asignado fallase (en dicho caso el Pod se quedará en estado Pending). Tampoco es posible elegir automáticamente uno o más nodos worker apropiados según diversos criterios. Pero tal vez, solo para necesidades muy básicas esta forma de asignación es más que suficiente.

En un próximo artículo compartiré una segunda forma de asignar Pods a nodos: basado en el uso de selectores de labels o etiquetas.

Post navigation

Deja un comentario

Agregue un comentario

Su dirección de correo no se hará público. Los campos requeridos están marcados *