Cómo se gestionan las réplicas de tus pods en Kubernetes

Voy escribiendo los artículos según yo creo que vas necesitando incorporar nuevas piezas a tu entendimiento de Kubernetes. No sé si es la forma más habitual, pero es la que yo he ido utilizando en mi propio aprendizaje. A grandes rasgos, hasta ahora te he contado:

Con todo ello ya eres capaz de desplegar aplicaciones en Kubernetes, exponerlas a través de un balanceador, gestionar el almacenamiento que utilizan, así como la configuración asociada que puedan tener. Llegados a este punto, para poder entender lo que sigue, creo que es importante revisar algunos matices que son necesarios para dar un salto en tu aprendizaje. Es por ello que hoy quería hablarte de cómo Kubernetes gestiona las réplicas de tus aplicaciones a través del objeto ReplicaSet.

¿Qué son los ReplicaSet?

Como todo en Kubernetes, se trata de un tipo de objeto que tiene como tarea asegurarse de que el número de réplicas que se ha establecido para un pod se cumpla. Estos objetos son los sucesores de otros llamados ReplicationControllers, los cuales sólo deberían usarse por un tema de retrocompatibilidad, ya que los ReplicaSet mejoran la forma de seleccionar qué pods le corresponden. No se suelen desplegar directamente sino que se usa un Deployment, el cual a su vez despliega un ReplicaSet de manera transparente por nosotros. La razón principal es que los Deployments nos permiten gestionar actualizaciones de los pods y los ReplicaSet no.

Para que entiendas cómo funcionan, voy a recuperar el YAML de ejemplo del primer Deployment que hice en el artículo Ejecutar contenedores de Docker en Kubernetes:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

Ejecuta este despliegue en tu clúster:

kubectl apply -f deployment.yaml

Podrás ver que tienes un despliegue:

kubectl get deployments

Un ReplicaSet:

#Get replicasets
kubectl get replicasets
kubectl get rs

Y tres pods:

kubectl get pods

A nginx-deployment, que es el nombre de nuestro despliegue, se le añade un literal aleatorio, en este ejemplo 64fc4c755d, como nombre del ReplicaSet. A cada pod se le asignará el nombre del ReplicaSet más otro literal aleatorio. De esta manera, será sencillo averiguar a simple vista a qué ReplicaSet corresponde un pod.

Deployment, replcaset y pods asociados

Por supuesto, también puedes ver esta información en el dashboard de Kubernetes, en el apartado ReplicaSets.

Nota: Si no tienes un clúster de Kubernetes puedes usar Azure Kubernetes Services o alguna de las opciones que te contaba en este artículo.

¿Cómo sabe un ReplicaSet qué pods son suyos?

Si bien el nombre es bastante descriptivo, el ReplicaSet determina que un pod es suyo por el selector que tiene definido. Si lanzamos el siguiente comando por cada uno de los pods existentes veremos que el selector para los tres tiene dos etiquetas:

kubectl describe pod 

De hecho, el valor de la etiqueta pod-template-hash es el mismo asociado al nombre del ReplicaSet y a los pods. También puedes comprobar en el propio objeto que el selector coincide con estas etiquetas, además de ser las que se le asignen a nuevos pods (tienes más información sobre cómo funcionan las etiquetas en este otro artículo):

Descripción del replicaset

Si quisiéramos hacer una prueba empírica de que esto es así, podrías crear un pod que contenga ambas etiquetas y podrás comprobar que el mismo es eliminado de manera automática. Esto es así porque el ReplicaSet comprobará que el número de replicas que necesita son tres, y no más de tres, y tomará este nuevo pod como suyo y verá que le sobra.

Como escalar automáticamente el ReplicaSet

Por último, si queremos autoescalar nuestros pod es posible a través de otro objeto llamado Horizontal Pod Autoscaler. Podemos decir que se tratan de reglas las cuales en base a una métrica pueden solicitar a los ReplicaSet que aumenten o disminuyan sus pods:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: auto-scaler
spec:
  scaleTargetRef:
    kind: ReplicaSet
    name: nginx-deployment-64fc4c755d
  minReplicas: 3
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

En este ejemplo, dependiendo de la CPU de los pods que hay actualmente subirá o bajará el número con un mínimo de 3 y un máximo de 10.

También puedes hacer lo mismo con el siguiente comando:

kubectl autoscale rs nginx-deployment-64fc4c755d --max=10 --cpu-percent=50

Ahora ya sabes cómo Kubernetes gestiona las réplicas de tus pods 🙂

¡Saludos!