# Resolución de problemas en el demonio de Docker


Esta página describe cómo diagnosticar y depurar el demonio si experimentas problemas.

Puedes activar la depuración en el demonio para conocer la actividad en tiempo de ejecución del demonio y ayudar en la resolución de problemas. Si el demonio no responde, también puedes [forzar un volcado de pila completo](/engine/daemon/troubleshoot/logs/#forzar-el-registro-de-un-volcado-de-pila-stack-trace) de todos los subprocesos para que se añada al registro del demonio enviando la señal `SIGUSR1` al demonio de Docker.

## Demonio (Daemon)

### No es posible conectarse al demonio de Docker

```text
Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?
```

Este error puede indicar:

- El demonio de Docker no se está ejecutando en tu sistema. Inicia el demonio e intenta ejecutar el comando nuevamente.
- Tu cliente de Docker está intentando conectarse a un demonio de Docker en un host diferente, y ese host no está accesible.

### Comprobar si Docker se está ejecutando

La forma independiente del sistema operativo para comprobar si Docker se está ejecutando es preguntarle a Docker, utilizando el comando `docker info`.

También puedes utilizar utilidades del sistema operativo, como `sudo systemctl is-active docker`, `sudo status docker` o `sudo service docker status`, o comprobar el estado del servicio utilizando utilidades de Windows.

Finalmente, puedes comprobar en la lista de procesos el proceso `dockerd`, utilizando comandos como `ps` o `top`.

#### Comprobar a qué host se está conectando tu cliente

Para ver a qué host se está conectando tu cliente, comprueba el valor de la variable `DOCKER_HOST` en tu entorno.

```console
$ env | grep DOCKER_HOST
```

Si este comando devuelve un valor, el cliente de Docker está configurado para conectarse a un demonio de Docker que se ejecuta en ese host. Si no está configurada, el cliente de Docker está configurado para conectarse al demonio de Docker que se ejecuta en el host local. Si se configuró por error, utiliza el siguiente comando para eliminarla:

```console
$ unset DOCKER_HOST
```

Es posible que necesites editar tu entorno en archivos como `~/.bashrc` o `~/.profile` para evitar que la variable `DOCKER_HOST` se configure erróneamente.

Si `DOCKER_HOST` está configurada de la forma prevista, verifica que el demonio de Docker se esté ejecutando en el host remoto y que un cortafuegos o una caída de red no te impidan conectarte.

### Resolver conflictos entre `daemon.json` y los scripts de inicio

Si utilizas un archivo `daemon.json` y también pasas opciones al comando `dockerd` de forma manual o mediante scripts de inicio, y estas opciones entran en conflicto, Docker no se iniciará y mostrará un error como el siguiente:

```text
unable to configure the Docker daemon with file /etc/docker/daemon.json:
the following directives are specified both as a flag and in the configuration
file: hosts: (from flag: [unix:///var/run/docker.sock], from file: [tcp://127.0.0.1:2376])
```

Si ves un error similar a este y estás iniciando el demonio manualmente con opciones (flags), es posible que debas ajustar tus opciones o el archivo `daemon.json` para eliminar el conflicto.

> [!NOTE]
>
> Si ves este mensaje de error específico sobre `hosts`, continúa en la [siguiente sección](#configurar-el-host-del-demonio-con-systemd) para ver una solución alternativa.

Si estás iniciando Docker utilizando los scripts de inicio de tu sistema operativo, es posible que debas anular los valores predeterminados en estos scripts de la manera específica que requiera el sistema operativo.

#### Configurar el host del demonio con systemd

Un ejemplo notable de conflicto de configuración difícil de diagnosticar es cuando deseas especificar una dirección de demonio diferente a la predeterminada. Docker escucha en un socket de forma predeterminada. En sistemas Debian y Ubuntu que utilizan `systemd`, esto significa que siempre se utiliza una opción de host `-H` al iniciar `dockerd`. Si especificas una entrada `hosts` en el archivo `daemon.json`, esto provoca un conflicto de configuración y hace que el demonio de Docker no se inicie.

Para solucionar este problema, crea un nuevo archivo `/etc/systemd/system/docker.service.d/docker.conf` con el siguiente contenido, para eliminar el argumento `-H` que se utiliza al iniciar el demonio de forma predeterminada:

```systemd
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
```

Existen otras ocasiones en las que podrías necesitar configurar `systemd` con Docker, como al [configurar un proxy HTTP o HTTPS](/engine/daemon/proxy/).

> [!NOTE]
>
> Si anulas esta opción sin especificar una entrada `hosts` en `daemon.json` o una opción `-H` al iniciar Docker manualmente, Docker no se iniciará.

Ejecuta `sudo systemctl daemon-reload` antes de intentar iniciar Docker. Si Docker se inicia correctamente, ahora estará escuchando en la dirección IP especificada en la clave `hosts` de `daemon.json` en lugar de en un socket.

> [!IMPORTANT]
>
> Configurar `hosts` en `daemon.json` no es compatible con Docker Desktop para Windows o Docker Desktop para Mac.

### Problemas de falta de memoria (Out of Memory)

Si tus contenedores intentan utilizar más memoria de la que el sistema tiene disponible, es posible que experimentes una excepción de falta de memoria (OOM) y que el kernel detenga un contenedor o el propio demonio de Docker mediante el OOM killer. Para evitar que esto suceda, asegúrate de que tu aplicación se ejecute en hosts con memoria adecuada y consulta [Comprender los riesgos de quedarse sin memoria](/engine/containers/resource_constraints/#comprender-los-riesgos-de-quedarse-sin-memoria).

### Compatibilidad del kernel

Docker no puede funcionar correctamente si tu kernel es anterior a la versión 3.10, o si le faltan módulos del kernel. Para comprobar la compatibilidad del kernel, puedes descargar y ejecutar el script [`check-config.sh`](https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh).

```console
$ curl https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh > check-config.sh

$ bash ./check-config.sh
```

El script solo funciona en Linux.

### Capacidades de límite de swap de cgroup en el kernel

En hosts Ubuntu o Debian, es posible que veas mensajes similares al siguiente al trabajar con una imagen:

```text
WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.
```

Si no necesitas estas capacidades, puedes ignorar la advertencia.

Puedes activar estas capacidades en Ubuntu o Debian siguiendo estas instrucciones. La contabilidad de memoria y swap conlleva una sobrecarga de aproximadamente el 1% de la memoria total disponible y una degradación general del rendimiento del 10%, incluso cuando Docker no se está ejecutando.

1. Inicia sesión en el host Ubuntu o Debian como un usuario con privilegios de `sudo`.

2. Edita el archivo `/etc/default/grub`. Añade o edita la línea `GRUB_CMDLINE_LINUX` para agregar los siguientes dos pares clave-valor:

   ```text
   GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"
   ```

   Guarda y cierra el archivo.

3. Actualiza el cargador de arranque GRUB:

   ```console
   $ sudo update-grub
   ```

   Se producirá un error si tu archivo de configuración de GRUB tiene una sintaxis incorrecta. En ese caso, repite los pasos 2 y 3.

   Los cambios surtirán efecto cuando reinicies el sistema.

## Redes

### Problemas de reenvío de IP (IP forwarding)

Si configuras manualmente tu red utilizando `systemd-network` con systemd versión 219 o posterior, es posible que los contenedores de Docker no puedan acceder a tu red. A partir de la versión 220 de systemd, la configuración de reenvío para una red determinada (`net.ipv4.conf.<interface>.forwarding`) está desactivada por defecto. Esta configuración impide el reenvío de IP. También entra en conflicto con el comportamiento de Docker de habilitar la configuración `net.ipv4.conf.all.forwarding` dentro de los contenedores.

Para solucionar esto en RHEL, CentOS o Fedora, edita el archivo `<interface>.network` en `/usr/lib/systemd/network/` en tu host de Docker, por ejemplo, `/usr/lib/systemd/network/80-container-host0.network`.

Añade el siguiente bloque dentro de la sección `[Network]`:

```systemd
[Network]
...
IPForward=kernel
# O
IPForward=true
```

Esta configuración permite el reenvío de IP desde el contenedor como se espera.

### Problemas con el resolver de DNS

```console
DNS resolver found in resolv.conf and containers can't use it
```

Los entornos de escritorio Linux a menudo tienen en ejecución un programa gestor de red que utiliza `dnsmasq` para almacenar en caché las solicitudes DNS agregándolas a `/etc/resolv.conf`. La instancia de `dnsmasq` se ejecuta en una dirección de bucle de retorno (loopback) como `127.0.0.1` o `127.0.1.1`. Acelera las búsquedas DNS y proporciona servicios DHCP. Dicha configuración no funciona dentro de un contenedor Docker. El contenedor Docker utiliza su propio espacio de nombres de red y resuelve las direcciones de loopback como `127.0.0.1` hacia sí mismo, y es poco probable que ejecute un servidor DNS en su propia dirección de loopback.

Si Docker detecta que ningún servidor DNS referenciado en `/etc/resolv.conf` es un servidor DNS completamente funcional, se produce la siguiente advertencia:

```text
WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers
can't use it. Using default external servers : [8.8.8.8 8.8.4.4]
```

Si ves esta advertencia, primero comprueba si utilizas `dnsmasq`:

```console
$ ps aux | grep dnsmasq
```

Si tu contenedor necesita resolver hosts que son internos de tu red, los servidores de nombres públicos no son adecuados. Tienes dos opciones:

- Especificar los servidores DNS que debe usar Docker.
- Desactivar `dnsmasq`.

  Desactivar `dnsmasq` añade las direcciones IP de los servidores de nombres DNS reales a `/etc/resolv.conf`, y pierdes los beneficios de `dnsmasq`.

Solo necesitas utilizar uno de estos métodos.

### Especificar servidores DNS para Docker

La ubicación predeterminada del archivo de configuración es `/etc/docker/daemon.json`. Puedes cambiar la ubicación del archivo de configuración utilizando la opción del demonio `--config-file`. Las siguientes instrucciones asumen que la ubicación del archivo de configuración es `/etc/docker/daemon.json`.

1. Crea o edita el archivo de configuración del demonio de Docker, el cual por defecto es `/etc/docker/daemon.json`, que controla la configuración del demonio de Docker.

   ```console
   $ sudo nano /etc/docker/daemon.json
   ```

2. Añade una clave `dns` con una o más direcciones IP de servidores DNS como valores.

   ```json
   {
     "dns": ["8.8.8.8", "8.8.4.4"]
   }
   ```

   Si el archivo ya tiene contenido, solo necesitas añadir o editar la línea `dns`. Si tu servidor DNS interno no puede resolver direcciones IP públicas, incluye al menos un servidor DNS que sí pueda. Hacerlo te permite conectarte a Docker Hub y que tus contenedores resuelvan nombres de dominio de Internet.

   Guarda y cierra el archivo.

3. Reinicia el demonio de Docker.

   ```console
   $ sudo service docker restart
   ```

4. Verifica que Docker puede resolver direcciones IP externas intentando descargar una imagen:

   ```console
   $ docker pull hello-world
   ```

5. Si es necesario, verifica que los contenedores de Docker pueden resolver un nombre de host interno haciendo ping al mismo:

   ```console
   $ docker run --rm -it alpine ping -c4 <mi_host_interno>

   PING google.com (192.168.1.2): 56 data bytes
   64 bytes from 192.168.1.2: seq=0 ttl=41 time=7.597 ms
   64 bytes from 192.168.1.2: seq=1 ttl=41 time=7.635 ms
   64 bytes from 192.168.1.2: seq=2 ttl=41 time=7.660 ms
   64 bytes from 192.168.1.2: seq=3 ttl=41 time=7.677 ms
   ```

### Desactivar `dnsmasq`

**Ubuntu**



Si prefieres no cambiar la configuración del demonio de Docker para usar una dirección IP específica, sigue estas instrucciones para desactivar `dnsmasq` en NetworkManager.

1. Edita el archivo `/etc/NetworkManager/NetworkManager.conf`.

2. Comenta la línea `dns=dnsmasq` añadiendo un carácter `#` al principio de la línea.

   ```text
   # dns=dnsmasq
   ```

   Guarda y cierra el archivo.

3. Reinicia tanto NetworkManager como Docker. Como alternativa, puedes reiniciar tu sistema.

   ```console
   $ sudo systemctl restart network-manager
   $ sudo systemctl restart docker
   ```

**RHEL, CentOS o Fedora**



Para desactivar `dnsmasq` en RHEL, CentOS o Fedora:

1. Detén el servicio `dnsmasq`:

   ```console
   $ sudo systemctl stop dnsmasq
   $ sudo systemctl disable dnsmasq
   ```

2. Configura los servidores DNS manualmente utilizando la [documentación de Red Hat](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_and_managing_networking/configuring-the-order-of-dns-servers_configuring-and-managing-networking).



### Redes de Docker que desaparecen

Si una red de Docker, como el puente `docker0` o una red personalizada, desaparece aleatoriamente o parece no funcionar correctamente, podría deberse a que otro servicio está interfiriendo o modificando las interfaces de Docker. Se sabe que las herramientas que gestionan las interfaces de red en el host a veces modifican de forma inapropiada las interfaces de Docker.

Consulta las siguientes secciones para obtener instrucciones sobre cómo configurar tu gestor de red para establecer las interfaces de Docker como no gestionadas (un-managed), según las herramientas de gestión de red que existan en el host:

- Si `netscript` está instalado, considera [desinstalarlo](#desinstalar-netscript)
- Configura el gestor de red para [tratar las interfaces de Docker como no gestionadas](#tratar-las-interfaces-de-docker-como-no-gestionadas)
- Si estás utilizando Netplan, es posible que debas [aplicar una configuración personalizada de Netplan](#evitar-que-netplan-anule-la-configuracion-de-red)

#### Desinstalar `netscript`

Si `netscript` está instalado en tu sistema, probablemente puedas solucionar este problema desinstalándolo. Por ejemplo, en un sistema basado en Debian:

```console
$ sudo apt-get remove netscript-2.4
```

#### Tratar las interfaces de Docker como no gestionadas

Iniciamente, en algunos casos, el gestor de red intentará gestionar las interfaces de Docker de forma predeterminada. Puedes intentar marcar explícitamente las redes de Docker como no gestionadas editando los ajustes de configuración de red de tu sistema.

**NetworkManager**



Si estás utilizando `NetworkManager`, edita la configuración de red de tu sistema bajo `/etc/network/interfaces`

1. Crea un archivo en `/etc/network/interfaces.d/20-docker0` con el siguiente contenido:

   ```text
   iface docker0 inet manual
   ```

   Ten en cuenta que esta configuración de ejemplo solo establece como "no gestionada" la interfaz bridge predeterminada `docker0`, no las redes personalizadas.

2. Reinicia `NetworkManager` para que el cambio de configuración surta efecto.

   ```console
   $ systemctl restart NetworkManager
   ```

3. Verifica que la interfaz `docker0` tenga el estado `unmanaged`.

   ```console
   $ nmcli device
   ```

**systemd-networkd**



Si estás ejecutando Docker en un sistema que utiliza `systemd-networkd` como demonio de red, configura las interfaces de Docker como no gestionadas creando archivos de configuración bajo `/etc/systemd/network`:

1. Crea `/etc/systemd/network/docker.network` con el siguiente contenido:

   ```ini
   # Garantizar que las interfaces de Docker no sean gestionadas

   [Match]
   Name=docker0 br-* veth*

   [Link]
   Unmanaged=yes
   ```

2. Recarga la configuración.

   ```console
   $ sudo systemctl restart systemd-networkd
   ```

3. Reinicia el demonio de Docker.

   ```console
   $ sudo systemctl restart docker
   ```

4. Verifica que las interfaces de Docker tengan el estado `unmanaged`.

   ```console
   $ networkctl
   ```



### Evitar que Netplan anule la configuración de red

En sistemas que utilizan [Netplan](https://netplan.io/) a través de [`cloud-init`](https://cloudinit.readthedocs.io/en/latest/index.html), es posible que debas aplicar una configuración personalizada para evitar que `netplan` anule la configuración del gestor de red:

1. Sigue los pasos de [Tratar las interfaces de Docker como no gestionadas](#tratar-las-interfaces-de-docker-como-no-gestionadas) para crear la configuración del gestor de red.
2. Crea un archivo de configuración de `netplan` bajo `/etc/netplan/50-cloud-init.yml`.

   El siguiente archivo de configuración de ejemplo es un punto de partida. Ajústalo para que coincida con las interfaces que deseas dejar como no gestionadas. Una configuración incorrecta puede provocar problemas de conectividad de red.

   ```yaml {title="/etc/netplan/50-cloud-init.yml"}
   network:
     ethernets:
       all:
         dhcp4: true
         dhcp6: true
         match:
           # edita este filtro para que coincida con lo que tenga sentido para tu sistema
           name: en*
     renderer: networkd
     version: 2
   ```

3. Aplica la nueva configuración de Netplan.

   ```console
   $ sudo netplan apply
   ```

4. Reinicia el demonio de Docker:

   ```console
   $ sudo systemctl restart docker
   ```

5. Verify that the Docker interfaces have the `unmanaged` state.

   ```console
   $ networkctl
   ```

## Volúmenes

### No se puede eliminar el sistema de archivos (Unable to remove filesystem)

```text
Error: Unable to remove filesystem
```

Algunas utilidades basadas en contenedores, como [Google cAdvisor](https://github.com/google/cadvisor), montan directorios del sistema de Docker, como `/var/lib/docker/`, dentro de un contenedor. Por ejemplo, la documentación de `cadvisor` te indica que ejecutes el contenedor `cadvisor` de la siguiente manera:

```console
$ sudo docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest
```

Al montar `/var/lib/docker/` mediante bind-mount, esto monta efectivamente todos los recursos de todos los demás contenedores en ejecución como sistemas de archivos dentro del contenedor que monta `/var/lib/docker/`. Cuando intentas eliminar cualquiera de estos contenedores, el intento de eliminación puede fallar con un error como el siguiente:

```text
Error: Unable to remove filesystem for
74bef250361c7817bee19349c93139621b272bc8f654ae112dd4eb9652af9515:
remove /var/lib/docker/containers/74bef250361c7817bee19349c93139621b272bc8f654ae112dd4eb9652af9515/shm:
Device or resource busy
```

El problema ocurre si el contenedor que monta `/var/lib/docker/` utiliza `statfs` o `fstatfs` en descriptores de sistemas de archivos dentro de `/var/lib/docker/` y no los cierra.

Normalmente, desaconsejaríamos montar `/var/lib/docker` de esta manera. Sin embargo, `cAdvisor` requiere este montaje para su funcionalidad principal.

Si no estás seguro de qué proceso está provocando que la ruta mencionada en el error esté ocupada e impidiendo que se elimine, puedes utilizar el comando `lsof` para encontrar su proceso. Por ejemplo, para el error anterior:

```console
$ sudo lsof /var/lib/docker/containers/74bef250361c7817bee19349c93139621b272bc8f654ae112dd4eb9652af9515/shm
```

Para solucionar este problema, detén el contenedor que monta `/var/lib/docker` e intenta nuevamente eliminar el otro contenedor.

