Docker 禁用失败时重启
Docker disable restart on-failure
以下情况:
- 我有一个 Spring 启动应用程序
- 在 Docker 集群中运行
- 但未能启动,因为它没有正确配置(缺少 属性)。
- 在我看来,docker swarm 总是试图重启容器,但总是因为缺少 属性 而失败。
- 重新启动没有意义,因为 docker 将永远无法启动应用程序,除非我修复丢失的 属性。
- 所以目前群以无限循环结束。
关于这个问题我已经看过了:
- docker 文档:https://docs.docker.com/config/containers/start-containers-automatically/
- 和几个 Whosebug 帖子:https://whosebug.com/search?q=Docker+restart
我的"setup":
docker 文件:
ARG nexus_docker_registry=mynexus.com:10099
FROM ${nexus_docker_registry}/openjdk:8-jdk-alpine
ADD myjar.jar myjar.jar
ENV JAVA_OPTS=""
ENTRYPOINT [ "java", "-jar", "/myjar.jar" ]
我的 YML 文件创建 docker 服务:
---
- hosts: docker_manager
become: false
vars:
servicename: 'myservice'
imageurl: "mynexus.com:10099/myjar:{{version}}"
extraoptions:
- "--with-registry-auth"
- "--detach=true"
- "--log-driver gelf"
- "--log-opt 'gelf-address=udp://{{ groups['logstash'][0] }}:10001'"
- "--hostname 'myhost.com'"
- "--mount 'type=bind,source=/etc/localtime,destination=/etc/localtime:ro'"
- "--mount 'type=volume,source=mykeys,destination=/mykeys'"
- "--env 'spring.profiles.active=docker'"
- "--publish 8000:6666"
tasks:
- name: Include vault
include_vars: "myvault.yml"
- name: "delete service '{{ servicename }}'"
command: sudo docker service rm "{{ servicename }}"
args:
warn: false
ignore_errors: true
run_once: true
- name: "create service {{ servicename }}"
command: sudo docker service create {{ extraoptions | join( ' ' ) }} --name "{{ servicename }}" "{{ imageurl }}"
args:
warn: false
run_once: true
我要实现的是:
- 如果 spring 引导应用程序由于
BeanCreationException
或类似的原因而无法启动,那么我不希望 docker 服务无休止地重新启动。
- 如果我重新启动 swarm 等,docker 服务应该会自动重新启动。
在docker文档中写道:
If you manually stop a container, its restart policy is ignored until the Docker daemon restarts or the container is manually restarted. This is another attempt to prevent a restart loop.
所以我想我想通过重启策略实现的目标是不可能的。
问题:
- 但也许我可以在
Dockerfile
中写一些我实现目标的东西?
- 还是我完全错了,误解了文档?
不幸的是,我不是 docker 专家,并且仍在学习处理 'the swarm'。
Docker中有4个不同的restart policies:
no
- 不要自动重启容器。 (默认)
on-failure
- 如果容器因错误退出(表现为非零退出代码),请重新启动容器。
always
- 如果容器停止,总是重启容器
unless-stopped
- 与 always 类似,除了当容器停止(手动或其他方式)时,即使在 Docker 守护程序重新启动后它也不会重新启动。
docker无法"detect"来自应用程序的错误类型并根据该类型重新启动或不重新启动。
实现此目的的一种方法是在您的容器中使用 supervisord 并让它根据您定义的退出代码列表处理重启。但这意味着您的容器只会在 supervisord 崩溃时重新启动,而不是在您的应用程序崩溃时重新启动,并且您必须将代码更改为 return 不同的退出代码,以应对应该重新启动的错误和不应该重新启动的错误.
因为我想要实现的目标似乎不可能,我再次阅读了文档 (https://docs.docker.com/engine/reference/commandline/service_create/) 并找到了选项 --restart-max-attempts
这将解决我的无限循环问题。
您可能想要尝试创建一个基于 docker-compose 文件的 docker stack
。
在这种情况下,如 compose v3 documentation 所示,您可以完全控制服务重启策略。
下一个示例将不允许重新启动:
version: "3.9"
services:
python:
image: my_user/my_repo:my_container
volumes:
- /home/python:/home
deploy:
restart_policy:
condition: none
您可以使用 condition: [none | on-failure | any]
和 max_attempts: [your_int]
调整 restart_policy
块
以下情况:
- 我有一个 Spring 启动应用程序
- 在 Docker 集群中运行
- 但未能启动,因为它没有正确配置(缺少 属性)。
- 在我看来,docker swarm 总是试图重启容器,但总是因为缺少 属性 而失败。
- 重新启动没有意义,因为 docker 将永远无法启动应用程序,除非我修复丢失的 属性。
- 所以目前群以无限循环结束。
关于这个问题我已经看过了:
- docker 文档:https://docs.docker.com/config/containers/start-containers-automatically/
- 和几个 Whosebug 帖子:https://whosebug.com/search?q=Docker+restart
我的"setup": docker 文件:
ARG nexus_docker_registry=mynexus.com:10099
FROM ${nexus_docker_registry}/openjdk:8-jdk-alpine
ADD myjar.jar myjar.jar
ENV JAVA_OPTS=""
ENTRYPOINT [ "java", "-jar", "/myjar.jar" ]
我的 YML 文件创建 docker 服务:
---
- hosts: docker_manager
become: false
vars:
servicename: 'myservice'
imageurl: "mynexus.com:10099/myjar:{{version}}"
extraoptions:
- "--with-registry-auth"
- "--detach=true"
- "--log-driver gelf"
- "--log-opt 'gelf-address=udp://{{ groups['logstash'][0] }}:10001'"
- "--hostname 'myhost.com'"
- "--mount 'type=bind,source=/etc/localtime,destination=/etc/localtime:ro'"
- "--mount 'type=volume,source=mykeys,destination=/mykeys'"
- "--env 'spring.profiles.active=docker'"
- "--publish 8000:6666"
tasks:
- name: Include vault
include_vars: "myvault.yml"
- name: "delete service '{{ servicename }}'"
command: sudo docker service rm "{{ servicename }}"
args:
warn: false
ignore_errors: true
run_once: true
- name: "create service {{ servicename }}"
command: sudo docker service create {{ extraoptions | join( ' ' ) }} --name "{{ servicename }}" "{{ imageurl }}"
args:
warn: false
run_once: true
我要实现的是:
- 如果 spring 引导应用程序由于
BeanCreationException
或类似的原因而无法启动,那么我不希望 docker 服务无休止地重新启动。 - 如果我重新启动 swarm 等,docker 服务应该会自动重新启动。
在docker文档中写道:
If you manually stop a container, its restart policy is ignored until the Docker daemon restarts or the container is manually restarted. This is another attempt to prevent a restart loop.
所以我想我想通过重启策略实现的目标是不可能的。
问题:
- 但也许我可以在
Dockerfile
中写一些我实现目标的东西? - 还是我完全错了,误解了文档?
不幸的是,我不是 docker 专家,并且仍在学习处理 'the swarm'。
Docker中有4个不同的restart policies:
no
- 不要自动重启容器。 (默认)on-failure
- 如果容器因错误退出(表现为非零退出代码),请重新启动容器。always
- 如果容器停止,总是重启容器unless-stopped
- 与 always 类似,除了当容器停止(手动或其他方式)时,即使在 Docker 守护程序重新启动后它也不会重新启动。
docker无法"detect"来自应用程序的错误类型并根据该类型重新启动或不重新启动。
实现此目的的一种方法是在您的容器中使用 supervisord 并让它根据您定义的退出代码列表处理重启。但这意味着您的容器只会在 supervisord 崩溃时重新启动,而不是在您的应用程序崩溃时重新启动,并且您必须将代码更改为 return 不同的退出代码,以应对应该重新启动的错误和不应该重新启动的错误.
因为我想要实现的目标似乎不可能,我再次阅读了文档 (https://docs.docker.com/engine/reference/commandline/service_create/) 并找到了选项 --restart-max-attempts
这将解决我的无限循环问题。
您可能想要尝试创建一个基于 docker-compose 文件的 docker stack
。
在这种情况下,如 compose v3 documentation 所示,您可以完全控制服务重启策略。
下一个示例将不允许重新启动:
version: "3.9"
services:
python:
image: my_user/my_repo:my_container
volumes:
- /home/python:/home
deploy:
restart_policy:
condition: none
您可以使用 condition: [none | on-failure | any]
和 max_attempts: [your_int]
restart_policy
块