Crear un entorno de Kubernetes en alta disponibilidad con Ubuntu 20.04 y K3s

Retomamos la actividad este mes de marzo, hablando de Kubernetes y de cómo implementar un nuevo entorno con K3s. La idea es crear un entorno para desplegar microservicios, ya sabéis todo eso de los contenedores, como laboratorio de pruebas.

Para ello, como viene siendo habitual, voy a utilizar mi proveedor de confianza Clouding.io. En esta plataforma he creado tres servidores cloud. Uno de ellos servirá como servidor maestro, y otros dos como workers. Una arquitectura bastante típica. Los tres equipos llevarán como sistema operativo Ubuntu 20.04

Logo oficial de K3S

Un entorno de Kubernetes en alta disponibilidad con Ubuntu y K3s

Imagino que ya sabrás que es eso de los microservicios y que hay varias maneras de crear un nuevo entorno con Kubernetes. Yo me he decantado con K3s. Producto que está diseñado para gestionar las cargas de trabajo en alta disponibilidad, en ubicaciones remotas desatendidas, con recursos limitados o dentro de dispositivos de Iot. Esto es, también es ideal para entornos con procesadores ARM64 como ARMv7, como esas plaquitas que tienes por casa como las Raspberry Pi.

Preparar el entorno

Cuando he creado los equipos les he asignado una IP privada, además de la IP pública que llevan por defecto, que es con las que trabajará el entorno.

Primero de todo tenemos que actualizar los equipos. Para poder trabajar con los tres a la vez, la manera más fácil es utilizar herramientas Pssh, o bien utilizar Ansible o Puppet, para igualar la configuración, que es lo que he hecho yo, utilizando varias clases.

Para actualizar:

sudo apt update
sudo apt upgrade -y

Igualamos el fichero «/etc/hosts» en los tres entornos.

sudo vim /etc/hosts

En mi caso:

10.20.10.2 servmaster.bitsandlinux.com servmaster puppet
10.20.10.5 servnode1.bitsandlinux.com servnode1
10.20.10.6 servnode2.bitsandlinux.com servnode

Abrir puertos en el Firewall

Clouding.io al igual que otros proveedores incorpora un cortafuegos configurado. En este debemos abrir los puertos 6443 y el 443, que son los que necesita el entorno para que se comuniquen los nodos.

Además, si utilizamos algún gestor de cortafuegos en los equipos, como UFW, debemos abrir también estos puertos en los hosts.

Instalar Docker en Ubuntu 20.04

Aquí lo podemos hacer la instalación nodo por nodo, o bien, por ejemplo, utilizar un Playbook de Ansible, que es lo que he hecho yo, lo podéis consultar aquí: Playbook Ansible para instalar Docker

Si en cambio, queremos ir nodo por nodo:

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"

Y ahora instalamos:

sudo apt update
sudo apt install docker-ce -y

Habilitamos el servicio al arranque y lo encendemos:

sudo systemctl start docker
sudo systemctl enable docker

Podemos comprobar su estado:

Comprobamos el estado de docker en el nodo

Por último, añadimos nuestro usuario, si así lo deseamos, para no utilizar root, a sudo:

sudo usermod -aG docker davidochobits
newgrp docker

Configuramos K3s en el nodo maestro

Previamente a lanzar la línea de instalación vamos definir unas variables de entorno:

INSTALL_K3S_EXEC="server \
--disable=traefik \
--flannel-iface=eth1 \
--bind-address 10.20.10.2 \
--advertise-adress 10.20.10.2 \
--node-ip 10.20.10.2 \
--datastore-endpoint etcd \
--node-external-ip 27.0.174.15 \
--cluster-init"

De esta manera indicamos que queremos que utiliza la interfaz «eth1» como interfaz principal para crear la red con su correspondiente IP, también indicamos el tiempo de datastore, la IP externa que ha de utilizar y que no queremos utilizar «traefik»

Ahora lanzamos la línea de instalación:

curl -sfL https://get.k3s.io | sh -s - --docker

Una vez hecho esto, si no nos ha aparecido ningún error, ya podríamos ver el estado del servicio K3s:

systemctl status k3s

De esta manera:

Comprobamos el estado de K3s

Y empezamos a utilizar los comandos de Kubernetes. Primero comprobamos que el nodo efectivamente está funcionando:

kubectl get nodes -o wide

Con este resultado en mi caso:

Vemos el estado del nodo

Instalar K3s en los nodos worker

Haremos lo mismo que hemos hecho en nodo maestro, pero variando las variables:

INSTALL_K3S_EXEC=" \
--flannel-iface=eth1 \
--node-ip 10.20.10.5"

Aquí el «node-ip» variará por cada nodo.

Antes de lanzar el comando de instalación debemos saber el TOKEN que tiene el nodo maestro, este código lo podemos ver consultando el fichero «/var/lib/rancher/k3s/server/token«

curl -sfL http://get.k3s.io | K3S_URL=https:"IP-MAESTRO"//:6443 K3S_TOKEN="TOKEN" sh -s - --docker

Una vez añadidos, comprobamos el estado de todos los nodos del entorno:

kubectl get nodes

Tal y como se ve en la imagen:

Vemos el estado de los tres nodos

De esta manera ya tendríamos el entorno funcionando.

Habilitar HELM y conplementos

Para facilitar las cosas en nuestro día a día siempre es recomendado instalar HELM, del que ya hablamos.

Nos descargamos la última versión desde este enlace.

wget https://get.helm.sh/helm-v3.8.1-linux-amd64.tar.gz

Descomprimimos:

tar xvf helm-v3.8.1-linux-amd64.tar.gz

Y movemos el binario:

sudo mv linux-amd64/helm /usr/local/bin/

Añadimos entonces nuevos repositorios:

helm repo add stable https://charts.helm.sh/stable
helm repo update

Despliege de aplicaciones

Montar todo este entorno no tendría sentido si después no muestro un ejemplo de despliegue de aplicaciones.

A modo de ejemplo vamos a desplegar un servicio con NGINX, utilizando HELM

#Añadimos el repositorio
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
#Y actualizamos helm
helm repo update

Ahora ya podemos instalar:

helm install nginx-ingress \
ingress-nginx/ingress-nginx \
--namespace kube-system  \
--set defaultBackend.enabled=false

Su aquí os aparece algún error, y nos indica el sistema no se puede comunicar con Kubernetes, debemos indicar donde esta el fichero de configuración:

export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

Una vez hecho esto ya no deberíamos tener más problemas.

Comprobamos que efectivamente la aplicación está desplegada, listamos los recursos del namespace:

kubectl get pods -n kube-system

En mi caso me indica que está funcionando sobre el nodo 1:

Comprobamos el estado del despliegue

Y ahora sí, ya podemos ver nuestra IP pública expuesta en el entorno:

Comprobar que efectivamente ya tenemos la IP pública expuesta

Y ahora la pregunta es, ¿relamente tenemos el nginx expuesto?

Mensaje 404 de Nginx

Como es natural nos sale un mensaje 404, esto es normal, ya que no hemos añadido todavía contenido.

Ahora, como decía el gran Joaquin Prat, «A jugar!!» 🙂

Entradas consultadas

Stackoverflow – Is there any way to bind K3s / flannel to another interface?

Computingforgeeks.com – Install Kubernetes Cluster on Ubuntu 20.04 using K3s

Github.com – Kubernetes/ingress-nginx