DEV Community

Raül Martínez i Peris
Raül Martínez i Peris

Posted on

Windows: container Windows + container Linux (IV)

Índice

  • Sección primera (básico):
    • Docker en Windows. Apartado I: Instalar WSL2 (y Docker).
    • Docker en Windows. Apartado II: Instalar Docker en Windows 11.
  • Sección segunda (avanzado):
    • Docker en Windows. Apartado III: Confianza entre entornos.
    • Docker en Windows. Apartado IV: Configurar conexión entre Docker Windows y Docker WSL.
    • Docker en Windows. Apartado V: Instalar Portainer en el entorno WSL.
    • Docker en Windows. Apartado VI: Apuntes.

Apartado IV. Configurar conexión entre Docker Windows y Docker WSL

Para empezar, abre una consola Powershell.

Crear reglas para el Firewall

Como sabes, los servicios en contenedores necesitan salir por un puerto para conversar con otros servicios o aplicaciones. Por ello, es necesario que pongas una regla en el cortafuegos para permitirlo.

Vamos a crear una regla de ejemplo para permitir el acceso al puerto 8080:

New-NetFirewallRule -DisplayName "Web TCP 8080" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
Enter fullscreen mode Exit fullscreen mode

Adicionalmente, revisa el puerto 443 (aunque suele estar abierto) y ábrelo si es necesario:

New-NetFirewallRule -DisplayName "HTTPS" -Direction Inbound -Protocol TCP -LocalPort 443 -Action Allow
Enter fullscreen mode Exit fullscreen mode

Cada vez que crees un contenedor deberás verificar que el puerto esté abierto.

Crear reglas en el Firewall para Docker

Vamos a crear las reglas necesarias para la escucha entre los Docker de ambos entornos, para ello abriremos el puerto 2375.

Para permitir el acceso al puerto 2375, crea la regla:

New-NetFirewallRule -DisplayName "Docker TCP 2375" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 2375
Enter fullscreen mode Exit fullscreen mode

Reiniciar el servicio Docker

Para que los cambios surtan efecto deberemos reiniciar el servicio de Docker:

net stop Docker
net start Docker
Enter fullscreen mode Exit fullscreen mode

Comprueba que el servicio Docker está funcionando:

Get-Service docker
Enter fullscreen mode Exit fullscreen mode

Configurar el demonio de Docker WSL

Entra en el entorno de Ubuntu:

wsl -d ubuntu
Enter fullscreen mode Exit fullscreen mode

Comprueba que tienes los archivos wsl-server-cert.pem, wsl-server-key.pem y ca.pem:

ls /mnt/c/ProgramData/docker/certs/
Enter fullscreen mode Exit fullscreen mode

Creamos el directorio para Docker (si no lo estuviera) y creamos el archivo daemon.json:

sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json
Enter fullscreen mode Exit fullscreen mode

con el contenido:

{
"hosts": [
  "unix:///var/run/docker.sock",
  "tcp://0.0.0.0:2376"
],
"tlsverify": true,
"tlscacert": "/mnt/c/ProgramData/certs/ca.pem",
"tlscert": "/mnt/c/ProgramData/docker/certs/wsl-server-cert.pem",
"tlskey": "/mnt/c/ProgramData/docker/certs/wsl-server-key.pem"
}
Enter fullscreen mode Exit fullscreen mode

Ahora vamos a crear el archivo override de la configuración:

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/override.conf
Enter fullscreen mode Exit fullscreen mode

con el contenido:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
Enter fullscreen mode Exit fullscreen mode

Y reiniciamos el servicio:

sudo systemctl daemon-reload
sudo service docker restart
Enter fullscreen mode Exit fullscreen mode

El siguiente paso es con Powershell, por lo que debemos salir de Ubuntu:

exit
Enter fullscreen mode Exit fullscreen mode

Y hacerle un shutdown:

wsl --shutdown
Enter fullscreen mode Exit fullscreen mode

Configurar en Windows la conexión al host de Linux

En la consola de Powershell, crea el nuevo contexto para WSL:

$userProfile = $env:USERPROFILE
$dockerDir = Join-Path $userProfile ".docker"
docker context create wsl --docker "host=tcp://localhost:2376,ca=$userProfile\.docker\ca.pem,cert=$userProfile\.docker\cert.pem,key=$userProfile\.docker\key.pem"
Enter fullscreen mode Exit fullscreen mode

Aunque es el contexto de WSL, lo estamos configurando en Windows por lo que las rutas para los certificados que utilizamos son los de Windows, no siendo necesario volver a copiarlos.

Añadir las reglas al Firewall

Para permitir el acceso al puerto 2376, crea la regla:

New-NetFirewallRule -DisplayName "Docker TCP 2376" -Direction Inbound -Protocol TCP -Action Allow -LocalPort 2376
Enter fullscreen mode Exit fullscreen mode

Configuración del Docker en WSL con TLS

Copiar las claves TLS a la carpeta de usuario

Ahora vamos a configurar en WSL la conexión al host docker de Windows.

Volvemos a la consola de WSL:

wsl -d ubuntu
Enter fullscreen mode Exit fullscreen mode

Primero copiamos los certificados a la carpeta docker del usuario:

cp /mnt/c/ProgramData/certs/ca.pem ~/.docker/ca.pem
cp /mnt/c/ProgramData/docker/certs/client-cert.pem ~/.docker/cert.pem
cp /mnt/c/ProgramData/docker/certs/client-key.pem ~/.docker/key.pem
Enter fullscreen mode Exit fullscreen mode

Y les ponemos los permisos adecuados:

cd ~/.docker/
chmod -v 0400 key.pem
chmod -v 0444 cert.pem ca.pem
Enter fullscreen mode Exit fullscreen mode

Crear contextos dentro del entorno WSL

Preparar el hostname de conexión

Lo primero es automatizar el nombre hostname en cada inicio de sesión. Para ello vamos a editar el archivo de inicio de sesión:

nano ~/.bashrc
Enter fullscreen mode Exit fullscreen mode

y le añadimos al final del todo el siguiente código:

WINDOWS_DOCKER_HOSTNAME="wsl2docker.local"
WINDOWS_HOST_IP=$(ip route show | grep -i default | awk '{ print $3 }')
sudo sed -i "/${WINDOWS_DOCKER_HOSTNAME}/d" /etc/hosts
echo "${WINDOWS_HOST_IP} ${WINDOWS_DOCKER_HOSTNAME}" | sudo tee -a /etc/hosts
sudo systemctl restart systemd-resolved
Enter fullscreen mode Exit fullscreen mode

En Windows deberíamos controlar que el archivo C:\Windows\System32\drivers\etc\hosts está correctamente configurado, sin embargo, crear un script Powershell que se lance automáticamente en el inicio de Windows para comprobar dicha línea “se sale” de las necesidades que tenemos.

Pero, sí que necesitamos saber si la IP nos ha cambiado, para ello, añadiremos al final del archivo, a continuación de donde acabas de pegar lo anterior, en el archivo ~/.bashrc, una pequeña comprobación:

WINDOWS_HOSTS_PATH="/mnt/c/Windows/System32/drivers/etc/hosts"
HOSTS_LINE=$(grep -i "$WINDOWS_DOCKER_HOSTNAME" "$WINDOWS_HOSTS_PATH" | grep -v "^#")
if [[ "$HOSTS_LINE" == *"$WINDOWS_HOST_IP"* ]]; then
  echo -e "\nLa IP y el Hostname para la conexión entre WSL y Windows están correctamente configuradas en ambos entornos.\n”
else
  echo -e "\nEl archivo de configuración de Windows no está correctamente configurado,"
  echo -e "por favor, abre el archivo '$WINDOWS_HOSTS_PATH' y revisa la siguiente línea:"
  echo -e "$WINDOWS_HOST_IP  $WINDOWS_DOCKER_HOSTNAME"
fi
Enter fullscreen mode Exit fullscreen mode

Esta comprobación nos avisará cuando levantemos WSL2 si coinciden las configuraciones de Windows y WSL2. Si no coinciden nos dirá la ruta del archivo y el contenido que debemos poner.

Crear el contexto de conexión a Windows

Ahora creamos el contexto para ver el Docker de Windows desde WSL:

WINDOWS_DOCKER_HOSTNAME="wsl2docker.local"
docker context create windows-from-wsl --docker "host=tcp://${WINDOWS_DOCKER_HOSTNAME}:2375,ca=${HOME}/.docker/ca.pem,cert=${HOME}/.docker/cert.pem,key=${HOME}/.docker/key.pem"
Enter fullscreen mode Exit fullscreen mode

Para simplificar la comprensión de esta creación de contexto hemos creado una variable llamada hostname para que quede más claro... evidentemente esto no es necesario, puedes escribirlo directamente.

Con este contexto creado, vamos a comprobarlo:

docker context use windows-from-wsl
docker ps
Enter fullscreen mode Exit fullscreen mode

Deberías de haber obtenido como resultado el listado del docker de Windows.

Una vez comprobado el Docker de Windows, puedes volver al contexto predeterminado de WSL (que generalmente apunta al socket unix:///var/run/docker.sock) ejecutando:

docker context use default
Enter fullscreen mode Exit fullscreen mode

Salimos de la consola WSL para continuar en Powershell:

exit
Enter fullscreen mode Exit fullscreen mode

Efectos secundarios

Al introducir en el .bashrc la creación del `hostname+ , tenemos como “inconveniente” que a partir de ahora cada vez que entremos en el entorno WSL nos pedirá la contraseña, ya que hemos incluido una línea de código con “sudo”, lo cual obliga a ejecutarse con los permisos de root.

¿Porqué añadimos la IP que nos entrega ip route show?

Si miras la configuración de redes de tu equipo, verás que tienes una red virtual que se llama “WSL (Hyper-V firewall)”, donde está configurada la IP de nuestro host con acceso a través del firewall. Si desde WSL compruebas con telnet verás que nos permite la conexión.

Finalizar la instalación

Activar WSL en el inicio de sesión.

El único inconveniente que tiene utilizar Docker con WSL es que necesitas tener WSL funcionando.
Por ello, lo mejor es levantar la distro al inicio de sesión y dejar la ventana minimizada.

Para añadir el arranque de WSL al inicio, pulsa Win+R y escribe shell:startup, y presiona Enter.

Ahora, en la ventana que te ha abierto, con el ratón, crea un nuevo acceso directo y escribe:

wsl -d Ubuntu

Para finalizar pulsa siguiente y ponle nombre al acceso directo, por ejemplo, "wsl-Ubuntu".

Enlaces

Siguiente artículo:

Top comments (0)