假设我有一个想要运行的Docker容器,然后我可以调用它

$ docker run ...

一切都很好。是否有一种内置的方法来运行容器,使其在系统崩溃并重新启动时自动重新启动?

如果是的话,这在Docker Compose中也可用吗?


当前回答

文档中的更“温和”模式:

docker run -dit --restart unless-stopped <image_name>

其他回答

你可以使用docker update——restart=on-failure <容器ID或名称>。

顾名思义,On -failure不仅会在失败时重新启动容器,还会在系统引导时重新启动容器。

根据文档,有多个重启选项:

Flag            Description
no              Do not automatically restart the container. (the default)
on-failure      Restart the container if it exits due to an error, which manifests as a non-zero exit code.
always          Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted. (See the second bullet listed in restart policy details)
unless-stopped  Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.

我在运行Linux系统时也遇到了类似的问题。在系统启动后,一个具有“unless-stopped”重启策略的容器将不会自动重启,除非我输入了一个以某种方式使用docker的命令,例如“docker ps”。我很惊讶,因为我以为这个命令只是报告一些状态信息。接下来我尝试了命令“systemctl status docker”。在一个没有运行docker命令的系统上,该命令报告如下:

● docker.service - Docker Application Container Engine

   Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)

     Active: inactive (dead)    TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com

在没有其他docker命令的情况下运行“docker ps”的系统上,我得到了以下信息:

● docker.service - Docker Application Container Engine
    Loaded: loaded (/lib/systemd/system/docker.service; disabled; vendor preset: enabled)

    Active: active (running) since Sun 2020-11-22 08:33:23 PST; 1h 25min ago

TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com

   Main PID: 3135 (dockerd)
      Tasks: 13

    Memory: 116.9M
     CGroup: /system.slice/docker.service
             └─3135 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
 ... [various messages not shown ]

最有可能的解释是,在完全初始化和启动容器之前,Docker会等待一些Docker命令。您可以假定在容器所需的所有服务初始化后的某个时刻在systemd单元文件中运行“docker ps”。我通过放置一个名为docker-onboot的文件来测试这一点。将服务放在/lib/systemd/system目录下,内容如下:

[Unit]
# This service is provided to force Docker containers
# that should automatically restart to restart when the system
# is booted. While the Docker daemon will start automatically,
# it will not be fully initialized until some Docker command
# is actually run.  This unit merely runs "docker ps": any
# Docker command will result in the Docker daemon completing
# its initialization, at which point all containers that can be
# automatically restarted after booting will be restarted.
#
Description=Docker-Container Startup on Boot
Requires=docker.socket
After=docker.socket network-online.target containerd.service

[Service]
Type=oneshot
ExecStart=/usr/bin/docker ps

[Install]

WantedBy = multi-user目标。

到目前为止(在一次测试中,启用了此服务),容器在计算机启动时启动。我没有尝试依赖docker。服务因为docker。在运行docker命令之前,服务不会启动。下一个测试将禁用docker-onboot(看看WantedBy依赖项是否会自动启动它)。

缺省情况下,重启策略为no。

对于已创建的容器,使用docker update更新重启策略。

docker update --restart=always 0576df221c0b

0576df221c0b是容器id。

如果你希望容器在没有用户登录的情况下也能启动(比如我只启动了VirtualBox虚拟机,不想每次都登录)。下面是我为Ubuntu 16.04 LTS执行的步骤。例如,我安装了一个oracle db容器:

$ docker pull alexeiled/docker-oracle-xe-11g
$ docker run -d --name=MYPROJECT_oracle_db --shm-size=2g -p 1521:1521 -p 8080:8080 alexeiled/docker-oracle-xe-11g
$ vim /etc/systemd/system/docker-MYPROJECT-oracle_db.service

并增加以下内容:

[Unit]
Description=Redis container
Requires=docker.service
After=docker.service

[Service]
Restart=always
ExecStart=/usr/bin/docker start -a MYPROJECT_oracle_db
ExecStop=/usr/bin/docker stop -t 2 MYPROJECT_oracle_db

[Install]
WantedBy=default.target

并在启动时启用该服务

sudo systemctl enable docker-MYPROJECT-oracle_db.service

欲了解更多信息,请访问https://docs.docker.com/engine/admin/host_integration/

这就是crontab的作用:

@reboot sleep 10 ; docker start <container name> 2>&1 | /usr/bin/logger -t 'docker start'

通过crontab -e访问用户crontab或使用crontab -l显示它或在/etc/crontab编辑系统crontab

这个答案只能作为备份或替代使用本地Docker重启策略和/或SystemD服务单元来控制系统启动时容器的启动。

我觉得我提到这个答案的唯一原因是一种非理性的情绪反应,因为为了使SystemD服务单元方法正常工作,您必须正确处理过于复杂和大量的事情,因为这样一个简单的任务在任何Linux机器上都应该是简单的。