Resumen del proyecto

Este post recoge el proceso de creación y configuración de Bárbara y constituye un resumen del proyecto. Puede descargarse en formato PDF 

Resumen 

El proyecto consiste en crear un clúster con Raspberries Pi, este clúster ejecuta aplicaciones distribuidas usando contenedores Docker y kubernetes.

En el proyecto se han puesto en práctica muchos de los conocimientos adquiridos en el módulo Implantación de Sistemas Operativos, entre ellos: 

  • Instalación de Sistemas Operativos (dispositivos, particionado..) 
  • Configuración inicial de un SO (idioma, teclado, zona horaria...) 
  • Configuración de redes 
  • Conexión remota (ssh) 
  • Instalación de aplicaciones 
  • Servicios 
  • Docker 
  • Kubernetes 
  • Samba 

Hardware necesario 

El material que hemos utilizado para construir Barbara ha consistido en: 

  • 9 Raspberry Pi 4 de 4GB cada una. (El trabajo lo realizamos con 10 Raspberry, pero una de ellas la regalamos como premio en un concurso de logotipos que hicimos para dar a conocer el proyecto en el instituto).
    • Cables de alimentación para cada Raspberry 
    • Tarjeta microSD de 32 bits para cada Raspberry
  • 1 Adaptador de USB a RJ45. Para que el máster tenga doble conexión de red 
  • 1 switch. El más sencillo que encontramos con los puertos suficientes. 
  • 10 Cables de red ethernet. 
  • 1 torre con ventilación para alojar las Raspberries. Este componente es opcional. 
  • Adaptadores con enchufes suficientes, necesarios para alimentar todas las Raspberries y el switch
  • Adaptador de microSD a USB para cargar el SO en las tarjetas. 

  • Ubuntu server de 32 bits para ARM. versión 20.04 LTS 
  • Contenedores Docker 
  • K3s Es una implementación ligera de kubernetes optimizada para dispositivos ARM 
  • Lens - The Kubernetes IDE, permite administrar de forma gráfica el cluster
  • Balena Etcher. Para grabar las imágenes en las tarjetas microSD 
  • Putty o Bitvise. Para administración remota con ssh

Mapa de red

El diseño de la red de nuestro proyecto es el siguiente: 

Nuestras Raspberries están una red local independiente creada con un switch y la Raspberry master tiene una segunda conexión de red que la conecta a la red de clase. De esta forma nosotros solo podemos acceder directamente al master y desde este a los nodos. 

Configuración inicial de cada Raspberry

Instalación del SO

Durante las pruebas realizadas hemos probado diferentes sistemas operativos en Raspberry y finalmente nos decantamos por una versión sin interfaz gráfica por ser más ligera. Elegimos Ubuntu server pues es el SO con el que hemos trabajado en clase. 

Hemos instalado un SO de tipo ARM, hemos elegido Ubuntu server de 32 bits versión LTS 20.04. para ARM. 

 Los pasos para instalar el SO en la tarjeta microSD con Balena Etcher son: 

  1. Instalar Balena Etcher en un equipo (Es multiplataforma así que puede usarse tanto en Windows, Linux como en MacOS) 
  2. Descargar la imagen del SO a instalar, en nuestro caso desde la página de Ubuntu 
  3. Flashear la tarjeta SD con la imagen descargada usando Balena Etcher. 

El proceso es muy simple, como se puede ver en la siguiente imagen;

Hemos probado a grabar los SO con Raspberry Pi Imager y el proceso es igual de sencillo. 

Deshabilitar cloud-init

En Ubuntu server está habilitado por defecto el servicio cloud-init, como no lo vamos a utilizar lo desinstalamos 

apt purge cloud-init 

Y borramos toda la información que configuración pueda existir ya que no la necesitamos 

rm -rf /etc/cloud/ &&  rm -rf /var/lib/cloud/

Teclado, idioma y zona horaria 

Configuramos los datos de localidad para tener el idioma del sistema y el teclado en español, además fijaremos la zona horaria apropiada. 

dpkg-reconfigure locales 

dpkg-reconfigure keyboard-configuration 

timedatectl set-timezone europe/Madrid 

Una Raspberry no tiene un reloj interno que mantenga la hora cuando es desconectada. Por lo tanto, es imprescindible tener correctamente configurado el acceso a un servidor NTP para poder sincronizar la hora. En el caso de Ubuntu esta sincronización se realiza por el servicio systemd-timesyncd.service que ya está configurado y activado por defecto.

Nombre del equipo 

Configuramos el nombre de cada Raspberry 

  • Para los nodos “nodo1”, “nodo2”... 
  • Para la Raspberry master “master” 

systemctl set-hostname nodo1 

Cambiamos además el fichero /etc/hosts de las Raspberries para que hagan referencia al nuevo nombre

Usuarios

Creamos un usuario llamado ae (Aula empresa) en todas las máquinas con la misma contraseña y le damos permisos de administrador 

adduser ae adduser ae 

passwd ae ******* 

Para facilitar las labores de administración habilitamos el usuario root asignándole una contraseña

passwd root 

Habilitar ssh

Nos aseguramos de que el servicio ssh está activo desde el arranque pues accederemos remotamente a las Raspberries desde nuestros PCs de clase

sudo apt install openssh-server

systemctl enable ssh.server

Para acceder a las Raspberries desde nuestros PCs de clase hemos usado tanto Putty o Bitvise.

Como la red de Raspberries es inaccesible desde clase para acceder a los nodos accedemos a la master y desde ella a los nodos.

Configuración de red

Usamos netplan pues es el tipo de configuración de red que usa Ubuntu por defecto. Ubuntu Server viene configurado para trabajar con networkd, por lo que solo solo hay que configurar los ficheros de netplan que se almacenan en /etc/netplan/ con la extensión .yaml y borrar los antiguos

rm /etc/netplan/*.yaml

Fichero de configuración de red para el master

EL MASTER La Raspberry master tiene dos interfaces de red y conectará la red interna del clúster con la red de clase, actuando como NAT. La configuración de sus dos interfaces es la siguiente:

  • eth0 Red de clase: Configuración dinámica por DHCP4. No podemos usar IP fija pues no tenemos acceso para administrar el servidor DHCP de clase y podrían producirse inconsistencias
  • eth1 Red interna de nuestro clúster. Usamos IP fija, hemos seleccionado la última del rango 192.168.10.254

Crearemos un fichero llamado /etc/netplan/00-Servidor.yaml con el siguiente contenido

            
network: 
  version: 2 
  renderer: networkd 
  ethernets: 
    eth0: 
      dhcp4: yes 
      optional: true 
    eth1: 
      optional: true 
      addresses: [192.168.10.254/24]
      routes: 
          - to: default 
            via: 192.168.10.254 
          nameservers: 
              addresses: [8.8.8.8,1.1.1.1]
        

Fichero de configuración de red para los nodos

Los nodos tienen IP fija del rango 192.168.10.0/24, de tal forma que hemos hecho coincidir el último byte con el número de nodo.

La puerta de enlace es la Raspberry master con la IP 192.168.10.254 y como servidores DNS usamos los conocidos: 8.8.8.8 y 1.1.1.1

Crearemos el fichero /etc/netplan/00-Cliente.yaml con el siguiente contenido

            
network: 
  version: 2 
  renderer: networkd
  ethernets: 
    eth0: 
      addresses: - 192.168.10.X/24 
      nameservers: 
        addresses: [8.8.8.8, 1.1.1.1] 
      routes: 
        - to: default 
          via: 192.168.10.254 
          

En cada uno de los nodos la X es sustituida por su número de nodo

Aplicación de la configuración de red

Tanto en el master como en los nodos comprobaremos que la configuración es correcta y la aplicaremos

netplan generate

netplan apply

Utilizar el master como elemento de conexión entre las dos redes

Necesitamos poder acceder a internet desde todas las Raspberries del clúster para configurarlas y actualizarlas.

Para permitir esta comunicación vamos a habilitar NAT en el master mediante iptables.

Debemos Habilitar el reenvío en ipv4

echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf

Como las iptables se borran en cada reinicio pondremos las reglas en un script y creamos un servicio para que se ejecute en el arranque

Creamos el script iptables.sh

    #!/bin/bash 
 iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE 
 iptables -A INPUT -s  192.168.10.0/24 -i eth1 -j ACCEPT 
        

NOTA: No se han tenido en cuenta cuestiones de seguridad, pues no era el objetivo de este proyecto. Si quisiéramos ser más restrictivos con las conexiones podríamos crear reglas que convirtieran a nuestro master en un cortafuegos perimetral filtrando los paquetes por origen, destino, protocolo, estado, número de conexiones...

Creamos el fichero que define el servicio iptables.service

    [Unit] 
    Description=Reglas de iptables 
    After=systemd-networkd.service
    
    [Service] 
    Type=oneshot 
    ExecStart=/usr/local/bin/iptables.sh 
    [Install]
    WantedBy=multi-user.target 

Para dejar instalado el servicio movemos el fichero iptables.sh y el fichero del servicio iptables.service a las carpetas apropiadas. Damos permiso de ejecución al script, habilitamos el servicio al inicio y lo arrancamos

cp ./iptables.sh /usr/local/bin/iptables.sh

chmod +x /usr/local/bin/iptables.sh

cp ./iptables.service /etc/systemd/system/

systemctl enable iptables.service

systemctl start iptables.service

CGROUPS

Para que funcione k3s necesitamos habilitar los grupos de control (cgroups) de este modo el kernel podra gestionar la asignación de recursos a los procesos.

En raspberry con Ubuntu Server hay que añadir al fichero /boot/firmware/cmdline.txt estos parámetros:

cgroup_memory=1 cgroup_enable=memory

Instalar Docker

Para instalar Docker en todos los nodos y en el master nos descargaremos un script de instalación que además de instalar Docker añade la web de Docker a los repositorios lo que facilitará su actualización

curl -sSL https://get.docker.com | sh

Instalar K3S

Usaremos un script que descarga e instala k3s.

En el master

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

En los nodos

Dejaremos los nodos asociados al master durante la instalación usando el mismo script que en el master, pero con parámetros que identifiquen al master su IP (En nuestro caso es fija) y un token que permite el acceso. Necesitamos saber el token para asociar a los nodos al master y está almacenado en /var/lib/rancher/k3s/server/node-token

curl -sSL https://get.k3s.io | K3S_URL=https://192.168.10.254:6443 K3S_TOKEN=token sh –s - --docker

Desplegar el cluster

>Una vez instalado el sistema desde el master podemos administrar kubernetes usando el comando kubectl que nos proporciona K3s.

Algunos de los comandos que hemos usado en el master para crear el cluster y ver su funcionamiento:

Ver los nodos que están asociados a nuestro master

kubectl get nodes -o wide

Crear un despliegue con una imagen que hemos creado previamente con Docker y que tenemos almacenada en dockerhub. Se trata de una imagen que parte de nginx y añade una página de pruebas muy simple.

kubectl create deploy asir --image=msolds/asir

Ver los pods. Al crear el deploy vemos cómo se ha creado un pod automáticamente k3s

kubectl get pods -o wide

Crear un servicio exponiendo el puerto 80 del master para poder ver nuestra web

kubectl expose deploy asir --port=80 --type=NodePort

Comprobar el servicio para ver que puerto es el que está asociando al puerto 80 y poder acceder a la web desde un navegador.

kubectl get services -o wide

A partir de este momento podemos ver que la página está accesible. Desde cualquier navegador de la red de clase accediendo a la IP que tiene el master en la red de clase y usando el puerto correspondiente

Podemos escalar el servicio para pedir más instancias y comprobaremos como se reparten automáticamente entre los nodos

kubectl scale --replicas=11 deploy/asir

Dentro de las pruebas realizadas hemos apagado algunas de las Raspberries para ver como el master lo detecta automáticamente y se crean nuevos pod en los nodos disponibles para tener siempre las instancias solicitadas.

También hemos comprobado como al reiniciar alguno de los nodos automáticamente se conecta de nuevo al master y este detecta que es un nodo operativo y comienza e asignarle pods

Hemos desplegado un segundo servicio en este caso la imagen caddy sin modificaciones. Podemos tener tantas instancias como queramos de cada una de las aplicaciones. Y vemos como están accesibles en diferentes puertos.

kubectl create deploy caddy--image=Caddy

Estas son algunas de las capturas de las prácticas realizadas:






Administrar el cluster de forma gráfica

Además de kubectl existen múltiples herramientas para administrar un cluster con Kubernetes, muchas de ellas con interfaz gráfica. Nosotros vamos a usar Lens Desktop pues es gratuita y multiplataforma.

Para poder acceder al cluster necesitamos el fichero de configuración en nuestro caso se encuentra en el máster en el fichero /etc/rancher/k3s/k3s.yaml. ·n el fichero cambiaremos la IP de bucle local que aparece en el master por la IP que tiene nuestro master en la red de clase. Accedemos al fichero a través de una carpeta compartida con samba.

La aplicación es muy visual y permite ver cómo se va desplegando la imagen en los nodos cuando cambiamos el número de réplicas y como detecta si alguno de los nodos ha dejado de funcionar (lo desenchufamos)

Comentarios