1、检查Docker是否正在运行
在进行具体问题定位和处理之前,最好和最简单直观的方式是先看看docker引擎是否能够正常运行。有以下几种方法可以确认docker是否处于正常运行状态:
1)通过执行docker info命令可以直接确认docker是否正常运行:
$ sudo docker info
2)也可以使用操作系统的命令来检查docker是否正常运行:
$ sudo systemctl is-active docker # 或者 $ sudo service docker status
3)可以使用ps或top等命令检查进程的进程是否有正常运行的dockerd。
2、解决daemon.json与启动脚本之间的冲突
在Docker中,守护程序会将所有数据都保存在一个根目录中。通过此目录,将能够跟踪到与Docker相关的所有内容,包括容器(containers),镜像(images),存储卷(volumes),服务定义(service definition)和机密(secrets)。默认情况下,此根目录为:
- Linux环境:/var/lib/docker
- Windows环境:C:\ProgramData\docker
可以使用data-root配置选项将Docker守护程序的配置为使用其他目录 。由于Docker守护程序的状态保留在此根目录中,因此需要确保每个守护程序使用专用的目录。如果两个守护程序共享同一根目录(例如,NFS共享),将可能会导致故障的无法处理的情况。
在docker引擎中,如果使用了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])
如果看到类似于上述内容的错误,并且使用此标志手动启动守护程序,则可能需要调整命令字段或daemon.json以解决冲突。如果使用操作系统的初始脚本启动Docker,则可能需要以特定于操作系统的方式覆盖这些脚本中的默认值。
2.1 在DAEMON.JSON中使用HOSTS密钥
默认情况下,Docker会监听套接字(socket)。在Debian和Ubuntu操作系统中使用启动docker时,-H字段会一直被使用。如果在daemon.json指定了一个 hosts条目,则会导致配置冲突,从而导致Docker无法启动。为了解决此问题,请/etc/systemd/system/docker.service.d/docker.conf使用以下内容创建一个新文件,以删除默认情况下启动守护程序时使用的-H参数。
[Service] ExecStart= ExecStart=/usr/bin/dockerd
3、查看日志
守护程序的日志可以帮助诊断问题,docker守护程序日志的具体存储位置取决于操作系统配置和使用的日志记录子系统:
操作系统 | 目录 |
---|---|
RHEL,Oracle Linux | /var/log/messages |
Debian | /var/log/daemon.log |
Ubuntu 16.04+,CentOS | 使用journalctl -u docker.service命令检查日志 |
Ubuntu 14.10- | /var/log/upstart/docker.log |
macOS(Docker 18.01+) | ~/Library/Containers/com.docker.docker/Data/vms/0/console-ring |
macOS(Docker <18.01) | ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/console-ring |
Windows | AppData\Local |
4、启用调试
在daemon.json文件中将 debug键的值设置为true就可以启用docker的调试模式,此方法适用于每个Docker平台。
- daemon.json文件通常位于/etc/docker/目录,如果该文件尚不存在,则需要手动创建此文件。
- 如果文件为空,请添加以下内容:
{ "debug": true }
如果文件中已经包含JSON,则只需添加键值对”debug”: true,如果它不是文件中的最后最后一行,请在行尾添加“;”。同时需要确认log-level是否已设置为info或debug。默认值为info,可能的值包括debug,info,warn,error,fatal。
- 向守护程序发送hup信号以使其重新加载新的配置。在Linux主机上,使用以下命令。
$ sudo kill -SIGHUP $(pidof dockerd)
也可以手动停止Docker守护程序,并使用debug的-D字段标志重新启动它。
5、强制记录堆栈跟踪
如果守护程序没有响应,则可以通过向SIGUSR1守护程序发送信号来强制记录完整堆栈跟踪。
$ sudo kill -SIGUSR1 $(pidof dockerd)
这会强制记录堆栈跟踪,但不会停止守护程序。守护程序日志显示堆栈跟踪或包含堆栈跟踪的文件的路径(如果已记录到文件)。处理完SIGUSR1信号并将堆栈跟踪转储到日志后,守护程序继续运行。堆栈跟踪可用于确定守护程序中所有goroutine和线程的状态。
5.1 查看堆栈跟踪
可以使用以下方法之一查看Docker守护程序日志:
- 在Linux系统上执行journalctl -u docker.service命令;
- 在较旧的Linux系统上,查看/var/log/messages,/var/log/daemon.log或/var/log/docker.log
在Docker日志中查找如下消息:
...goroutine stacks written to /var/run/docker/goroutine-stacks-2017-06-02T193336z.log ...daemon datastructure dump written to /var/run/docker/daemon-data-2017-06-02T193336z.log
Docker保存这些堆栈跟踪和转储的位置取决于操作系统和配置,有时可以直接从堆栈跟踪和转储中获取有用的诊断信息。
参考资料:
1.《Configure and troubleshoot the Docker daemon》地址:https://docs.docker.com/config/daemon/
作者简介:
季向远,本文版权归原作者所有。