docker compose服务依赖和健康检查
准备环境

容器本身有一个健康检查的功能,但是需要在Dockerfile
里定义,或者在执行docker run
的时候,通过下面的一些参数指定。
--health-cmd string Command to run to check health
--health-interval duration Time between running the check (ms|s|m|h) (default 0s)
--health-retries int Consecutive failures needed to report unhealthy
--health-start-period duration Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)
--health-timeout duration Maximum time to allow one check to
在Dockerfile
中定义了一个健康检查。 会每隔30秒检查一次,如果失败就会退出,退出代码是1
。
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:5000/ || exit 1
然后执行下面的步骤。
先单独启动
flask
容器,触发健康检查机制。再启动Redis服务,让
flask
能够正常访问。
可以查看容器详情中有有关health
的部分。
> docker inspect flask
"Health": {
"Status": "starting",
"FailingStreak": 1,
"Log": [
{
"Start": "2021-07-14T19:04:46.4054004Z",
"End": "2021-07-14T19:04:49.4055393Z",
"ExitCode": -1,
"Output": "Health check exceeded timeout (3s)"
}
]
}
经过3次检查,如果一直不通的话,health
的状态会从starting
变为unhealthy
。
> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
059c12486019 flask-demo "flask run -h 0.0.0.0" 4 hours ago Up 2 minutes (unhealthy) 5000/tcp flask
启动Redis,连到mybridge
上,name=redis
,经过几秒钟后flask
变成了healthy
。
> docker run -d --network mybridge --name redis redis:latest redis-server --requirepass abc123
> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc4e826ee938 redis:latest "docker-entrypoint.s…" 18 seconds ago Up 16 seconds 6379/tcp redis
059c12486019 flask-demo "flask run -h 0.0.0.0" 4 hours ago Up 6 minutes (healthy) 5000/tcp flask
通过Docker Compose也可实现健康检查,而且还能设置检查条件。
version: "3.8"
services:
flask:
......
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000"]
interval: 30s
timeout: 3s
retries: 3
start_period: 40s
depends_on:
redis-server:
condition: service_healthy # 只有当redis服务的状态是healthy时才启动flask
......
redis-server:
image: redis:latest
command: redis-server --requirepass ${REDIS_PASSWORD}
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 3s
retries: 30
......
nginx:
......
flask:
condition: service_healthy # 只有当flask服务状态是healthy时才启动nginx
......
从以上代码中可以看出。
Docker Compose会首先启动Redis服务容器。
只有当Redis服务的状态是
healthy
时才启动flask
。只有当
flask
服务状态是healthy
时才启动Nginx。
也就是实现了如下的健康状态
依赖关系。
依赖于flask的健康状态 依赖于redis的健康状态
nginx ————————————————————————————> flask ————————————————————————————> redis
healthcheck
支持下列选项。
test
:健康检查命令,例如["CMD", "curl", "-f", "http://localhost/healthcheck"]
。interval
:健康检查的间隔,默认为30
秒,单位(h/m/s)。timeout
:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,单位(h/m/s)。retries
:当连续失败指定次数后,则将容器状态视为unhealthy
。start_period
:应用启动期间的健康,检测不计入统计次数,但仍会发生检测。
和CMD
、ENTRYPOINT
一样,healthcheck
只可以出现一次,如果写了多个,那么只有最后一个生效。
在depends_on
中,可以通过添加一个condition
属性来指定服务之间的启动条件,该属性接受三个值。
service_started
:表示在依赖的服务启动之后,才启动本服务。service_healthy
:表示在依赖的服务健康检查通过之后,才启动本服务。service_completed_successfully
:表示在依赖的服务成功执行之后,才启动本服务。
官方给出的Docker Compose学习资源。
感谢支持
更多内容,请移步《超级个体》。