我有一个包含 PostgreSQL 和我的应用程序的 docker compose 文件,如下所示:
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"
问题是,restart: always
当我杀死容器(使用模拟应用程序崩溃)时,策略似乎不起作用,docker kill
并且docker-compose不会重新启动我的容器,即使退出代码为 137。当我使用策略时,我观察到了相同的行为restart: on-failure
。docker-compose 的版本2
和3
行为相同。我的系统是 Ubuntu Server 16.04 x64。
我的问题是:
- 为什么 docker-compose 不重新启动崩溃(终止)的容器?
- 如何检查重启策略是否有效?
答案1
当您使用 docker kill 时,这是预期的行为,因为 Docker 不会重新启动容器:“如果您手动停止容器,则其重新启动策略将被忽略,直到 Docker 守护程序重新启动或手动重新启动容器。这是另一种防止重启循环的尝试”(参考)
如果您使用 docker stop 或 docker kill,则表示您手动停止容器。您可以对重启策略进行一些测试:重启 docker 守护进程、重启服务器、在容器内使用 CMD 并运行 exit...
例如,如果我使用重启策略终止部署的容器,我会看到它以代码 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
但如果我重新启动守护进程……
[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
设置了重启策略的容器会再次启动,正如文档所说,所以 docker kill 不是您测试重启策略的方式,因为它假定您已经故意停止了容器,并且 Docker 希望有一种方法可以防止重启循环,如果您杀死它,您真的想杀死它。
我发现以下链接很有价值,它们显示了不同版本中的相同行为(因此这不是错误而是预期的行为):