Í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
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
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
Reiniciar el servicio Docker
Para que los cambios surtan efecto deberemos reiniciar el servicio de Docker:
net stop Docker
net start Docker
Comprueba que el servicio Docker está funcionando:
Get-Service docker
Configurar el demonio de Docker WSL
Entra en el entorno de Ubuntu:
wsl -d ubuntu
Comprueba que tienes los archivos wsl-server-cert.pem
, wsl-server-key.pem
y ca.pem
:
ls /mnt/c/ProgramData/docker/certs/
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
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"
}
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
con el contenido:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
Y reiniciamos el servicio:
sudo systemctl daemon-reload
sudo service docker restart
El siguiente paso es con Powershell, por lo que debemos salir de Ubuntu:
exit
Y hacerle un shutdown:
wsl --shutdown
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"
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
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
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
Y les ponemos los permisos adecuados:
cd ~/.docker/
chmod -v 0400 key.pem
chmod -v 0444 cert.pem ca.pem
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
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
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
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"
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
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
Salimos de la consola WSL para continuar en Powershell:
exit
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:
- Docker en Windows. Apartado V: Instalar Portainer en el entorno WSL2.
Top comments (0)