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
WSL2
Una vez que hemos satisfecho los prerrequisitos de instalación, podemos lanzar el terminal de WSL2 desde el menú Windows tecleando Ubuntu.
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
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.
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.
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:
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:
Y pegamos ms-vscode-remote.remote-wsl en el buscador para encontrar el plugin deseado:
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:
Seleccionamos New WSL Window using Distro...
Y seleccionamos la distribución de Linux que hemos instalado anteriormente Ubuntu 18.04
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.
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.
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
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
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.
Para solucionarlo ejecutamos la acción recomendada
# Eliminamos toda la configuración generada
minikube delete
Si levantamos de nuevo el clúster
# Arrancamos minikube con el driver Docker
minikube start --driver=docker
Ahora obtenemos el siguiente mensaje:
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
Referencias
Como punto de partida hemos tomado este excelente artículo.
Otros enlaces de interés relacionados:
¿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.