Docker 守护程序故障排除
本页介绍了在遇到 问题。
您可以在守护程序上启用调试,以了解
守护程序并帮助进行故障排除。如果守护程序没有响应,您可以
还强制对所有
线程添加到守护进程日志中,方法是发送SIGUSR
signal 传递给
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-file
daemon 标志。以下说明假定
配置文件为/etc/docker/daemon.json
.
创建或编辑 Docker 守护进程配置文件,默认为
/etc/docker/daemon.json
文件,它控制 Docker 守护进程 配置。$ sudo nano /etc/docker/daemon.json
添加
dns
key 中将一个或多个 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 网络(例如docker0
bridge 或自定义网络(随机)
消失或似乎工作不正常,可能是因为
另一个服务正在干扰或修改 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” 默认
docker0
bridge 而不是 Custom networks 的 Bridge 中。重新启动
NetworkManager
以使配置更改生效。$ systemctl restart NetworkManager
验证
docker0
interface 具有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
指示您运行cadvisor
container 设置为
遵循:
$ 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
或fstatfs
on filesystem 句柄内/var/lib/docker/
并且不会关闭它们。
通常,我们建议不要绑定安装/var/lib/docker
以这种方式。
然而cAdvisor
需要此 bind-mount 才能实现核心功能。
如果您不确定是哪个进程导致错误中提到的路径
忙碌并防止它被删除,您可以使用lsof
命令
以查找其进程。例如,对于上面的错误:
$ sudo lsof /var/lib/docker/containers/74bef250361c7817bee19349c93139621b272bc8f654ae112dd4eb9652af9515/shm
要临时解决这个问题,请停止 bind-mounts/var/lib/docker
,然后再次尝试删除另一个容器。