Compartir comentarios
Las respuestas se generan en base a la documentación.

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 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

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.

$ 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:

$ 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:

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 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:

[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.

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.

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.

$ 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:

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:

    GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"

    Guarda y cierra el archivo.

  3. Actualiza el cargador de arranque GRUB:

    $ 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]:

[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

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:

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:

$ 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.

    $ sudo nano /etc/docker/daemon.json
    
  2. Añade una clave dns con una o más direcciones IP de servidores DNS como valores.

    {
      "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.

    $ sudo service docker restart
    
  4. Verifica que Docker puede resolver direcciones IP externas intentando descargar una imagen:

    $ 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:

    $ 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

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.

    # dns=dnsmasq

    Guarda y cierra el archivo.

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

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

Para desactivar dnsmasq en RHEL, CentOS o Fedora:

  1. Detén el servicio dnsmasq:

    $ sudo systemctl stop dnsmasq
    $ sudo systemctl disable dnsmasq
    
  2. Configura los servidores DNS manualmente utilizando la documentación de Red Hat.

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:

Desinstalar netscript

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

$ 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.

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:

    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.

    $ systemctl restart NetworkManager
    
  3. Verifica que la interfaz docker0 tenga el estado unmanaged.

    $ nmcli device
    

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:

    # Garantizar que las interfaces de Docker no sean gestionadas
    
    [Match]
    Name=docker0 br-* veth*
    
    [Link]
    Unmanaged=yes
  2. Recarga la configuración.

    $ sudo systemctl restart systemd-networkd
    
  3. Reinicia el demonio de Docker.

    $ sudo systemctl restart docker
    
  4. Verifica que las interfaces de Docker tengan el estado unmanaged.

    $ networkctl
    

Evitar que Netplan anule la configuración de red

En sistemas que utilizan Netplan a través de cloud-init, 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 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.

    /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.

    $ sudo netplan apply
    
  4. Reinicia el demonio de Docker:

    $ sudo systemctl restart docker
    
  5. Verify that the Docker interfaces have the unmanaged state.

    $ networkctl
    

Volúmenes

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

Error: Unable to remove filesystem

Algunas utilidades basadas en contenedores, como 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:

$ 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:

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:

$ 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.