如何对 Docker 容器进行健康检查

熟悉使用过kubernetes的人应该知道,kubernetes支持对pod进行健康检查的功能,这对生产业务来说其实是非常有用处的,能快速发现服务不可用,并进行快速重启恢复。其实不使用kubernetes这种容器管理工具,docker自身也能实现对容器的健康检查。
从docker 1.12 版本之后,Docker 实现了原生的健康检查实现。对于容器而言,最简单的健康检查是进程级的健康检查,即检验进程是否存活。Docker Daemon 会自动监控容器中的 PID1 进程,如果 docker run 命令中指明了 restart policy,可以根据重启策略自动重启已结束的容器。但是在很多实际应用中,仅使用进程级健康检查方式还远远不够。比如,容器中进程虽然还在运行却由于其他种种原因无法继续响应用户请求(如应用死锁),这样的问题是无法通过进程级监控发现的。

容器启动之后,初始状态会为 starting (启动中)。Docker Engine 会等待 interval 时间,开始执行健康检查命令,并周期性执行。如果单次检查返回值非 0 或者运行需要比指定 timeout 时间还长,则本次检查被认为失败;如果健康检查连续失败超过了 retries 重试次数,状态就会变为 unhealthy (不健康)。

1) 过程中有一次健康检查成功,Docker 会将容器标记为healthy (健康)状态

2) 当容器的健康状态发生变化时,Docker Engine 会发出一个 health_status 事件。通过检查容器监控状态这里介绍以下三种方式

▍1、 docker run 方式

这种方式是在 docker run 命令中,直接指明 healthcheck 相关设置,该方法修改起来比较方便快捷,但是要求使用者对命令行使用比较熟练。

[root@k8s-m1 ~]# docker ps -l
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS                        PORTS     NAMES
80726f760696   nginx     "/docker-entrypoint.…"   About a minute ago   Up About a minute (healthy)   80/tcp    nginx-test
[root@k8s-m1 ~]#  docker run  -d --name=nginx-test --health-cmd="curl http://localhost/ || exit 1" --health-interval=5s --health-retries=6  --health-timeout=3s nginx

对命令行不熟悉的,可以通过执行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
功能失效

▍2、 Dockerfile 方式

可以在 Dockerfile 中通过使用HEALTHCHECK声明应用自身的健康检测配置。HEALTHCHECK配置了健康检测命令,用这个命令来判断容器主进程的服务状态是否正常,从而比较真实的反应容器实际运行状况。

HEALTHCHECK
指令格式:

  • HEALTHCHECK [选项] CMD <命令>
    设置检查容器健康状况的命令,注意CMD一直有
  • HEALTHCHECK NONE
    如果基础镜像有健康检查指令,可以通过该配置屏蔽

注 :和cmd、entrypoint一样,在 Dockerfile 中HEALTHCHECK只可以出现一次,如果写了多个,只有最后一个生效。
HEALTHCHECK 返回值,决定了该次健康检查的成功与否:0:成功;1:失败;2:保留(不要使用这个值)

使用包含HEALTHCHECK指令的 Dockerfile 构建出来的镜像,在实例化 Docker 容器的时候,就具备了健康状态检查的功能。启动容器后会自动进行健康检查。

参数说明:

HEALTHCHECK 支持下列选项:

  • --interval=<间隔>:两次健康检查的间隔,默认为 30 秒;
  • --timeout=<间隔>:健康检查命令运行超时时间,如果超过这个时间,本次健康检查就被视为失败,默认 30 秒;
  • --retries=<次数>:当连续失败指定次数后,则将容器状态视为 unhealthy,默认3次,如果正常的话好像会一直检查下去,可自行测试。
  • --start-period=<间隔>: 应用的启动的初始化时间,在启动过程中的健康检查失效不会计入,默认 0 秒,需要一定启动时间的服务最好设置;

假设有个镜像是个最简单的 nginx 服务,我们希望增加健康检查来判断其 nginx服务是否在正常工作,我们可以使用 curl 来帮助检查测试, Dockerfile 的HEALTHCHECK可以简单这么写:

[root@k8s-m1 ~]vim Dockerfile
FROM nginx
HEALTHCHECK --interval=5s --timeout=3s  CMD curl  http://localhost/ || exit 1[root@k8s-m1 ~]docker build -t nginx:v1 .
[root@k8s-m1 ~]docker run -d --name webtest -p 80:80 nginx:v1
[root@k8s-m1 ~]# docker ps -l
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS                            PORTS                NAMES
c4dcff064e99   nginx:v1   "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds (health: starting)   0.0.0.0:80->80/tcp   webtest
[root@k8s-m1 ~]# docker ps -l
CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS                   PORTS                NAMES
c4dcff064e99   nginx:v1   "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds (healthy)   0.0.0.0:80->80/tcp   webtest
[root@k8s-m1 ~]#

这里设置了每 5 秒检查一次,如果健康检查命令超过 3 秒没响应,并且重试 3 次都没响应就视为失败,并且使用curl http://localhost/ || exit 1,可以根据自己的业务自行调整检查命令。构建好后启动一个容器实例,看到最初的状态为(health: starting),在等待几秒钟后,再次docker ps -l,就可以看到健康状态变化为了(healthy)

当然如果健康检查连续失败超过了重试次数,状态就会变为(unhealthy)

为了帮助排障,健康检查命令的输出(包括stdout以及stderr)都会被存储于健康状态里,可以用 docker inspect来查看。

[root@k8s-m1 ~]#  docker inspect --format '{{json .State.Health}}' webtest | python -m json.tool
{"Status": "healthy","FailingStreak": 0,"Log": [{"Start": "2023-06-12T10:33:48.163431699+08:00","End": "2023-06-12T10:33:48.303906069+08:00","ExitCode": 0,"Output": "  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current\n                                 Dload  Upload   Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0\r100   615  100   615    0     0   600k      0 --:--:-- --:--:-- --:--:--  600k\n<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\nhtml { color-scheme: light dark; }\nbody { width: 35em; margin: 0 auto;\nfont-family: Tahoma, Verdana, Arial, sans-serif; }\n</style>\n</head>\n<body>\n<h1>Welcome to nginx!</h1>\n<p>If you see this page, the nginx web server is successfully installed and\nworking. Further configuration is required.</p>\n\n<p>For online documentation and support please refer to\n<a href=\"http://nginx.org/\">nginx.org</a>.<br/>\nCommercial support is available at\n<a href=\"http://nginx.com/\">nginx.com</a>.</p>\n\n<p><em>Thank you for using nginx.</em></p>\n</body>\n</html>\n"

▍3、 docker-composer 方式

在 docker-compose 中,可以使用以下方式来实现对容器的健康状况检查(下面以nginx为例,也可以参考Harbor的docker-compose文件):

version: '3'
services:myapp:image: nginxcontainer_name: healthcheckhealthcheck:test: ["CMD", "curl", "-fs", "http://localhost/"]interval: 6stimeout: 3sretries: 3

#设置初次检查等待6s,每次检查超时设置为3s,总共检查3次,如果3次都失败则判断为健康检查不通过。过程中有一次检查通过则判断为健康。

执行成功后,等待数秒查询容器的状态:

[root@k8s-m1 hewei]# docker ps -l
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS                            PORTS     NAMES
46e1d11e2431   nginx     "/docker-entrypoint.…"   3 seconds ago   Up 3 seconds (health: starting)   80/tcp    healthcheck
[root@k8s-m1 hewei]# docker ps -l
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS                            PORTS     NAMES
46e1d11e2431   nginx     "/docker-entrypoint.…"   6 seconds ago   Up 8 seconds (health: starting)   80/tcp    healthcheck[root@k8s-m1 hewei]# docker-compose  psName                  Command                  State       Ports
--------------------------------------------------------------------
healthcheck   /docker-entrypoint.sh ngin ...   Up (healthy)   80/tcp

更复杂的使用请自行探索,一般也很少单独使用。更多docker容器和运维方面的知识请前往博客主页。

如何对Docker容器进行健康检查相关推荐

  1. 如何优雅的对 Docker 容器进行健康检查

    公众号关注 「奇妙的 Linux 世界」 设为「星标」,每天带你玩转 Linux ! 自 1.12 版本之后,Docker 引入了原生的健康检查实现.对于容器而言,最简单的健康检查是进程级的健康检查, ...

  2. k8s探针检测php,K8S教程(7)使用探针对容器进行健康检查

    应用在运行过程不可避免会出现各种问题导致服务不可用的情况发生,K8S的Health Check健康检查机制可以对这些异常服务进行重启.剔除等操作,保障高可用. 一.K8S的健康检查探针 K8S的探针主 ...

  3. 极速体验docker容器健康

    本文目是体验docker容器的健康检查功能,以体验为主不涉及开发,与开发相关的内容会在后面的文章细说. 关于容器健康检查 考虑这样的情况:docker环境中,springboot应用的容器还在,但已无 ...

  4. Docker学习总结(28)——Docker 容器健康检查机制

    摘要: 在分布式系统中,经常需要利用健康检查机制来检查服务的可用性,防止其他服务调用时出现异常.自 1.12 版本之后,Docker 引入了原生的健康检查实现.本文将介绍Docker容器健康检查机制, ...

  5. Docker 容器健康检查机制

    摘要: 在分布式系统中,经常需要利用健康检查机制来检查服务的可用性,防止其他服务调用时出现异常.自 1.12 版本之后,Docker 引入了原生的健康检查实现.本文将介绍Docker容器健康检查机制, ...

  6. Docker Swarm 健康检查

    Docker Swarm 健康检查 文章目录 Docker Swarm 健康检查 1. 容器添加健康检查 2. 崩溃命令 3. 验证状态 4. 状态修复 5. swarm 运用 Healthcheck ...

  7. pod健康检查之容器的存活探针、就绪探针、启动探针

    前言 环境:centos7.9 docker-ce-20.10.9 kubernetes-version v1.22.6 为什么需要存活探针和就绪探针 在前面我们介绍过,可以通过配置restartPo ...

  8. Docker4.Docker容器运行、查看、启停、删除

    Docker4.Docker容器运行.查看.启停.删除 docker run:运行容器 常用选项参数 -p的四种方式 docker run -it:交互式进入容器 docker run -d:后台启动 ...

  9. Java应用在docker环境配置容器健康检查,如何保证消息队列的高可用

    改造java应用,提供/getstate接口服务,根据业务的实际情况决定当前应用是否健康,健康时返回码为200,不健康时返回码为403: 编译构建应用并且生成docker镜像: 验证: 制作基础镜像 ...

最新文章

  1. Python之数据聚合与分组运算
  2. Segment Routing — SRv6 — 统一的 SDN 控制面与数据面
  3. 转-OpenJDK源码阅读导航跟编译
  4. ajax调用上一个ajax,关于jquery:当频繁使用ajax请求调用函数时,如何在处理下一个请求之前等待上一个ajax请求完成?...
  5. Vector shrink 请求容器降低其容量和size匹配 shrink_to_fit();
  6. onmousedown活用之碰撞效果
  7. zynq文档学习之GPIO寄存器基本操作
  8. qq浏览文件服务器,腾讯浏览服务
  9. 【牛客网C++服务器项目学习】Day12-网络编程的两种事件处理模式
  10. ftw, nftw - file tree walk
  11. 试题 历届试题 回文数字
  12. 非线性规划的对偶问题
  13. vm linux安装增强功能,VirtualBox虚拟机CentOS安装增强功能Guest Additions(示例代码)
  14. 美国四大科技巨头:苹果、微软、Facebook、谷歌的爱恨情仇
  15. 8421BCD码的加6修正的原因
  16. 计量经济学(stata)笔记1 记录每天的进步
  17. 一个简单的猜数字游戏(附带关机惩罚)
  18. STM32触摸屏按下检测多次解决方案
  19. yoyo跑_yoyo主持人5岁女儿照片曝光 其老公魏哲浩个人资料简介
  20. python中find函数是什么意思_find函数什么意思

热门文章

  1. OpenCV每日函数 计算摄影模块(1) 图像修复算法 inpaint函数
  2. 软件测试-如何准备测试数据
  3. java operate_java中的operate(x); 是个是么样的函数,功能是什么,在哪里可以连接它的机制啊??...
  4. Adobe正版软件购买
  5. 基于ENVI软件进行图像归一化操作
  6. Laravel dcat-admin 用户头像显示不出的原因及解决方法
  7. java计算机毕业设计钢材出入库管理系统源码+mysql数据库+系统+lw文档+部署
  8. tcpip协议与服务器的关系,RS232转TCPIP的TCP工作模式选择
  9. 创维E900-S-普通版-MV100纯净通刷_卡刷固件包
  10. gshhs matlab,科学网—Matlab 利用m_map加国界线 - 肖鑫的博文