viernes, 25 de diciembre de 2020

Kubernetes - Conceptos básicos III

Siguiendo con los conceptos básicos de Kubernetes, vamos a estudiar de forma simple la arquitectura de un cluster de Kubernetes.

Vimos en la primera entrada de esta serie de posts que podíamos distinguir entre nodos master y nodos worker, llamados anteriormente minions. En general, dentro de la terminología de Kubernetes, un nodo es directamente un worker, el cual se caracteriza porque dispone del motor de ejecución de contenedores, los procesos kubelet y kube-proxy y es gestionado por los componentes del master.
 
En general, la arquitectura de un cluster de Kubernetes estará formado por uno o más nodos master y varios nodos worker. Los administradores usarán el comando kubectl para comunicarse con un balanceador de carga, que repartirá las conexiones entre todos los nodos master, controlando así el cluster y estableciendo el estado deseado del cluster. La forma más sencilla de ver esta arquitectura es la siguiente:
 
Arquitectura básica de un cluster de Kubernetes.

Esta gestión de los nodos worker por parte del master, se realiza mediante la comunicación entre el apiserver del nodo master y el proceso kubelet de los nodos worker. Esta comunicación permite al master obtener los logs del nodo worker, la ejecución de contenedores y proporcionar la característica de reenvío de puertos de kubelet.

Esta comunicación entre el apiserver y kubelet se realiza mediante el protocolo HTTPS, pero el apiserver por defecto no comprueba el certificado ofrecido por kubelet. Para forzar la comprobación del certificado ofrecido por kubelet, es necesario usar la opción --kubelet-certificate-authority del apiserver especificando un conjunto de certificados raíz que permitan la comprobación del certificado de kubelet.

El apiserver también se conecta con los nodos y contenedores usando el protocolo HTTP y aunque, puede cambiarse a HTTPS no se realiza ningún tipo de validación de credenciales ni de comprobación de certificados en estas conexiones.

Adicionalmente, los nodos worker y servicios del propio master se comunican con el apiserver, que por defecto acepta peticiones HTTPS en el puerto 443. Para añadir más seguridad a estas comunicaciones es importante utilizar autenticación de clientes, por ejemplo mediante certificados de cliente, así como autorizaciones para dichas conexiones.

Podemos obtener el estado de un worker, en base a una serie de características del mismo, utilizando el comando siguiente:

Descripción de estado de un nodo.
 
La salida de este comando es bastante extensa y entre toda la información que proporciona, nos devolverá el rol del nodo, su hostname y dirección interna y externa, la capacidad del nodo en terminos de CPU y memoria disponible, la versión del motor de ejecución de contenedores, una lista de los últimos eventos y el estado de condiciones como falta de memoria o disco.

Dentro de los tipos de condiciones de un nodo worker, es muy importante la condición Ready. Esta condición indica al master si el nodo worker es capaz de ejecutar contenedores y puede tener tres valores diferentes, True, False o Unknown. Si la condición Ready de un nodo worker permanece en estado False o Unknown durante más de un tiempo determinado, que por defecto son 5 minutos y se denomina pod-eviction-timeout, el kube-controller-manager del master lanza un borrado de los contenedores que se estén ejecutando en el nodo worker. Si el master no puede comunicarse con el proceso kubelet del nodo worker, es posible que los contenedores sigan ejecutándose en el nodo fallido hasta que la comunicación con el kube-apiserver vuelva a establecerse.

En caso de querer realizar algún tipo de operación de mantenimiento con un nodo worker, que implique que el nodo no puede aceptar contenedores, podemos hacer el nodo worker no disponible con el comando:

Marcando un nodo como no disponible.

El proceso kube-controller-manager del master ejecuta controladores que operan sobre recursos y objetos del cluster de Kubernetes, siendo uno de estos el controlador de nodos. Este controlador de nodos es responsable, entre otras cosas, de monitorizar la salud de todos los nodos del cluster y en caso de ser necesario, de mover los contenedores de un nodo que no responde a otro cuyo estado Ready sea True.