Docker原生健康检测机制
在docker-compose中加入healthcheck
healthcheck 支持下列选项:
test:健康检查命令,例如 ["CMD", "curl", "-f", "http://localhost/actuator/health"]
interval:健康检查的间隔,默认为 30 秒,单位(h/m/s);
timeout:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,单位(h/m/s);
retries:当连续失败指定次数后,则将容器状态视为 unhealthy。
和 CMD, ENTRYPOINT 一样,HEALTHCHECK 只可以出现一次,如果写了多个,只有最后一个生效。
start_period:应用启动期间的健康,检测不计入统计次数,但仍会发生检测。
HEALTHCHECK的CMD命令和其他CMD命令一样,支持SHELL和EXEC两种格式。命令的返回值有以下几种:
返回值 | 意义 |
---|---|
0 | healthy |
1 | unhealthy |
2 | 重试指定次数仍失败,容器将被认为unhealthy |
自动重启 unhealthy 容器
K8S提供了对Pod的健康状态检测,没有对Pod的单个容器进行健康检测机制,kubernetes提供了两类探针(Probe)来执行对Pod的健康状态检测:
LivenessProbe探针
用于判断容器是否存活,即Pod是否为running状态,如果LivenessProbe探针探测到容器不健康,则kubelet将kill掉容器,并根据容器的重启策略是否重启,如果一个容器不包含LivenessProbe探针,则Kubelet认为容器的LivenessProbe探针的返回值永远成功。
ReadinessProbe探针:
用于判断容器是否启动完成,即容器的Ready是否为True,可以接收请求,如果ReadinessProbe探测失败,则容器的Ready将为False,控制器将此Pod的Endpoint从对应的service的Endpoint列表中移除,从此不再将任何请求调度此Pod上,直到下次探测成功。
每类探针都支持三种探测方法:
exec:通过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康。
httpGet:通过发送http请求检查服务是否正常,返回200-399状态码则表明容器健康。tcpSocket:通过容器的IP和Port执行TCP检查,如果能够建立TCP连接,则表明容器健康。
但是对于不健康的容器Docker没有提供自动重启机制,GitHub上提供了一个Auto Heal容器可以保证自动重启本机上的unhealthy容器。Autoheal容器是一个独立的容器,它可以监控本机上的某一个容器或者所有容器,根据容器的健康状态来自动重启不健康的容器。
docker run -d --name autoheal --restart=always -e AUTOHEAL_CONTAINER_LABEL=all -v /var/run/docker.sock:/var/run/docker.sock willfarrell/autoheal
对于已经在项目中使用K8S或者Swarm来进行容器化编排的可以利用K8S提供探针来自动重启不在运行状态或者不具备对外提供服务的POD机制保证系统的高可用,减少系统的宕机时间,但是K8S只能检测Pod,不能提供对原生态的Docker容器检测,现在很多云服务提供商已经具备此能力。对于那些对系统宕机时间要求不是十分苛刻,并且也还没有用使用容器编排工具部署自己的系统的用户,使用auto heal也是一种经济方案,部署和运维都比较简单,但不具备自动扩容的能力,可以比较简单的保证单个容器不健康后自动恢复,减少系统的宕机时间,降低运维成本。