Instala y configura K3s en HA o Single Master

Tener dos nodos master no va a dotar a nuestra infraestructura de mas velocidad o capacidad de ejecutar pods, sin embargo si nos va a permitir tener una tolerancia a fallos en uno de los nodos maestros bien sea por un fallo hardware, un bug en el software o simplemente una actualización. Por lo tanto la decisión depende del numero de Raspberrys que tengamos; para un despliegue en HA recomendaría un mínimo de 4 placas: dos que harían las veces de master y las dos restantes de workers. ¿Podríamos tener solo un worker? definitivamente si, ya que podríamos activar la opción de ejecutar pods también en los nodos master como ya veremos más adelante, pero personalmente no me parece una buena idea.

Instalación

Primero voy a detallar la instalación de los Master Nodes ya sea como Single Master o bien en High Availability. El despliegue de los Workers Nodes sería común a ambos entornos.

Single Master

La estructura de ésta instalación sería la que podemos ver a continuación:

Despliegue de K3s con un solo master node

Los elementos que constituyen la instalación son:

  1. K3sUser: Es nuestro servidor o portátil donde tenemos instalado kubectl, que es la utilidad de Kubernetes para gestionar el cluster por línea de comandos.
  2. SQLite: Es la base de datos donde se almacenan todos los datos del cluster, está embebida en el propio nodo. Ésta será la gran diferencia con la instalación en HA.
  3. Agent Nodes: O workers, donde vamos a ejecutar nuestros amplicativos
  4. Load Balancer: En base a la carga del cluster, decide a que nodo nuestra petición.
  5. External Traffic: Poco que añadir, es nuestra petición que realizamos al cluster.

Asuminendo que ya estamos dentro del nodo seleccionado, seguimos los siguientes pasos:

Establecer las variables de entorno

$ export K3S_KUBECONFIG_MODE="644"
$ export INSTALL_K3S_EXEC=" --no-deploy servicelb --disable traefik"

La primera linea nos permite manejar el cluster sin ser usuario root. La segunda necesita una pequeña explicación; por defecto, K3s despliega un Load Balancer y un Proxy propio llamados servicelb y traefik. En su momento me encontré con bastantes problemas para hacerlo funcionar con mis pods, por lo que decidí utilizar metalb como Load Balancer y el más que conocido Nginx como Proxy. Mediante esos flags, evitamos que se instalen esos servicios por defecto, para poder instalar después de manera manual metalb y nginx.

Ejecutar el instalador

Simple y directo, una sola línea y él se encarga de todo.

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

[INFO]  Finding latest release
[INFO]  Using v1.18.3+k3s as release
[INFO]  Downloading hash https://github.com/rancher/k3s/releases/download/v1.18.3+k3s/sha256sum-arm.txt
[INFO]  Downloading binary https://github.com/rancher/k3s/releases/download/1.18.3+k3s/k3s-armhf
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Creating /usr/local/bin/ctr symlink to k3s
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s

Verificar la instalación

El instalador crea un servicio que se puede usar para iniciar, parar, reiniciar y verificar su estado actual:

pi@noldork3sM:~ $ sudo systemctl status k3s
● k3s.service - Lightweight Kubernetes
   Loaded: loaded (/etc/systemd/system/k3s.service; enabled; vendor preset: enab
   Active: active (running) since Sat 2020-07-04 17:16:24 CEST; 4h 16min ago
     Docs: https://k3s.io
  Process: 25865 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0
  Process: 25866 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCC
 Main PID: 25867 (k3s-server)
    Tasks: 15
   Memory: 124.2M
 (...)

Igualmente, el instalador despliega el Kubernetes Command Line Tools kubectl, para que podemos interactuar con el cluster:

pi@noldork3sM:~ $ kubectl get nodes -o wide
NAME          STATUS   ROLES    AGE   VERSION        INTERNAL-IP      
noldork3sm    Ready    master   5m   v1.18.3+k3s1   192.168.1.245   

También podemos ver los pods que se han desplegado con la instalación:

$ kubectl get pods -A -o wide

NAMESPACE     NAME                                      READY   STATUS    
kube-system   metrics-server-7566d596c8-rgwgm            1/1   Running   
kube-system   local-path-provisioner-6d59f47c7-xh6t5     1/1   Running   
kube-system   coredns-8655855d6-pkxmp                    1/1   Running   

Alta Disponibilidad (HA)

Nuestra instalación en este caso, tendría la siguiente estructura:

Despliegue de K3s en HA

Las diferencias notables entre ésta instalación y la anterior son dos: la primera es que contamos con un o varios nodos que actúan como masters y la segunda, y más importante, es que la base de datos para a ser una base de datos externa.

Por lo tanto, si optamos por opción, deberemos tener lista otra raspberry (o placa arm por continuar con la misma arquitectura) externa donde se pueda ejecutar nuestro servidor de base de datos.

Una vez tengamos el servidor de base de datos listo, creamos nuestra base de datos, usuario y contraseña mediante los siguientes comandos :

mysql> CREATE database <database>;
mysql> CREATE USER <user>'@'%' IDENTIFIED BY '<password>';
mysql> GRANT ALL ON <database>.* TO '<user>'@'%';
mysql> flush privileges;

Ahora solo nos resta continuar con los siguientes pasos que deberemos ejecutar en todos los nodos que vayan a ser Master, y que como veréis son prácticamente los mismos que la instalación Single Master :

Establecer las variables de entorno

$ NODE_TOKEN=$(echo $(hostname) $(date +%s) | shasum | base64) 
$ export K3S_KUBECONFIG_MODE="644"
$ export INSTALL_K3S_EXEC=" -t ${NODE_TOKEN} --tls-san <hostname> --no-deploy servicelb --disable traefik --node-taint k3s-controlplane=true:NoExecute --datastore-endpoint mysql://<dbuser>:<dbpassword>@tcp(<dbhostname>:3306)/<database>"

La primera linea no es una diferencia como tal, ya que la vamos a usar también en una instalación Single Master cuando vayamos a añadir los workers. Sin embargo, en esta modalidad, vamos a utilizar mas de un Master Node por lo que necesitamos este token para crear nuestro cluster. Apuntar bien el valor de esa variable puesto que la necesitaremos más adelante, para ello ejecutamos este comando:

$ echo $NODE_TOKEN

La segunda línea es común a la instalación anterior. Sin embargo en la tercera línea si encontramos diferencias:

  • –tls-san <hostname> / <ip>: es necesaria para evitar errores de certificados en la configuración del cluster. Debemos especificar el hostname o la ip de nuestro nodo master.
  • –node-taint k3s-controlplane=true:NoExecute: esta opción es opcional, de hecho, la podríamos especificar también en una instalación Single Node . Nos sirve para evitar que los pods se ejecuten en nuestro nodo Master, lo que es muy util si nuestras placas no tienen suficiente potencia.
  • –datastore-endpoint mysql://<dbuser>:<dbpassword>@tcp(<dbhostname>:3306)/: es quizás la más importante de todas y la clave de todo. Estamos especificando el usuario, contraseña y hostname/ip de nuestro servidor donde se ejecuta nuestra base de datos, en este ejemplo MYSQL

Ejecutar el instalador

Exactamente igual que con un solo master node:

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

[INFO]  Finding latest release
[INFO]  Using v1.18.3+k3s as release
[INFO]  Downloading hash https://github.com/rancher/k3s/releases/download/v1.18.3+k3s/sha256sum-arm.txt
[INFO]  Downloading binary https://github.com/rancher/k3s/releases/download/1.18.3+k3s/k3s-armhf
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Creating /usr/local/bin/ctr symlink to k3s
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s

Una vez estén listos todos los Master Nodes podemos comprobar su estado mediante el comando kubectl:

pi@noldork3sM:~ $ kubectl get nodes -o wide
NAME          STATUS   ROLES    AGE   VERSION        INTERNAL-IP      
noldork3sm    Ready    master   5m   v1.18.3+k3s1   192.168.1.245
noldork3sm2   Ready    master   5m   v1.18.3+k3s1   192.168.1.246

Workers Nodes

La instalación de los Workers Nodes es igual en ambos entornos, y consta de los siguientes pasos:

Establecer las variables de entorno

$ export K3S_KUBECONFIG_MODE="644"
$ export K3S_URL="https://ip_master_node:6443"
$ export K3s_TOKEN=<token_master_node>

Recordar el token del Master Node que obtuvimos anteriormente. Si por lo que sea lo hemos perdido, podemos recuperarlo entrando por ssh en cualquiera de los Master Nodes ejecutando el siguiente comando:

$ sudo cat /var/lib/rancher/k3s/server/node-token

Ejecutar el instalador

Como veréis es igual que con los Master Nodes:

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

[INFO]  Finding latest release
[INFO]  Using v1.18.3+k3s as release
[INFO]  Downloading hash https://github.com/rancher/k3s/releases/download/v1.18.3+k3s/sha256sum-arm.txt
[INFO]  Downloading binary https://github.com/rancher/k3s/releases/download/1.18.3+k3s/k3s-armhf
[INFO]  Verifying binary download
[INFO]  Installing k3s to /usr/local/bin/k3s
[INFO]  Creating /usr/local/bin/kubectl symlink to k3s
[INFO]  Creating /usr/local/bin/crictl symlink to k3s
[INFO]  Creating /usr/local/bin/ctr symlink to k3s
[INFO]  Creating killall script /usr/local/bin/k3s-killall.sh
[INFO]  Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO]  env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO]  systemd: Creating service file /etc/systemd/system/k3s.service
[INFO]  systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO]  systemd: Starting k3s

Una vez hecho en todos nuestros workers, podemos comprobar el estado de nuestro cluster:

pi@noldork3sM:~ $ kubectl get nodes -o wide
NAME          STATUS   ROLES    AGE     VERSION        
noldork3sn1   Ready    <none>   3d21h   v1.18.2+k3s1   
noldork3sm2   Ready    master   3d21h   v1.18.2+k3s1   
noldork3sm    Ready    master   3d22h   v1.18.2+k3s1   
noldork3sn3   Ready    <none>   3d21h   v1.18.2+k3s1  

Como podeis observar tenemos nuestro cluster activo, con dos Master Nodes y dos Worker Nodes. Veréis que éstos últimos no tienen un rol asignado, no es preocupéis, es normal.

Accediendo al cluster de manera remota.

Para acceder a nuestro cluster, o gestionarlo, no es necesario acceder a cualquiera de los nodos, podemos hacerlo desde cualquier sistema Linux, OSx o Windows. Para ello solamente tenemos que instalar la herramienta kubectl, que ya viene instalada en nuestro cluster. Después solo tendremos que copiar el fichero de configuración de nuestro cluster a la maquina.

  • Instalar kubectl en nuestra máquina

Solamente tenéis que leer y seguir los pasos descritos en documentación oficial para instalarla en cualquier entorno.

  • Copiar el fichero de configuración de nuestro nodo master a nuestra máquina

Mediante el comando scp podemos copiar información desde una maquina a otra por ssh. De ésta manera, podremos descargar el fichero /etc/rancher/k3s/k3s.yaml de nuestro nodo master a nuestra máquina local, en el path ~/.kube/config.

scp i5js@nanoserver:/etc/rancher/k3s/k3s.yaml ~/.kube/config

Ahora solo tenemos que editarlo y cambiar la dirección ip que es 127.0.0.1 por la ip de nuestro nodo master, en mi caso 192.168.1.240. Podemos hacerlo mediante el editor que mas cómodo os resulte o bien, mediante el comando sed:

sed -i '' 's/127\.0\.0\.1/192\.168\.1\.240/g' ~/.kube/config
  • Probar kubectl desde nuestra máquina local
i5js@nanoserver:~ $ kubectl get nodes -o wide
NAME          STATUS   ROLES    AGE     VERSION        
noldork3sn1   Ready    <none>   3d21h   v1.18.2+k3s1   
noldork3sm2   Ready    master   3d21h   v1.18.2+k3s1   
noldork3sm    Ready    master   3d22h   v1.18.2+k3s1   
noldork3sn3   Ready    <none>   3d21h   v1.18.2+k3s1  

Leave a Reply

Your email address will not be published. Required fields are marked *