共计 4064 个字符,预计需要花费 11 分钟才能阅读完成。
如何优雅的对 Docker 容器进行健康检查
自 1.12 版本之后,Docker 引入了原生的健康检查实现。对于容器而言,最简略的健康检查是过程级的健康检查,即测验过程是否存活。Docker Daemon 会主动监控容器中的 PID1 过程,如果 docker run 命令中指明了 restart policy,能够依据策略主动重启已完结的容器。在很多理论场景下,仅应用过程级健康检查机制还远远不够。比方,容器过程尽管仍旧运行却因为利用死锁无奈持续响应用户申请,这样的问题是无奈通过过程监控发现的。
容器启动之后,初始状态会为 starting (启动中)。Docker Engine 会期待 interval 工夫,开始执行健康检查命令,并周期性执行。如果单次查看返回值非 0 或者运行须要比指定 timeout 工夫还长,则本次查看被认为失败;如果健康检查间断失败超过了 retries 重试次数,状态就会变为 unhealthy (不衰弱)。
注:
- 一旦有一次健康检查胜利,Docker 会将容器置回 healthy (衰弱)状态
- 当容器的衰弱状态发生变化时,Docker Engine 会收回一个 health_status 事件。通过查看容器监控状态有以下两种形式
1. Dockerfile 形式
能够在 Dockerfile 中申明利用本身的衰弱检测配置。HEALTHCHECK 指令申明了衰弱检测命令,用这个命令来判断容器主过程的服务状态是否失常,从而比拟实在的反馈容器理论状态。
HEALTHCHECK 指令格局:
- HEALTHCHECK [选项] CMD < 命令 >:设置查看容器健康状况的命令
- HEALTHCHECK NONE:如果根底镜像有健康检查指令,应用这行能够屏蔽掉
注:在 Dockerfile 中 HEALTHCHECK 只能够呈现一次,如果写了多个,只有最初一个失效。
应用蕴含 HEALTHCHECK 指令的 Dockerfile 构建进去的镜像,在实例化 Docker 容器的时候,就具备了衰弱状态查看的性能。启动容器后会主动进行健康检查。
参数参考:
https://docs.docker.com/engin…
HEALTHCHECK 反对下列选项:
- –interval=< 距离 >:两次健康检查的距离,默认为 30 秒;
- –timeout=< 距离 >:健康检查命令运行超时工夫,如果超过这个工夫,本次健康检查就被视为失败,默认 30 秒;
- –retries=< 次数 >:当间断失败指定次数后,则将容器状态视为 unhealthy,默认 3 次。
- –start-period=< 距离 >: 利用的启动的初始化工夫,在启动过程中的健康检查生效不会计入,默认 0 秒;
参数作用解释如下:
运行状态查看首先会在容器启动后的 interval 秒内运行,而后在前一次查看实现后的 interval 秒内再次运行。
如果一次状态查看破费的工夫超过 timeout 秒,则认为这次查看失败。
容器的运行状态查看间断失败 retries 次才会被视为不衰弱。
start period 为须要工夫启动的容器提供初始化工夫。在此期间的探测失败将不计入最大重试次数。
然而,如果在启动期间健康检查胜利,则认为容器已启动,所有间断失败的状况都将计算到最大重试次数。
在 HEALTHCHECK [选项] CMD 前面的命令,格局和 ENTRYPOINT 一样,分为 shell 格局,和 exec 格 式。命令的返回值决定了该次健康检查的胜利与否:
- 0:胜利;
- 1:失败;
- 2:保留值,不要应用
假如有个镜像是个最简略的 Web 服务,咱们心愿减少健康检查来判断其 Web 服务是否在失常工作,咱们能够用 curl 来帮忙判断,其 Dockerfile 的 HEALTHCHECK 能够这么写:
FROM nginx:1.23
HEALTHCHECK --interval=5s --timeout=3s --retries=3 \
CMD curl -fs http://localhost/ || exit 1
这里设置了每 5 秒查看一次(这里为了试验所以距离十分短,理论应该绝对较长),如果健康检查命令超过 3 秒没响应,并且重试 3 次都没响应就视为失败,并且应用 curl -fs http://localhost/ || exit 1 作为健康检查命令。
应用 docker build 来构建这个镜像:
docker build -t myweb:v1 .
构建好后启动容器:
docker run -d --name web myweb:v1
当运行该镜像后,能够通过 docker container ls 看到最后的状态为(health: starting):
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7068d793c6e4 myweb:v1 "/docker-entrypoint.…" 3 seconds ago Up 2 seconds (health: starting) 80/tcp web
在期待几秒钟后,再次 docker container ls,就会看到衰弱状态变动为了(healthy):
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7068d793c6e4 myweb:v1 "/docker-entrypoint.…" 18 seconds ago Up 16 seconds (healthy) 80/tcp web
如果健康检查间断失败超过了重试次数,状态就会变为 (unhealthy)。
为了帮忙排障,健康检查命令的输入(包含 stdout 以及 stderr)都会被存储于衰弱状态里,能够用 docker inspect 来查看。
$ docker inspect --format '{{json .State.Health}}' web | python -m json.tool
{
"FailingStreak": 0,
"Log": [
{
"End": "2022-08-20T14:02:38.19224648+08:00",
"ExitCode": 0,
"Output": "xxx",
"Start": "2022-08-20T14:02:38.116041192+08:00"
},
{
"End": "2022-08-20T14:02:43.271105619+08:00",
"ExitCode": 0,
"Output": "xxx",
"Start": "2022-08-20T14:02:43.200932585+08:00"
}
],
"Status": "healthy"
}
2. docker run 形式
另外一种办法是在 docker run 命令中,间接指明 healthcheck 相干策略:
$ docker run -d \
--name=myweb \
--health-cmd="curl -fs http://localhost/ || exit 1" \
--health-interval=5s \
--health-retries=12 \
--health-timeout=2s \
nginx:1.23
通过执行 docker run –help | grep health 命令查看相干的参数及解释如下:
- –health-cmd string:运行查看健康状况的命令
- –health-interval duration:运行间隔时间(ms|s|m|h)(缺省为 0s)
- –health-retries int:须要报告不衰弱的间断失败次数
- –health-start-period duration:容器在开始衰弱重试倒计时之前初始化的起始周期(ms|s|m|h)(默认 0)
- –health-timeout duration:容许一次查看运行的最大工夫(ms|s|m|h)(默认为 0s)
-
–no-healthcheck:禁用任何容器指定的 HEALTHCHECK,会使得 Dockerfile 构建进去的 HEALTHCHECK 性能生效。
如果是以 supervisor 来治理容器的多个服务,想通过子服务的状态来判断容器的监控状态,能够应用 supervisorctl status 来做判断,比方:$ docker run --rm -d \ --name=myweb \ --health-cmd="supervisorctl status" \ --health-interval=5s \ --health-retries=3 \ --health-timeout=2s \ nginx:v1
依照此参数的设置,如果 supervisorctl status 查看子服务有一个不为失常的 RUNNING 状态,那么在期待大概 15 秒左右,容器的监控状态就会从 (healthy) 变为(unhealthy)
3. docker-composer 形式
在 docker-composer 中,能够应用以下形式来实现对容器的健康状况查看(以通过 supervisor 治理子过程的容器为例):
version: '3'
services:
web:
image: nginx:v1
container_name: web
healthcheck:
test: ["CMD", "supervisorctl", "status"]
interval: 5s
timeout: 2s
retries: 3
执行胜利后,期待数秒查问容器的状态:
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------
web supervisord -c /etc/superv ... Up (healthy) 443/tcp, 80/tcp
当通过手动 supervisorctl stop 停掉外面的一些子服务,导致外面的子服务状态不全为 RUNNING 状态时,再查看容器的状态:
healthcheck:
disable: true
本文转载自:「seafog 的博客」,原文:https://url.hi-linux.com/mgvKJ,版权归原作者所有。
本文由 mdnice 多平台公布