docker healthcheck with curl and wget
How to add a docker health check to test a tcp port is open?
printf "GET / HTTP/1.1\n\n" > /dev/tcp/127.0.0.1/9083
service:
build: ./service
...
healthcheck:
test: bash -c "exec 6<> /dev/tcp/localhost/80"
healthcheck:
test: "bash -c 'printf \"GET / HTTP/1.1\n\n\" > /dev/tcp/127.0.0.1/8080; exit $?;'"
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
docker和docker-compose 服务健康检测(healthcheck)_docker-compose healthcheck-CSDN博客
docker 的healthcheck产生的背景
docker 启动服务,容器里面变成UP了;但这时,还不能正常对外提供服务,对调用方表现是处于不可用状态,直接报错;
若业务线涉及组件比较多,都是这种启动方式,验证影响业务服务的SLA
docker 服务启动设置 healthcheck的目的
为了规避上面的风险,docker在v1.12版本后添加了healthcheck功能,这个功能可以自定义容器监控状态的检测标准。
healthcheck 参数说明
docker 官方文档 healthcheck部分
Dockerfile reference | Docker Documentation

-
healthcheck:
-
test: ["CMD-SHELL", "curl -sS 127.0.0.1:9200 || exit 1"] # 检测方式
-
interval: 1m30s # 多次检测间隔多久 (default: 30s)
-
timeout: 10s # 超时时间 (default: 30s)
-
retries: 3 # 尝试次数(default: 3)
-
start_period: 40s # 容器启动后多久开始检测 (default: 0s)
docker 支持的 healthcheck种类
Docker 支持以下几种 healthcheck 类型:
- CMD:
dockerfile
HEALTHCHECK CMD curl -f http://localhost/ || exit 1
使用 cURL 对服务指定 URL 进行检查。
- CMD-SHELL:
dockerfile
HEALTHCHECK CMD-SHELL "curl -f http://localhost/ || exit 1; echo healthy"
使用 Shell 脚本对服务进行检查。
- HTTP:
dockerfile
-
HEALTHCHECK --interval=30s --timeout=3s \
-
HTTP/1.1 GET /actors HTTP/1.1
使用 HTTP GET 请求指定 URL 对服务进行检查。
- TCP:
dockerfile
-
HEALTHCHECK --interval=5m --timeout=3s \
-
TCP/9200
通过连接指定端口,使用 TCP ping 对服务进行检查。
- NONE: 不进行任何健康检查。
举个例子:
HEALTHCHECK NONE
总的来说:
- CMD 和 CMD-SHELL 是最常用的两种方式,可以执行任意命令检查服务健康。
- HTTP 是使用 HTTP API 检查服务健康。
- TCP 是通过连接指定端口检查服务是否可达。
- NONE 不进行任何健康检查。
CMD 和 CMD-SHELL健康检查方式
CMD 和 CMD-SHELL 是最常用的两种健康检查方式
CMD 和 CMD-SHELL 在 HEALTHCHECK 命令中的区别:
• CMD:
- 使用 exec 执行
- 使用 /bin/sh -c 执行命令
- 只接收一条命令及其参数
• CMD-SHELL:
- 使用 shell 执行
- 多条命令需要使用 ; 分号隔开
- 可以使用 shell 的所有功能,如变量、循环等
举个例子:
CMD:
HEALTHCHECK CMD curl -f http://localhost/ || exit 1
CMD-SHELL:
HEALTHCHECK CMD-SHELL "curl -f http://localhost/ || exit 1; echo healthy"
相同的健康检查命令,CMD 版本只执行一条 curl 命令,CMD-SHELL 版本执行两条命令:
- curl 检查健康
- echo healthy 输出 healthy 字符串
总的来说:
- 如需执行简单的单条命令测量健康,使用 CMD
- 如需执行复杂 Shell 脚本来测量健康,使用 CMD-SHELL
Dockerfile和docker-compose 启动服务使用healthcheck 实战
Dockerfile 启动服务使用healthcheck 实战
在Dockerfile里定义镜像的healthcheck可以应用用基于这个镜像的所有容器
-
# healthcheck
-
HEALTHCHECK --interval=5s --timeout=5s \
-
CMD curl -sS 'http://localhost:9200' || exit 1
docker-compose 启动服务使用healthcheck 实战
在docker-compose里定义healthcheck 可以针对当前服务下的所有容器进行检测
-
healthcheck:
-
test: ["CMD-SHELL", "curl -sS 'http://localhost:9200' || exit 1"]
-
interval: 5s
-
timeout: 5s
-
retries: 6
docker-compose yaml文件中添加完healthcheck后,添加服务依赖
注意:condition属性仅适用于在version: '3.2'及以上版本的docker-compose中。
-
在depends_on中,可以通过添加一个condition属性来指定服务之间的启动条件。该condition属性可以接受三个值:
-
-
condition: service_started 表示在依赖的服务启动之后,才启动本服务;
-
condition: service_healthy 表示在依赖的服务健康检查通过之后,才启动本服务;
-
condition: service_completed_successfully 表示在依赖的服务成功执行之后,才启动本服务。
使用实战:
-
depends_on:
-
mysql:
-
condition: service_healthy
How to execute healthcheck without curl · Issue #58 · dart-lang/dart-docker
healthcheck:
#test: curl --fail -s http://127.0.0.1:80/healthcheck || exit 1
test: timeout 10s bash -c ':> /dev/tcp/127.0.0.1/80' || exit 1
interval: 30s
timeout: 15s
retries: 3
this script actually does it for me, works with usual bash:
#!/bin/bash
exec 3<>/dev/tcp/localhost/"$1"
echo -e "GET /path/to/health/endpoint/ HTTP/1.1
host: localhost:$1
" >&3
timeout 1 cat <&3 | grep status | grep UP || exit 1
of course you will have to alter the path to your health endpoint as well as the grep s to whatever you are looking for in a healthy status answer.
the way it works is by using this sentence to your advantage:
so by exec 3<>/dev/tcp/localhost/"$1" i am redirecting FD 3 to the specified port for the current shell.
more on this here: https://ceh51.blogspot.com/2016/07/how-to-open-tcpudp-sockets-bash-shell.html
you can use the script in your compose.yaml like so:
healthcheck:
test: [ 'CMD-SHELL', '/bin/bash -c "/path/to/healthcheck.sh 8081"' ]
...
How can I make a Docker healthcheck with wget instead of curl? - Stack Overflow
wget -nv -t1 --spider 'http://localhost:8000/
healthcheck:
test: wget -qO - localhost || exit 1


浙公网安备 33010602011771号