sábado, 5 de septiembre de 2020

Kubernetes - Conceptos básicos II

Tras el post sobre PODs y servicios, hoy vamos con más rollo teorico en el que veremos los objetos de Kubernetes y algunos conceptos importantes que usaremos más adelante.

Ya vimos que definiendo objetos del API de Kubernetes, establecemos la configuración deseada del cluster y que el KCP se encarga de realizar todas las tareas necesarias para que el cluster llegue a dicho estado.

Los objetos disponibles en el API de Kubernetes permiten establecer, entre otras cosas:
  • Las aplicaciones que deben ejecutarse en los contenedores.
  • Los recursos disponibles para la ejecución de dichas aplicaciones.
  • Las políticas que se aplican a dichas aplicaciones.
Ya que un objeto de Kubernetes es una definición de un estado deseado, una vez que hemos creado un objeto, Kubernetes trabajará de forma constante para que dicho objeto exista con las características que hayamos definido para él mismo.

Podemos decir que cada objeto de Kubernetes posee dos conjuntos de información que están relacionados entre sí:
  • La especificación del objeto (object spec), que es la definición de las caracterísiticas del objeto. El spec establece la configuración que deseamos del objeto. Por tanto nosotros seremos quien proporcionemos la especificación del objeto.
  • El estado del objeto (object status), que es el estado real del objeto gestionado por Kubernetes y por tanto, proporcionado y actualizado por el sistema.
Como ya vimos en la entrada anterior de esta serie, el KCP realizará todas las tareas necesarias para que el estado sea idéntico a la especificación del objeto.

¿Cómo podemos establecer la configuración de un objeto de Kubernetes? mediante YAML, siendo la estructura básica para definir un objeto la siguiente:

Definición básica de un objeto.
 
En cada fichero YAML que creamos hay una serie de campos requeridos que debemos definir a la hora de establecer la configuración de un objeto, siendo cada uno de ellos:
  • apiVersion, versión del API de Kubernetes utilizada para definir el objeto.
  • kind, tipo de objeto que estamos definiendo.
  • metadata, información usada para identificar claramente el objeto. Lo normal es que contenga el nombre del objeto y, en algunos casos, etiquetas para establecer relaciones entre diferentes objetos.  
  • spec, contendrá la configuración del objeto y por tanto, el estado deseado del mismo. En función del tipo de objeto (kind), el contenido de esta sección contendrá diferentes campos.
Como vemos, el campo metadata contendrá el nombre del objeto que estamos definiendo o sobre el que queremos realizar alguna operación. El nombre de un objeto debe ser único en el cluster para ese tipo de recurso, es decir, puedo tener objetos con el mismo nombre siempre y cuando sean de diferentes tipos. Además del nombre dado por nosotros, el objeto estará identificado por un UID generado de forma automática por Kubernetes.

Para poder añadir información más descriptiva a los objetos, el campo metadata admite el uso de annotations mediante las cuales podremos añadir parejas clave/valor arbitrarias. Por ejemplo:

Uso de annotations.
 
Adicionalmente también podemos usar labels dentro del campo metadata para incluir más información en los objetos. La principal diferencia entre annotations y labels es que estas últimas se utilizan para identifcar objetos dentro del cluster y como hemos visto con los services, nos permiten relacionar unos objetos con otros.

Por último, el campo metadata también puede especificar en que namespace debe realizarse la operación. Un namespace es una forma de particionar o dividir un cluster de Kubernetes en clusters virtuales, permitiéndonos la asignación de diferentes recursos a cada uno.

Dentro del mismo namespace los nombres de los recursos deben ser únicos, no pueden anidarse entre si y un objeto solo puede existir en un namespace. En un cluster recien desplegado existen tres namespaces por defecto:
  • default, namespace por defecto donde crearemos nuestros objetos.
  • kube-system, namespace del sistema donde se crean objetos propios de Kubernetes.
  • kube-public, namespace reservado para uso del cluster y de lectura para todos los usuarios, incluidos los no autenticados.
Es muy importante tener en cuenta la relación entre el servicio DNS interno de Kubernetes, el cual se ejecuta en el namespace kube-system, y el namespace de un objeto. Cada vez que se crea un objeto de tipo Service, Kubernetes crea una entrada DNS para el mismo con el nombre:

Nombre DNS de un objeto de tipo Service.
 
De esta manera podremos acceder desde un POD a servicios de diferentes namespaces con solo especificar el nombre completo DNS.

Para terminar, no todos los recursos están en un namespace, así recursos de bajo nivel como los nodos que forman el cluster no se encuentran en ningún namespace, lo cual podemos consultar con el comando:

Como listar recursos relacionados con o sin namespace.

Y de nuevo, una vez descrito un objeto en un fichero YAML, solo tendremos que aplicar dicha descripción al cluster mediante el comando: 

Comando kubectl.
 
Emplearemos el comando kubectl continuamente para interactuar con el cluster de kubernetes y cambiar el estado deseado del cluster. Este comando interactua directamente con el kube-apiserver que se encuentra en los nodos master del cluster.

Hasta aquí el roolo teórico de hoy. En próximas entradas seguiremos estudiando los objetos básicos de Kubernetes y trabajando con ellos.