Docker 守护程序故障排除

本页介绍了在遇到 问题。

您可以在守护程序上启用调试,以了解 守护程序并帮助进行故障排除。如果守护程序没有响应,您可以 还强制对所有 线程,通过向 Docker 守护程序。SIGUSR

守护 进程

无法连接到 Docker 守护程序

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

此错误可能表示:

  • Docker 守护程序未在您的系统上运行。启动守护程序并尝试 再次运行该命令。
  • 您的 Docker 客户端正在尝试连接到其他 host,并且该主机无法访问。

检查 Docker 是否正在运行

检查 Docker 是否正在运行的独立于操作系统的方法是 ask Docker,使用命令。docker info

您还可以使用操作系统实用程序(如 or 或 ),或使用 Windows 检查服务状态 公用事业。sudo systemctl is-active dockersudo status dockersudo service docker status

最后,您可以使用 命令(如 或 .dockerdpstop

检查您的客户端正在连接到哪个主机

要查看您的客户端正在连接到哪个主机,请检查环境中变量的值。DOCKER_HOST

$ env | grep DOCKER_HOST

如果此命令返回值,则 Docker 客户端将设置为连接到 Docker 守护程序。如果未设置,则 Docker 客户端设置为 connect 添加到本地主机上运行的 Docker 守护程序。如果设置错误,请使用 以下命令取消设置:

$ unset DOCKER_HOST

您可能需要在 files 中编辑环境,例如 or 以防止变量设置错误。~/.bashrc~/.profileDOCKER_HOST

如果按预期设置,请验证 Docker 守护程序是否正在运行 远程主机,并且防火墙或网络中断不会阻止您 连接。DOCKER_HOST

排查 daemon.json 脚本和启动脚本之间的冲突

如果使用文件并将选项传递给命令 手动或使用启动脚本,并且这些选项冲突,则 Docker 无法 以如下错误开头:daemon.jsondockerd

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

如果您看到与此类似的错误,并且正在手动启动守护程序 使用 Flags,您可能需要调整 Flags 或 要删除 冲突。daemon.json

注意

如果您看到有关 的特定错误消息,请继续阅读下一部分以获取解决方法。hosts

如果您使用操作系统的 init 脚本启动 Docker,则可以 需要以特定于 操作系统。

使用 systemd 配置守护程序主机

一个难以 疑难解答是指您希望指定与 违约。默认情况下,Docker 侦听套接字。在 Debian 和 Ubuntu 系统上 使用 ,这意味着在启动 时始终使用 Host 标志。如果在 中指定一个条目,这会导致 配置冲突,导致 Docker 守护程序无法启动。systemd-Hdockerdhostsdaemon.json

要临时解决这个问题,请创建一个包含以下内容的新文件: 删除默认情况下启动守护程序时使用的参数。/etc/systemd/system/docker.service.d/docker.conf-H

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

在其他时候,您可能需要使用 Docker 进行配置, 例如配置 HTTP 或 HTTPS 代理systemd

注意

如果在手动启动 Docker 时覆盖此选项,但未在 or 标志中指定条目,则 Docker 无法 开始。hostsdaemon.json-H

在尝试启动 Docker 之前运行。如果 Docker 成功启动,它现在正在侦听 key 中指定的 IP 地址,而不是套接字。sudo systemctl daemon-reloadhostsdaemon.json

重要

Docker 不支持 中的设置 适用于 Windows 的 Desktop 或适用于 Mac 的 Docker Desktop。hostsdaemon.json

内存不足问题

如果您的容器尝试使用的内存超过系统的可用内存,则 可能会遇到内存不足 (OOM) 异常,并且容器或 Docker 守护进程可能会被内核 OOM 终止程序停止。为了防止这种情况 发生时,请确保您的应用程序在具有足够内存的主机上运行,并且 请参阅了解内存不足的风险

内核兼容性

如果您的内核版本低于 3.10 版本,或者 Docker 无法正常运行 缺少内核模块。要检查内核兼容性,您可以下载并运行 check-config.sh 脚本。

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

$ bash ./check-config.sh

该脚本仅适用于 Linux。

内核 cgroup 交换限制功能

在 Ubuntu 或 Debian 主机上,在以下情况下,您可能会看到类似于以下内容的消息 使用镜像。

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

如果您不需要这些功能,则可以忽略警告。

您可以按照以下方法在 Ubuntu 或 Debian 上启用这些功能 指示。内存和交换空间会计产生的开销约为 总可用内存和 10% 的整体性能下降,即使 Docker 未运行。

  1. 以具有权限的用户身份登录 Ubuntu 或 Debian 主机。sudo

  2. 编辑文件。添加或编辑行 添加以下两个键值对:/etc/default/grubGRUB_CMDLINE_LINUX

    GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"

    保存并关闭文件。

  3. 更新 GRUB 引导加载程序。

    $ sudo update-grub
    

    如果您的 GRUB 配置文件的语法不正确,则会发生错误。在这个 case 中,重复步骤 2 和 3。

    这些更改将在您重新启动系统时生效。

联网

IP 转发问题

如果使用 systemd 手动配置网络 版本 219 或更高版本,Docker 容器可能无法访问您的网络。 从 systemd 版本 220 开始,给定网络的转发设置 () 默认为 off。此设置可防止 IP 转发。它还与 Docker 在容器中启用设置的行为冲突。systemd-networknet.ipv4.conf.<interface>.forwardingnet.ipv4.conf.all.forwarding

要在 RHEL、CentOS 或 Fedora 上解决此问题,请在 Docker 主机上编辑该文件,例如 .<interface>.network/usr/lib/systemd/network//usr/lib/systemd/network/80-container-host0.network

在该部分中添加以下块。[Network]

[Network]
...
IPForward=kernel
# OR
IPForward=true

此配置允许按预期从容器进行 IP 转发。

DNS 解析器问题

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

Linux 桌面环境通常运行一个网络管理器程序,该程序 用于缓存 DNS 请求,方法是将 DNS 请求添加到 。实例在环回地址上运行,例如 或 。它加快了 DNS 查找速度并提供 DHCP 服务。这样的 配置在 Docker 容器中不起作用。Docker 容器使用 它自己的网络命名空间,并解析环回地址,例如解析到自身,并且它不太可能在自己的环回上运行 DNS 服务器 地址。dnsmasq/etc/resolv.confdnsmasq127.0.0.1127.0.1.1127.0.0.1

如果 Docker 检测到 中引用的 DNS 服务器是完全的 正常运行的 DNS 服务器,则会出现以下警告:/etc/resolv.conf

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]

如果您看到此警告,请首先检查您是否使用了 :dnsmasq

$ ps aux | grep dnsmasq

如果您的容器需要解析网络内部的主机,则 公共名称服务器是不够的。您有两个选择:

  • 指定 Docker 要使用的 DNS 服务器。

  • 关闭。dnsmasq

    关闭 会将实际 DNS 名称服务器的 IP 地址添加到 ,并且您会失去 的好处。dnsmasq/etc/resolv.confdnsmasq

您只需要使用其中一种方法。

为 Docker 指定 DNS 服务器

配置文件的默认位置是 。你 可以使用 daemon 标志更改配置文件的位置。以下说明假定 配置文件为 。/etc/docker/daemon.json--config-file/etc/docker/daemon.json

  1. 创建或编辑 Docker 守护程序配置文件,该文件默认为 file,用于控制 Docker 守护程序 配置。/etc/docker/daemon.json

    $ sudo nano /etc/docker/daemon.json
    
  2. 添加具有一个或多个 DNS 服务器 IP 地址作为值的密钥。dns

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

    如果文件已有内容,则只需添加或编辑该行。如果您的内部 DNS 服务器无法解析公有 IP 地址,请包括 至少一个可以的 DNS 服务器。这样做允许您连接到 Docker Hub 和您的容器来解析 Internet 域名。dns

    保存并关闭文件。

  3. 重新启动 Docker 守护程序。

    $ sudo service docker restart
    
  4. 验证 Docker 是否可以解析外部 IP 地址,方法是尝试拉取 镜像:

    $ docker pull hello-world
    
  5. 如有必要,请验证 Docker 容器是否可以解析内部主机名 通过 ping 它。

    $ docker run --rm -it alpine ping -c4 <my_internal_host>
    
    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
    

关闭 dnsmasq


如果您不想更改 Docker 守护进程的配置以使用特定的 IP 地址,请按照这些说明在 NetworkManager 中关闭。dnsmasq

  1. 编辑文件。/etc/NetworkManager/NetworkManager.conf

  2. 通过在开头添加字符来注释掉该行 的线路。dns=dnsmasq#

    # dns=dnsmasq

    保存并关闭文件。

  3. 重新启动 NetworkManager 和 Docker。或者,您可以重新启动 您的系统。

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

要在 RHEL、CentOS 或 Fedora 上关闭:dnsmasq

  1. 关闭服务:dnsmasq

    $ sudo systemctl stop dnsmasq
    $ sudo systemctl disable dnsmasq
    
  2. 使用 Red Hat 文档手动配置 DNS 服务器。


Docker 网络正在消失

如果 Docker 网络(例如网桥或自定义网络)随机 消失或似乎工作不正常,可能是因为 另一个服务正在干扰或修改 Docker 接口。工具 管理主机上的网络接口有时也是已知的 不恰当地修改 Docker 接口。docker0

有关如何配置 network manager 将 Docker 接口设置为 un-managed,具体取决于 主机上存在的网络管理工具:

卸载 netscript

如果您的系统上安装了 ,您可以通过以下方式解决此问题 卸载它。例如,在基于 Debian 的系统上:netscript

$ sudo apt-get remove netscript-2.4

取消管理 Docker 接口

在某些情况下,网络管理器将尝试通过以下方式管理 Docker 接口 违约。您可以尝试将 Docker 网络显式标记为非托管 编辑系统的 Network Configuration 设置。


如果您使用的是 ,请在NetworkManager/etc/network/interfaces

  1. 使用以下命令创建文件 内容:/etc/network/interfaces.d/20-docker0

    iface docker0 inet manual

    请注意,此示例配置仅 “un-managed” 默认网桥,而不是自定义网络。docker0

  2. 重新启动以使配置更改生效。NetworkManager

    $ systemctl restart NetworkManager
    
  3. 验证接口是否具有状态。docker0unmanaged

    $ nmcli device
    

如果您在用作网络的系统上运行 Docker daemon 中,通过创建配置 下的文件 :systemd-networkd/etc/systemd/network

  1. 使用以下内容创建 (Create):/etc/systemd/network/docker.network

    # Ensure that the Docker interfaces are un-managed
    
    [Match]
    Name=docker0 br-* veth*
    
    [Link]
    Unmanaged=yes
  2. 重新加载配置。

    $ sudo systemctl restart systemd-networkd
    
  3. 重新启动 Docker 守护程序。

    $ sudo systemctl restart docker
    
  4. 验证 Docker 接口是否具有状态。unmanaged

    $ networkctl
    

防止 Netplan 覆盖网络配置

在通过 cloud-init 使用 Netplan 的系统上,您可以 需要应用自定义配置以防止覆盖 Network Manager 配置:netplan

  1. 按照 取消管理 Docker 接口 中的步骤创建网络管理器配置。

  2. 在 下创建配置文件。netplan/etc/netplan/50-cloud-init.yml

    以下示例配置文件是一个起点。 调整它以匹配要取消管理的接口。 不正确的配置可能会导致网络连接问题。

    /etc/netplan/50-cloud-init.yml
    network:
      ethernets:
        all:
          dhcp4: true
          dhcp6: true
          match:
            # edit this filter to match whatever makes sense for your system
            name: en*
      renderer: networkd
      version: 2
  3. 应用新的 Netplan 配置。

    $ sudo netplan apply
    
  4. 重新启动 Docker 守护程序:

    $ sudo systemctl restart docker
    
  5. 验证 Docker 接口是否具有状态。unmanaged

    $ networkctl
    

无法删除文件系统

Error: Unable to remove filesystem

一些基于容器的实用程序,例如 作为 Google cAdvisor,挂载 Docker 系统 目录(如 )添加到容器中。例如, documentation 的 指导您将容器作为 遵循:/var/lib/docker/cadvisorcadvisor

$ 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

当你 bind-mount 时,这有效地挂载了 所有其他正在运行的容器作为挂载 .当您尝试删除这些容器中的任何一个时, 删除尝试可能会失败,并显示如下错误:/var/lib/docker//var/lib/docker/

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

如果绑定挂载的容器使用 或 on 文件系统处理 WITHIN 但不关闭它们,则会出现此问题。/var/lib/docker/statfsfstatfs/var/lib/docker/

通常,我们建议不要以这种方式进行绑定挂载。 但是,核心功能需要此 bind-mount。/var/lib/dockercAdvisor

如果您不确定是哪个进程导致错误中提到的路径 忙碌并防止它被删除,你可以使用命令 以查找其进程。例如,对于上面的错误:lsof

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

要临时解决这个问题,请停止 bind-mounts 的容器,然后再次尝试删除另一个容器。/var/lib/docker