Docker 守护程序故障排除
本页介绍了在遇到 问题。
您可以在守护程序上启用调试,以了解
守护程序并帮助进行故障排除。如果守护程序没有响应,您可以
还强制对所有
线程添加到守护进程日志中,方法是发送SIGUSRsignal 传递给
Docker 守护程序。
守护 进程
无法连接到 Docker 守护程序
Cannot connect to the Docker daemon. Is 'docker daemon' running on this host?此错误可能表示:
- Docker 守护程序未在您的系统上运行。启动守护程序并尝试 再次运行该命令。
- 您的 Docker 客户端正在尝试连接到其他 host,并且该主机无法访问。
检查 Docker 是否正在运行
检查 Docker 是否正在运行的独立于作系统的方法是
ask Docker 使用docker info命令。
您还可以使用作系统实用程序,例如sudo systemctl is-active docker或sudo status docker或sudo service docker status或使用 Windows 检查服务状态
公用事业。
最后,您可以在进程列表中查看dockerd进程, 使用
命令,如ps或top.
检查您的客户端正在连接到哪个主机
要查看您的客户端正在连接到哪个主机,请检查DOCKER_HOST变量。
$ env | grep DOCKER_HOST
如果此命令返回值,则 Docker 客户端将设置为连接到 Docker 守护程序。如果未设置,则 Docker 客户端设置为 connect 添加到本地主机上运行的 Docker 守护程序。如果设置错误,请使用 以下命令取消设置:
$ unset DOCKER_HOST
您可能需要在以下文件中编辑环境~/.bashrc或~/.profile以防止DOCKER_HOST变量。
如果DOCKER_HOST按预期设置,请验证 Docker 守护程序是否正在运行
远程主机,并且防火墙或网络中断不会阻止您
连接。
排查daemon.json和启动脚本
如果您使用daemon.json文件,并将选项传递给dockerd命令
手动或使用启动脚本,并且这些选项冲突,则 Docker 无法
以如下错误开头:
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 系统上
用systemd,这意味着 host 标志-H在启动时始终使用dockerd.如果指定hosts条目daemon.json,这会导致
配置冲突,导致 Docker 守护程序无法启动。
要解决此问题,请创建一个新文件/etc/systemd/system/docker.service.d/docker.conf包含以下内容,
要删除-H默认情况下启动守护程序时使用的参数。
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd在其他时候,您可能需要配置systemd使用 Docker,
例如配置 HTTP 或 HTTPS 代理。
注意
如果在未指定
hosts条目daemon.json或-H标志,Docker 无法 开始。
跑sudo systemctl daemon-reload在尝试启动 Docker 之前。如果 Docker
启动成功,它现在正在侦听hosts键的daemon.json而不是套接字。
重要
设置
hosts在daemon.json在 Docker 上不受支持 适用于 Windows 的 Desktop 或适用于 Mac 的 Docker Desktop。
内存不足问题
如果您的容器尝试使用的内存超过系统的可用内存,则 可能会遇到内存不足 (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 未运行。
以用户身份登录 Ubuntu 或 Debian 主机,使用
sudo特权。编辑
/etc/default/grub文件。添加或编辑GRUB_CMDLINE_LINUX线 添加以下两个键值对:GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"保存并关闭文件。
更新 GRUB 引导加载程序。
$ sudo update-grub如果您的 GRUB 配置文件的语法不正确,则会发生错误。在这个 case 中,重复步骤 2 和 3。
这些更改将在您重新启动系统时生效。
联网
IP 转发问题
如果您使用systemd-network使用 systemd
版本 219 或更高版本,Docker 容器可能无法访问您的网络。
从 systemd 版本 220 开始,给定网络的转发设置
(net.ipv4.conf.<interface>.forwarding) 默认为 off。此设置可防止
IP 转发。它还与 Docker 启用net.ipv4.conf.all.forwarding设置。
要在 RHEL、CentOS 或 Fedora 上解决此问题,请编辑<interface>.network文件/usr/lib/systemd/network/例如,在您的 Docker 主机上,/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 桌面环境通常运行一个网络管理器程序,该程序
使用dnsmasq缓存 DNS 请求,方法是将 DNS 请求添加到/etc/resolv.conf.这dnsmasq实例在环回地址上运行,例如127.0.0.1或127.0.1.1.它加快了 DNS 查找速度并提供 DHCP 服务。这样的
配置在 Docker 容器中不起作用。Docker 容器使用
它自己的网络命名空间,并解析环回地址,例如127.0.0.1到自身,并且不太可能在自己的环回上运行 DNS 服务器
地址。
如果 Docker 检测到/etc/resolv.conf完全是
正常运行的 DNS 服务器,则会出现以下警告:
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.关闭
dnsmasq将实际 DNS 名称服务器的 IP 地址添加到/etc/resolv.conf,您将失去dnsmasq.
您只需要使用其中一种方法。
为 Docker 指定 DNS 服务器
配置文件的默认位置是/etc/docker/daemon.json.你
可以使用--config-filedaemon 标志。以下说明假定
配置文件为/etc/docker/daemon.json.
创建或编辑 Docker 守护进程配置文件,默认为
/etc/docker/daemon.json文件,它控制 Docker 守护进程 配置。$ sudo nano /etc/docker/daemon.json添加
dnskey 中将一个或多个 DNS 服务器 IP 地址作为值。{ "dns": ["8.8.8.8", "8.8.4.4"] }如果文件已有内容,则只需添加或编辑
dns线。如果您的内部 DNS 服务器无法解析公有 IP 地址,请包括 至少一个可以的 DNS 服务器。这样做允许您连接到 Docker Hub 和您的容器来解析 Internet 域名。保存并关闭文件。
重新启动 Docker 守护程序。
$ sudo service docker restart验证 Docker 是否可以解析外部 IP 地址,方法是尝试拉取 镜像:
$ docker pull hello-world如有必要,请验证 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 地址,请按照以下说明关闭dnsmasq在 NetworkManager 中。
编辑
/etc/NetworkManager/NetworkManager.conf文件。注释掉
dns=dnsmasq行,在开头添加一个字符 的线路。## dns=dnsmasq保存并关闭文件。
重新启动 NetworkManager 和 Docker。或者,您可以重新启动 您的系统。
$ sudo systemctl restart network-manager $ sudo systemctl restart docker
要关闭dnsmasq在 RHEL、CentOS 或 Fedora 上:
关闭
dnsmasq服务:$ sudo systemctl stop dnsmasq $ sudo systemctl disable dnsmasq使用 Red Hat 文档手动配置 DNS 服务器。
Docker 网络正在消失
如果 Docker 网络(例如docker0bridge 或自定义网络(随机)
消失或似乎工作不正常,可能是因为
另一个服务正在干扰或修改 Docker 接口。工具
管理主机上的网络接口有时也是已知的
不恰当地修改 Docker 接口。
有关如何配置 network manager 将 Docker 接口设置为 un-managed,具体取决于 主机上存在的网络管理工具:
- 如果
netscript已安装,请考虑卸载它 - 配置网络管理器以将 Docker 接口视为非托管接口
- 如果您使用的是 Netplan,则可能需要应用自定义 Netplan 配置
卸载netscript
如果netscript已安装在您的系统上,您可以通过以下方式解决此问题
卸载它。例如,在基于 Debian 的系统上:
$ sudo apt-get remove netscript-2.4
取消管理 Docker 接口
在某些情况下,网络管理器将尝试通过以下方式管理 Docker 接口 违约。您可以尝试将 Docker 网络显式标记为非托管 编辑系统的 Network Configuration 设置。
如果您使用的是NetworkManager,在/etc/network/interfaces
在
/etc/network/interfaces.d/20-docker0替换为 内容:iface docker0 inet manual请注意,此示例配置仅 “un-managed” 默认
docker0bridge 而不是 Custom networks 的 Bridge 中。重新启动
NetworkManager以使配置更改生效。$ systemctl restart NetworkManager验证
docker0interface 具有unmanaged州。$ nmcli device
如果您在使用systemd-networkd作为网络
daemon 中,通过创建配置
下的文件/etc/systemd/network:
创造
/etc/systemd/network/docker.network包含以下内容:# Ensure that the Docker interfaces are un-managed [Match] Name=docker0 br-* veth* [Link] Unmanaged=yes重新加载配置。
$ sudo systemctl restart systemd-networkd重新启动 Docker 守护程序。
$ sudo systemctl restart docker验证 Docker 接口是否具有
unmanaged州。$ networkctl
防止 Netplan 覆盖网络配置
在使用 Netplan 的系统上cloud-init,您可以
需要应用自定义配置以防止netplan从覆盖
Network Manager 配置:
按照 取消管理 Docker 接口 中的步骤创建网络管理器配置。
创建一个
netplan配置文件/etc/netplan/50-cloud-init.yml.以下示例配置文件是一个起点。 调整它以匹配要取消管理的接口。 不正确的配置可能会导致网络连接问题。
/etc/netplan/50-cloud-init.ymlnetwork: ethernets: all: dhcp4: true dhcp6: true match: # edit this filter to match whatever makes sense for your system name: en* renderer: networkd version: 2应用新的 Netplan 配置。
$ sudo netplan apply重新启动 Docker 守护程序:
$ sudo systemctl restart docker验证 Docker 接口是否具有
unmanaged州。$ networkctl
卷
无法删除文件系统
Error: Unable to remove filesystem一些基于容器的实用程序,例如
作为 Google cAdvisor,挂载 Docker 系统
目录,例如/var/lib/docker/,放入容器中。例如,
文档cadvisor指示您运行cadvisorcontainer 设置为
遵循:
$ 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如果 bind-mounts/var/lib/docker/使用statfs或fstatfson filesystem 句柄内/var/lib/docker/并且不会关闭它们。
通常,我们建议不要绑定安装/var/lib/docker以这种方式。
然而cAdvisor需要此 bind-mount 才能实现核心功能。
如果您不确定是哪个进程导致错误中提到的路径
忙碌并防止它被删除,您可以使用lsof命令
以查找其进程。例如,对于上面的错误:
$ sudo lsof /var/lib/docker/containers/74bef250361c7817bee19349c93139621b272bc8f654ae112dd4eb9652af9515/shm
要临时解决这个问题,请停止 bind-mounts/var/lib/docker,然后再次尝试删除另一个容器。