Instalación de un cluster local de Kubernetes con Ubuntu

El cluster de Kubernetes está formado por servidores master, que controlan el cluster, y por nodos (worker nodes) que es donde corren los contenedores. Por norma general se debe disponer de 3 servidores master y tantos nodos como carga queramos soportar, por norma general son como mínimo 3.

En este post vamos a crear una infraestructura de un master y un nodo que posteriormente seria ampliable a lo aconsejado para una infraestructura de producción.

Las máquinas deberán tener un mínimo de 2Gb de RAM y 2 CPUs, el servidor maestro no funcionará si no dispone de estos recursos.

En todos los servidores (maestro y nodos) instalaremos la versión la última versión de Ubuntu, en nuestro caso Ubuntu 20.04.3 LTS, realizaremos los siguientes pasos:

  • Preparación de los servidores
  • Instalación de Kubernetes (kubeadm, kubelet y kubectl)

Preparación de los servidores

Esta configuración inicial se debe hacer en el master y en el nodo, por lo que podemos realizarla completamente en un equipo y posteriormente clonar el servidor.

Instalaremos el servidor con la configuración por defecto y posteriormente lo actualizaremos con los últimos parches disponibles:

# apt-get update && apt-get upgrade

Una vez instalado realizaremos algunos cambios en el sistema e instalaremos docker

Paso 1

Aseguraremos que el módulo de red br_netfilter está cargado. Crearemos el fichero para la carga del módulo:

# cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

Aplicaremos la siguiente configuración en el Kernel

# cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# sysctl --system

Paso 2

En nuestro caso desactivaremos el protocolo IPv6 para que no nos de problemas más tarde en las configuraciones de red del cluster:

Modificaremos el fichero de configuración del Kernel /etc/default/grub añadiendo o modificando las siguientes líneas:

GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1"
GRUB_CMDLINE_LINUX="ipv6.disable=1"

Ejecutaremos el siguiente comando y reiniciaremos:

# update-grub

Paso 3

Desactivamos el Swap en los servidores:

# swapoff -a

Y eliminaremos la entrada en el /etc/fstab

Paso 4

Comprobaremos que los servidores pueden comunicarse entre ellos, los puertos utilizados son los siguientes:

Paso 5

Kubernetes puede funcionar con varios tipos de contenedores, en nuestro caso utilizaremos Docker. Si no especificamos nada Kubernetes automáticamente detectará el runtime instalado en nuestro sistema.

Instalaremos Docker en todos los servidores:

# apt-get install docker.io

# systemctl enable docker

# systemctl daemon-reload

# systemctl restart docker

El runtime de contenedores y Kubernetes tienen una propiedad llamada “cgroup driver” que es importante para manejar los cgroup en Linux (asignación de recursos a los procesos) esta propiedad tiene que tener el mismo valor en el runtime (docker) y en Kubernetes, los valores posibles son “cgroupfs” y “systemd”, aunque la página oficial de Kubernetes aconseja que sea “systemd”. Para comprobar el valor de docker ejecutaremos el siguiente comando:

# docker info | grep Cgroup

En el caso que el valor sea “cgroupfs” prodremos cambiarlo creando o modificando el fichero /etc/docker/daemon.json y añadiendo lo siguiente:

{
  "exec-opts": ["native.cgroupdriver=systemd"]
}

Reiniciaremos docker y volveremos a comprobar el valor.  Para Kubernetes, en la versión 1.22 si no se especifica el campo cgroupDriver en KubeletConfiguration por defecto kubeadm tendrá el valor de systemd.

Para finalizar este paso reiniciaremos el servidor.

Instalación de Kubernetes (kubeadm, kubelet y kubectl)

En cada paso se indica en que servidores se aplicará la configuración.

Paso 1

Añadiremos el repositorio de Kubernetes en todos los servidores del cluster:

# apt-get install -y apt-transport-https ca-certificates curl

# curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

# echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# apt update

Paso 2

Procederemos a instalar los siguientes paquetes en todos los servidores:

  • kubeadm: Comando para crear el cluster
  • kubelet: Es el componente que está corriendo en todos los servidores del cluster y se encarga de realizar varias tareas, entre ellas iniciar pods y contenedores.
  • kubectl: Comando para interactuar con el cluster.
# apt-get install -y kubelet kubeadm kubectl

Marcaremos los paquetes de Kubernetes para que no se actualicen automáticamente, el motivo es porque la actualización deestos componentes se debe realizar de forma controlada:

# apt-mark hold kubelet kubeadm kubectl

Paso 3

Una vez instalados todos los componentes en todos los servidores pasaremos a configurar el cluster y el driver de red (weave) en el servidor maestro:

  • Inicialización del cluster
  • Instalación del driver de red weave

Para iniciar el cluster ejecutaremos:

# kubeadm init

Al finalizar el comando anterior nos mostrará el comando “kubeadm join” que utilizaremos para añadir nodos posteriormente.

Para tener permisos de administración de Kubernetes  deberemos copiar el archivo de configuración que proporciona Kubernetes en el home del usuario desde el cual vayamos a administrar el cluster:

# mkdir -p $HOME/.kube

# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

# chown $(id -u):$(id -g) $HOME/.kube/config

El siguiente paso es instalar el plugin de red, disponemos de varias opciones, en nuestro caso utilizaremos Weave. La instalación del componente de red es sencilla sólo deberemos ejecutar una instrucción:

# kubectl apply -f https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')

Paso 4

Finalmente con la instrucción “kubeadm join” proporcionada anteriormente al crear el cluster procedemos añadir los nodos o workers:

Podremos comprobar el cluster con el siguiente comando ejecutándolo desde el nodo master:

# kubectl get nodes