Cómo funcionan las etiquetas en Kubernetes

Si estás trabajando con Kubernetes, para tu entorno de contenedores, uno de los conceptos que debes aprender la mar de bien es el de label o etiquetas. Básicamente porque sobre este concepto se apoyan diferentes mecanismos, que debes entender perfectamente, como por ejemplo la pertenencia a un ReplicaSet o la distribución de los pods sobre tus nodos. En este artículo te quiero contar cómo se crean, se visualizan y se usan.

Crear etiquetas durante la creación de un recurso

Normalmente las etiquetas suelen tener un significado dentro del contexto de tu clúster. Cada etiqueta trata de un par clave=valor que pueden tener la clave que quieras y el valor que quieras. Para crearlas puedes hacerlo desde el propio archivo YAML que define tu recurso:

#pod-with-labels.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-with-labels
  labels:
    owner: gisela
    env: test
    type: web
spec:
  containers:
  - image: nginx
    name: nginx
    ports:
    - containerPort: 80
      protocol: TCP

Como ves, en este caso he creado tres etiquetas con tres valores diferentes: owner, env y type. Puedes crear el recurso para ver el resultado:

kubectl create -f pod-with-labels.yaml

Para poder ver las etiquetas asociadas a un pod debes especificar el parámetro –show-labels:

kubectl get po --show-labels
kubectl get po –show-labels

Verás una última columna donde aparecen todas las etiquetas que has asociado como parte de tu pod en este caso. Estas por si solas no hacen absolutamente nada, pero son importante para muchos escenarios, como por ejemplo tus propios scripts.

Añadir y modificar etiquetas a pods existentes

También es posible añadir etiquetas a recursos que ya existen. Para ello, puedes utilizar kubectl label, el tipo de recurso, el nombre del que quieres etiquetar, así como las propias etiquetas:

kubectl label po nginx-with-labels release=52

Si por el contrario quisieras modificar una etiqueta ya existente solo tienes que añadir el parámetro –overwrite al comando anterior:

kubectl label po nginx-with-labels release=53 --overwrite

Filtrar por etiquetas

La parte más importante de todo esto es la capacidad de filtrar por una o varias etiquetas:

kubectl get po -L owner,env
kubectl get po -L owner,env

También puedes filtrar no solo por la clave, sino por el valor de las mismas:

kubectl get po -l owner=gisela,env=test

O incluso por aquellos pods que no tienen una o varias etiquetas asignadas:

kubectl get po -l '!env'

También puedes querer buscar todos los objetos que tengan cualquier valor excepto uno en concreto, o que el valor esté contenido en una lista que le pasemos o que no esté dentro de dicha lista:

kubectl get po -l 'owner!=gisela'
kubectl get po -l 'env in (prod,pre,dev)'
kubectl get po -l 'env notin (test,dev)'

Como puedes ver, todo lo que se trate de expresiones deben ir dentro de comillas, para que kubectl lo interprete correctamente.

Ejemplo real del uso de las etiquetas

Ahora que ya sabes crear, modificar y filtrar por etiquetas quiero mostrarte un caso real de su uso. Por supuesto, uno de ellos es el uso en tus propios scripts, para poder aplicar ciertos cambios sobre los recursos seleccionados, pero el propio Kubernetes también hace un uso intensivo de las mismas. Un ejemplo claro de ello es cómo el recurso ReplicaSet se apoya en ellas para controlar cuántos pods tiene y así saber si cumplen el estado deseado definido en su especificación. Para verlo más claro, voy a crear un recurso de este tipo que controle el número de replicas que necesita del pod nginx-with-labels:

#replicaset-for-nginx-with-labels.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-with-labels  
spec:
  replicas: 3
  selector:
    matchLabels:
      type: web
      owner: gisela
  template:
    metadata:
      labels:
        type: web
        owner: gisela
    spec:
      containers:
      - name: nginx-with-labels
        image: nginx

En el apartado selector se le dice a este ReplicaSet que busque aquellos pods que tengan las labels type y owner con unos valores específicos. Si creas este recurso:

kubectl create -f replicaset-for-nginx-with-labels.yaml

y compruebas de nuevo tus pods podrás ver que ahora tienes 3, contando con el que creaste en primer lugar.

Esto es así porque los ReplicaSet filtran por la expresión definida en el selector y comprueban si el número de pods que existen se ajustan al estado deseado, en este caso 3 réplicas.

Del mismo modo, también es posible eliminar una o varias etiquetas de un pod y, en este caso, nuestro ReplicaSet se dará cuenta de que le falta una replica, al no cumplir con el selector establecido, creando un nuevo pod:

kubectl label po nginx-with-labels type-
kubectl label po nginx-with-labels type-

Este escenario es útil cuando queremos sacar un pod controlado por un ReplicaSet para su posterior revisión o análisis.

Existen diferentes casos en los que Kubernetes hacen uso de este mecanismo. No sólo los pods son susceptibles de ser etiquetados. Por ejemplo, también es posible etiquetar los nodos que componen el clúster, especificando por ejemplo las capacidades de estos y posteriormente utilizar la propiedad nodeSelector junto con las etiquetas que debe cumplir el nodo para el despliegue del recurso.

¡Saludos!