“重启:始终”策略如何在 docker-compose 中工作?

Mar*_*cki 40 docker docker-compose

我有 docker compose 文件与 PostgreSQL 和我的应用程序,如下所示:

version: '3'

services:
  postgresql:
    image: postgres:9.6.6
    ports:
      - 9932:5432
    expose:
      - "5432"
    environment:
      - POSTGRES_PASSWORD=pass
    restart: always
    volumes:
      - /data:/var/lib/postgresql/data

  myapp:
    image: myapp
    links:
      - postgresql
    depends_on:
      - "postgresql"
    restart: always
    ports:
      - "5000:5000"
Run Code Online (Sandbox Code Playgroud)

问题是restart: always当我杀死容器(使用 模拟应用程序崩溃docker kill)并且 docker-compose 不会重新启动我的容器时,策略似乎不起作用,即使退出代码是 137。当我使用restart: on-failure策略时,我观察到相同的行为。版本23docker-compose 的行为相同。我的系统是 Ubuntu Server 16.04 x64。

我的问题是:

  1. 为什么 docker-compose 不重启崩溃(被杀死)的容器?
  2. 如何检查重启策略是否有效?

小智 31

当您使用 docker kill 时,这是预期的行为,因为 Docker 不会重新启动容器:“如果您手动停止容器,则其重新启动策略将被忽略,直到 Docker 守护程序重新启动或容器被手动重新启动。这是另一种防止重启循环” (参考)

如果您使用 docker stop 或 docker kill,您将手动停止容器。您可以对重启策略进行一些测试:重启 docker 守护进程、重启服务器、在容器内使用 CMD 并运行退出...

例如,如果我杀死了使用重启策略部署的容器,我会看到它以代码 137 退出,但它没有根据 docker ps -a 重新启动,它仍然退出:

[root@andromeda ~]# docker ps --all
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                        PORTS               NAMES
819d1264c30a        redis:alpine        "docker-entrypoint..."   3 minutes ago       Exited (137) 34 seconds ago                       keepalive_redis_1
Run Code Online (Sandbox Code Playgroud)

但是如果我重新启动守护进程......

[root@andromeda ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
819d1264c30a        redis:alpine        "docker-entrypoint..."   30 minutes ago      Up 2 seconds        6379/tcp            keepalive_redis_1
Run Code Online (Sandbox Code Playgroud)

设置了重启策略的容器再次启动,这就是文档所说的,所以 docker kill 不是你应该测试重启策略的方式,因为它假设你故意停止了容器并且 Docker 希望有一种方法来防止重启循环,如果你杀死它,你真的想杀死它。

我发现以下链接很有价值,它们在不同版本中显示相同的行为(因此这不是错误,而是预期的行为):