配置Docker后台程序并进行故障排除

成功安装并启动Docker之后,dockerd后台程序将使用其默认配置运行。本主题讲述如何配置,手动启动后台程序以及在遇到问题时对后台程序进行故障排除和调试。

使用操作系统实用程序启动后台程序

在典型安装中,Docker后台程序由系统实用程序启动,而不是由用户手动启动。这使得在机器重启时自动启动Docker更容易。

启动Docker的命令取决于您的操作系统。在安装Docker下找到正确的页面。要将Docker配置为在系统启动时自动启动,请参阅配置Docker在开机时启动

手动启动后台程序

如果您不想使用系统实用程序来管理Docker后台进程,或者只想进行测试,则可以使用dockerd命令手动运行它。您可能需要使用sudo,具体取决于您的操作系统配置。

当您以这种方式启动Docker时,它在前台运行,并将其日志直接发送到您的终端。

$ dockerd

INFO[0000] +job init_networkdriver() INFO[0000] +job serveapi(unix:///var/run/docker.sock) INFO[0000] Listening for HTTP on unix (/var/run/docker.sock)

要在手动启动Docker时停止它,请在终端中发出Ctrl + C

配置Docker后台程序

有两种方法可以配置Docker后台程序:

  • 使用JSON配置文件。 这是首选方法,因为它将所有配置都放在一个位置。
  • 启动dockerd时使用标志。

就可以同时使用这些选项,只要您未同时在标志和JSON文件中指定相同的选项。 如果发生这种情况,Docker后台程序将不会启动并显示错误消息。

要使用JSON文件配置Docker后台程序,请在Linux系统上的/etc/docker/daemon.json或Windows下的C:\ProgramData\docker\config\daemon.json中创建一个文件。 在MacOS上,转到任务栏中的鲸鱼> Preferences > Daemon > Advanced。

配置文件如下所示:

{
  "debug": true,
  "tls": true,
  "tlscert": "/var/docker/server.pem",
  "tlskey": "/var/docker/serverkey.pem",
  "hosts": ["tcp://192.168.59.3:2376"]
}

通过此配置,Docker后台程序以调试模式运行,使用TLS,并在端口2376上侦听路由至192.168.59.3的流量。 您可以在dockerd参考文档中了解可用的配置选项。

您也可以手动启动Docker后台程序并使用标志对其进行配置。 这对于解决问题很有用。

这是一个如何手动启动Docker后台程序的示例,使用与上面相同的配置:

dockerd --debug--tls=true--tlscert=/var/docker/server.pem--tlskey=/var/docker/serverkey.pem--host tcp://192.168.59.3:2376

您可以在dockerd参考文档中了解可用的配置选项,或通过运行以下命令:

dockerd --help

整个Docker文档中讨论了许多特定的配置选项。 你可能想要了解的内容包括:

Docker后台程序目录

Docker后台程序将所有数据保留在一个目录中。 这将跟踪与Docker相关的所有内容,包括容器,镜像,卷,服务定义和机密。

默认情况下,该目录为:

  • /var/lib/docker on Linux.
  • C:\ProgramData\docker on Windows.

您可以使用data-root配置选项将Docker后台程序配置为使用其他目录。

由于Docker后台程序的状态保留在此目录中,因此请确保为每个后台程序使用专用目录。 如果两个后台程序共享同一目录(例如,NFS共享),则将遇到难以解决的错误。

后台程序故障排除

您可以在后台程序上启用调试功能,以了解该后台程序的运行时活动并为故障排除提供帮助。 如果后台程序完全没有响应,您还可以强制把所有线程的全堆栈跟踪,添加到后台程序日志中,通过发送SIGUSR信号给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])

如果看到类似的错误,并且正在使用标志手动启动后台程序,则可能需要调整标志或daemon.json才能消除冲突。

注意: 如果看到此特定错误,请继续下一节中的解决方法。

如果要使用操作系统的init脚本启动Docker,则可能需要以特定于操作系统的方式覆盖这些脚本中的默认值。

将daemon.json中的hosts键与systemd一起使用

难以解决的配置冲突的一个值得注意的示例是,您想指定一个不同于默认值的后台程序地址。 Docker默认情况下侦听套接字。 在Debian和Ubuntu系统上使用systemd,这意味着启动dockerd时总是使用主机标志-H。 如果您在daemon.json中指定一个hosts条目,则将导致配置冲突(如上述消息所示),并且Docker无法启动。

要解决此问题,请创建具有以下内容的新文件/etc/systemd/system/docker.service.d/docker.conf,以删除默认情况下启动后台程序时使用的-H参数。 。

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

有时您可能需要使用Docker配置systemd,例如配置HTTP或HTTPS代理

注意:如果您覆盖此选项,然后在手动启动Docker时未在daemon.json中指定hosts条目或在-H标志中指定,则Docker无法启动。

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

重要:Desktop for Windows或Docker Desktop for Mac不支持在daemon.json中设置hosts

内存不足异常(OOME)

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

阅读日志

后台程序日志可以帮助您诊断问题。日志可能保存在几个位置之一,具体取决于操作系统配置和使用的日志记录子系统:

Operating system Location
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

启用调试

有两种启用调试的方法。 推荐的方法是将daemon.json文件中的debug键设置为true。 该方法适用于每个Docker平台。

  1. 编辑daemon.json文件,该文件通常位于/etc/docker/中。 如果该文件尚不存在,则可能需要创建它。 在macOS或Windows上,请勿直接编辑文件。取而代之,请转到Preferences/Daemon/Advanced

  2. 如果文件为空,请添加以下内容:

```json
{
  "debug": true
}
```

如果文件已经包含JSON,则只需添加键`"debug":true`,请注意,如果不是结束括号之前的最后一行,请在该行的末尾添加逗号。 还要检查是否已设置`log-level`键,将其设置为`info`或`debug`。 `info`是默认值,可能的值为`debug`,`info`,`warn`,`error`,`fatal`。
  1. 向后台程序发送HUP信号以使其重新加载其配置。 在Linux主机上,使用以下命令。
```bash
$ sudo kill -SIGHUP $(pidof dockerd)
```

在Windows主机上,重新启动Docker。

除了遵循此过程之外,您还可以停止Docker后台进程,并使用调试标志-D手动重新启动它。 但是,这可能会导致Docker在与主机启动脚本创建的不同环境下重新启动,这可能使调试更加困难。

强制记录堆栈跟踪

如果后台程序没有响应,则可以通过向后台程序发送SIGUSR1信号来强制记录完整的堆栈跟踪。

  • Linux:

    $ sudo kill -SIGUSR1 $(pidof dockerd)
    
  • Windows Server:

    下载docker-signal.

    获取dockerd的进程ID Get-Process dockerd.

    运行带有标志的可执行文件 --pid=<PID of daemon>.

这将强制记录堆栈跟踪,但不会停止后台程序。 后台程序日志显示堆栈跟踪或包含堆栈跟踪的文件的路径(如果已将其记录到文件中)。

在收到SIGUSR1信号后后台程序将继续运行,并将堆栈跟踪信息转储到日志。 堆栈跟踪可用于确定后台程序中所有goroutine和线程的状态。

View stack traces

可以使用以下方法之一查看Docker后台程序日志:

  • 在Linux系统上使用systemctl运行journalctl -u docker.service
  • 在一些老板片的Linux上/var/log/messages, /var/log/daemon.log, /var/log/docker.log
  • 在Windows Server上的Docker Engine - Enterprise 运行 Get-EventLog -LogName Application -Source Docker -After (Get-Date).AddMinutes(-5) | Sort-Object Time | Export-CSV ~/last5minutes.CSV

注意:无法在Docker Desktop for Mac 或 Docker Desktop for Windows上手动生成堆栈跟踪。 但是,如果遇到问题,您可以单击Docker任务栏图标,然后选择诊断和反馈以将信息发送给Docker。

在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保存这些堆栈跟踪和转储的位置取决于您的操作系统和配置。 有时您可以直接从堆栈跟踪和转储中获得有用的诊断信息。 否则,您可以将此信息提供给Docker,以帮助诊断问题。

检查Docker是否正在运行

所有操作系统都适用的检查Docker是否正在运行的方法是使用docker info命令询问Docker。

你也可以使用操作系统适用程序, 例如sudo systemctl is-active dockersudo status dockersudo service docker status, 或使用Windws实用程序检查服务状态.

最后, 你可以在进程列表中检查dockerd进程, 使用类似pstop这样的命令。