Usando Kubernetes en local - Minikube - Instalación en Windows


Introducción

En nuestro post anterior Hola Kubernetes: Definiciones vimos una introducción a los conceptos que rodean a Kubernetes. En este post nos centraremos en poder trabajar en Windows en local utilizando minikube.


Kubernetes permite la gestión de cargas de trabajo con contenedores, en un clúster. Para refrescar nuestra memoria, un clúster es una agrupación lógica de máquinas (virtuales y/o físicas). Existen distintas maneras de definir este clúster, en nuestra máquina local, mediante máquinas virtuales, con proveedores públicos de Cloud, como AWS, Azure o Google entre otros. Pero de ahí a poder empezar a correr Kubernetes todavía nos quedaría trabajo por hacer.


Para ponernos en situación, con un clúster provisto por nosotros, ya sea mediante máquinas físicas o virtuales deberíamos hacer la instalación de todos los componentes de Kubernetes, es lo que se conoce como instalación en Bear Metal, evidentemente esto no es algo directo de hacer. Con respecto a los proveedores de cloud, el camino, puede ser más o menos directo, evidentemente tiene su curva de aprendizaje, pero sobre todo, vamos a tener que gastar dinero en los recursos que consumamos, a menos que disfrutemos de cuentas gratuitas, como AWS, que ofrece alguno de sus servicios de manera gratuita el primer año.


¿Significa esto que no podemos tener un clúster, de manera sencilla y gratuita, para poder jugar con esta maravillosa herramienta? Si podemos :). Existen a día de hoy una gran variedad de herramientas, que permiten correr Kubernetes de manera local. En este artículo nos centraremos en la instalación de Minikube.
Usar Minikube, nos da como ventaja, que goza de un sistema de plugins, los cuales nos permitirán encender/apagar características de Kubernetes en nuestro clúster local. Esto es ideal en fases de experimentación y aprendizaje, cómo contrapartida sólo podremos ejecutar un clúster de un solo nodo.

A tener en cuenta antes de arrancar

Para poder emular un clúster (aunque sea de un solo nodo), minikube va a levantar una máquina virtual en la máquina donde se encuentre instalado. Esto significa que para poder correr minikube, la máquina debe soportar tecnologías de virtualización. A día de hoy la mayoría de máquinas soportan virtualización, eso sí dependiendo de nuestra máquina puede que tengamos que activar características desde la BIOS y otros por menores.


En este post, intentaremos trazar el camino más directo y con mayores garantías garantías para obtener un funcionamiento robusto, instalando minikube en Windows.

Windows y los contenedores

La forma más sencilla de poder ejecutar contenedores en Windows es a través de Docker Desktop for Windows.


El problema que nos encontrábamos en Windows, es que Docker utilizaba `Hyper-V` como tecnología de virtualización y si teníamos instalado en nuestros equipos Virtualbox, VM-Ware u otro proveedor de máquinas virtuales, éstas entraban en conflicto.


Esto a la hora de ejecutar minikube junto con Docker Desktop, era un gran problema ya que el driver esencial para que minikube pueda correr, no funcionaba.
Afortunadamente los tiempos han cambiado y la forma recomendada de correr Docker Desktop en Windows es a través de [WSL2 - Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). Esta es la opción que nosotros seguiremos para tener una buena experiencia en Windows.

Windows - Prerrequisitos

  • Sistema operativo: Windows 10, Pro o Home versión >= 2004, Build >= 19041

  • WSL2 (Windows Subsystem Linux): En esta guía te explican como instalar WSL

  • Para poder instalar distribuciones en WSL2 por defecto, una vez que hayas completado la instalación de WSL2, ejecuta el comando wsl.exe --set-default-version 2 en Powershell.

  • WSL2 distro (la distribución de _linux_ con la que queremos trabajar), la podemos instalar de la Windows Store - la distribución que vamos a usar es **Ubuntu-18.04**, el enlace para la descarga de Ubuntu-18.04

  • Docker Desktop for Windows

WSL2

Una vez que hemos satisfecho los prerrequisitos de instalación, podemos lanzar el terminal de WSL2 desde el menú Windows tecleando Ubuntu.

Buscando Ubuntu menú Windows

Buscando Ubuntu menú Windows

Una vez que tengamos el terminal de Ubuntu abierto vamos a actualizar nuestro sistema:

# Actualiza los repositorios y las listas de paquetes disponibles
sudo apt update
# Actualiza el sistema en función de los paquetes instalados, la "-y" aprueba los cambios de forma automática
sudo apt upgrade -y

NOTA sobre sudo: En Ubuntu Linux, la cuenta root no viene configurada por defecto. Si el usuario necesita hacer modificaciones en la máquina para instalar nuevo software o realizar ciertas operaciones> especiales, debe proveer una cuenta root con password. Eso es lo que va a hacer sudo por nosotros, nos permite registrarnos por defecto como usuario root. Usar sudo es una medida de protección contra software malicioso que se pudiera instalar y quisiera utilizar la máquina.

Desde el terminal ejecutaremos los siguientes comandos:

# Devuelve la versión y build que hemos instalado de Docker
docker version
# Devuelve la versión y build que hemos instalado de Kubectl
kubectl version
Docker version & kubectl version failed

Docker version & kubectl version failed

Para esta prueba, el resultado esperado es que estos comandos den una fallo al ejecutar, en que de que no te de ese mensaje de error, si ese no es tu caso, lo que está pasando es que ya tienes una distribución de linux ya habilitada en Docker Desktopy que Kubernetes está habilitado también. Para que la instalación de minikube tenga éxito, debemos deshabilitar Kubernetes en Docker Desktop. Esto lo hacemos abriendo el panel de control de Docker Desktop y desmarcando el check box Enabled Kubernetes.

kubernetes-off-docker-dektop.png

Para habilitar la distribución de Ubuntu, debemos seleccionar settings y seleccionar Use the WSL 2 based engine. Una vez seleccionado presionamos Apply & Restart.

Ahora debemos seleccionar la distribución de Ubuntu que instalamos para ello, seleccionamos Resources, seleccionamos WSL Integration y activamos Ubuntu-20.04. Una vez seleccionado presionamos Apply & Restart.

Enable Ubuntu 18.0.4

Enable Ubuntu 18.0.4

NOTA: En algunos casos para que los cambios surtan efecto puede que necesitemos reiniciar el sistema.

Ahora si volvemos a ejecutar:

# Devuelve la versión y build que hemos instalado de Docker
docker version
# Devuelve la versión y build que hemos instalado de kubectl
kubectl version

Nuestra salida será algo como esto:

Docker version & kubectl version success

Docker version & kubectl version success

Mejorando nuestro entorno de trabajo

Un tema que nos puede impactar en nuestra productividad es que en el terminal por defecto que se levanta al arrancar Ubuntu 18.04, no vamos a poder pegar desde el portapapeles. Para solucionar esto podemos abrir Microsoft Terminal si lo hemos instalado, o utilizar la extensión Remote - WSL de Visual Studio Code. En esto post vamos a usar Remote - WSL. Este es el identificador de la extensión en VSCode es ms-vscode-remote.remote-wsl, para instalarlo seleccionamos Extensions:

Open vs code extensions

Open vs code extensions

Y pegamos ms-vscode-remote.remote-wsl en el buscador para encontrar el plugin deseado:

Remote containers extension

Remote containers extension

Una vez tenemos instalada esta extensión, podemos utilizarla para abrir un terminal remoto, con la distribución de Ubuntu 18.04 que instalamos previamente. Para abrir un nuevo terminal remoto, en VS Code, presionamos sobre Open remote Window:

Open remote window

Open remote window

Seleccionamos New WSL Window using Distro...

New WSL window

New WSL window

Y seleccionamos la distribución de Linux que hemos instalado anteriormente Ubuntu 18.04

VS Code Ubuntu Window

VS Code Ubuntu Window

Ahora en la nueva instancia que se ha levantado, si abrimos un terminal embebido estaremos en Ubuntu 18.04 y podremos pegar desde el portapapeles.

Terminal Ubuntu desde VS Code

Terminal Ubuntu desde VS Code

Instalando Minikube

Ahora mismo tenemos instalado e integrado Docker en la distribución de Ubuntu, pero si ejecutamos kubectl version, nos daremos cuenta de que no ha sido capaz de encontrar ningún clúster. Recordad hemos dejado deshabilitado Kubernetes en Docker Desktop. Para instalar minikube, seguiremos los pasos de la guía oficial para Linux.

# Descargamos la  última versión de Minikube
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
# Hacemos el binario ejecutable
chmod +x ./minikube
# Movemos el binario a la ruta ejecutable de nuestro usuario
sudo mv ./minikube /usr/local/bin/

Para poder utilizarlo con Docker, debemos usar --driver=docker, si ejecutamos:

# Create a minikube one node cluster
minikube start --driver=docker

Obtenemos múltiples errores, entre los errores que hemos tenido, por ejemplo aparecen errores de certificados, el más importante es el relacionado con systemd. ¿Qué es systemd? Básicamente son un conjunto de paquetes de Linux para la inicialización y gestión de servicios. Debido a las características con las que corre minikube con Docker como driver, nuestro sistema debe soportarlo. En la documentación oficial de Docker existe una entrada de cómo manejar el servicio con systemd.

Systemd error docker driver

Systemd error docker driver

Para habilitar SystemD en WSL2 usaremos los scripts de Daniel Llewellyn

Estos son los comandos:

# Instalamos los paquetes necesarios para usar systemd
sudo apt install -yqq daemonize dbus-user-session fontconfig
installing systemd 1

installing systemd 1

A continuación creamos el script start-systemd-namespace:

# Crear start-systemd-namespace script
sudo nano /usr/sbin/start-systemd-namespace
#!/bin/bash

SYSTEMD_PID=$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')
if [ -z "$SYSTEMD_PID" ] || [ "$SYSTEMD_PID" != "1" ]; then
    export PRE_NAMESPACE_PATH="$PATH"
    (set -o posix; set) | \
        grep -v "^BASH" | \
        grep -v "^DIRSTACK=" | \
        grep -v "^EUID=" | \
        grep -v "^GROUPS=" | \
        grep -v "^HOME=" | \
        grep -v "^HOSTNAME=" | \
        grep -v "^HOSTTYPE=" | \
        grep -v "^IFS='.*"$'\n'"'" | \
        grep -v "^LANG=" | \
        grep -v "^LOGNAME=" | \
        grep -v "^MACHTYPE=" | \
        grep -v "^NAME=" | \
        grep -v "^OPTERR=" | \
        grep -v "^OPTIND=" | \
        grep -v "^OSTYPE=" | \
        grep -v "^PIPESTATUS=" | \
        grep -v "^POSIXLY_CORRECT=" | \
        grep -v "^PPID=" | \
        grep -v "^PS1=" | \
        grep -v "^PS4=" | \
        grep -v "^SHELL=" | \
        grep -v "^SHELLOPTS=" | \
        grep -v "^SHLVL=" | \
        grep -v "^SYSTEMD_PID=" | \
        grep -v "^UID=" | \
        grep -v "^USER=" | \
        grep -v "^_=" | \
        cat - > "$HOME/.systemd-env"
    echo "PATH='$PATH'" >> "$HOME/.systemd-env"
    exec sudo /usr/sbin/enter-systemd-namespace "$BASH_EXECUTION_STRING"
fi
if [ -n "$PRE_NAMESPACE_PATH" ]; then
    export PATH="$PRE_NAMESPACE_PATH"
fi

NOTA: Una vez que nuestro fichero quede editado como nosotros queremos, para guardarlo desde la terminal de nano, pulsamos la combinacion de teclas `CTRL + X`, `Y`, y por útimo `tecla enter`.

Podemos comprobar su contenido ejecutando:

cat /usr/sbin/start-systemd-namespace

A continuación creamos el script enter-systemd-namespace:

# Crear enter-systemd-namespace
sudo nano /usr/sbin/enter-systemd-namespace
#!/bin/bash

if [ "$UID" != 0 ]; then
    echo "You need to run $0 through sudo"
    exit 1
fi

SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
if [ -z "$SYSTEMD_PID" ]; then
    /usr/sbin/daemonize /usr/bin/unshare --fork --pid --mount-proc /lib/systemd/systemd --system-unit=basic.target
    while [ -z "$SYSTEMD_PID" ]; do
        SYSTEMD_PID="$(ps -ef | grep '/lib/systemd/systemd --system-unit=basic.target$' | grep -v unshare | awk '{print $2}')"
    done
fi

if [ -n "$SYSTEMD_PID" ] && [ "$SYSTEMD_PID" != "1" ]; then
    if [ -n "$1" ] && [ "$1" != "bash --login" ] && [ "$1" != "/bin/bash --login" ]; then
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /usr/bin/sudo -H -u "$SUDO_USER" \
            /bin/bash -c 'set -a; source "$HOME/.systemd-env"; set +a; exec bash -c '"$(printf "%q" "$@")"
    else
        exec /usr/bin/nsenter -t "$SYSTEMD_PID" -a \
            /bin/login -p -f "$SUDO_USER" \
            $(/bin/cat "$HOME/.systemd-env" | grep -v "^PATH=")
    fi
    echo "Existential crisis"
fi

NOTA: Una vez que nuestro fichero quede editado como nosotros queremos, para guardarlo desde la terminal de nano, pulsamos CTRL + X, Y, y por último `tecla enter`.

Podemos comprobar su contenido ejecutando:

cat /usr/sbin/enter-systemd-namespace

Para que nuestro sistema arranque con systemd, debemos hacer las siguientes modificaciones:

# Editar los permisos de enter-systemd-namespace script
sudo chmod +x /usr/sbin/enter-systemd-namespace
# Editar el fichero bash.bashrc
sudo sed -i 2a"# Start or enter a PID namespace in WSL2\nsource /usr/sbin/start-systemd-namespace\n" /etc/bash.bashrc

Salimos e iniciamos una nueva sesión. Para ello basta con ejecutar:

exit

Abrimos una nueva terminal embebida, y comprobamos que se está usando systemd:

ps -ef
Systemd installed

Systemd installed

Minikube - Listos para el clúster

Ya casi estamos listos para levantar nuestro primer clúster con minikube, si lanzamos ahora

# Arrancamos minikube con el driver Docker
minikube start --driver=docker

Volvemos a tener un error, esta vez, relacionado con los certificados.

Minikube start error

Minikube start error

Para solucionarlo ejecutamos la acción recomendada

# Eliminamos toda la configuración generada
minikube delete
Minikube delete

Minikube delete

Si levantamos de nuevo el clúster

# Arrancamos minikube con el driver Docker
minikube start --driver=docker

Ahora obtenemos el siguiente mensaje:

minikube start success

minikube start success

Podemos comprobar el clúster creado y sus objetos:

# Los nodos creados
kubectl get nodes
# Todos los servicios disponibles en todo el clúster
kubectl get all --all-namespaces
Kubernetes Cluster

Kubernetes Cluster

¿Te gusta el mundo Devops?

En Lemoncode impartimos un Bootcamp Devops Online, en el encontrarás todos los recursos necesarios: clases de los mejores profesionales del sector, tutorías en cuanto las necesites y ejercicios para desarrollar lo aprendido en los distintos módulos. Si quieres saber más puedes pinchar aquí para más información sobre este Bootcamp Devops.