docker容器的健康状态监控功能healthcheck实践补充

之前在论坛上发过一个求助贴:

求助,我参考git hub 项目xxproject做容器化部署,中间有双eureka高可用,但是eureka始终处于health:starting状态,从浏览器能访问到eureka控制台,证明已经启动,但容器状态就是不变成healthy,打日志发现eureka除了一直在同步状态外,没有任何异常。

求指点
1容器健康状态转化的机制和标志
2针对我遇到的问题,如何解决

这个贴子没有得到回答。关于容器的健康状态,找到了两篇文章,算是说明白了问题:

https://blog.csdn.net/CloudMan6/article/details/78827984

容器状态是 UP 的,应用就是健康的吗?

还真不一定!
Docker 只能从容器启动进程的返回代码判断其状态,而对于容器内部应用的运行情况基本没有了解。

执行 docker run 命令时,通常会根据 Dockerfile 中的 CMD 或 ENTRYPOINT 启动一个进程,这个进程的状态就是 docker ps STATUS 列显示容器的状态。
549.png

 

命令显示:

    有的容器正在运行,状态为 UP。

    有的容器已经正常停止了,状态是 Exited (0)。

    有的则因发生故障停止了,退出代码为非 0,例如 Exited (137)、Exited (1) 等。

即使容器状态是 UP,也不能保证应用没有问题。web server 虽然没有崩溃,但如果总是返回 HTTP 500 - Internal Server Error ,对应用来说这就是很严重的故障。

如何从应用的业务层面检查容器的状态呢? 答案是:Health Check。

Docker 支持的 Health Check 可以是任何一个单独的命令,Docker 会在容器中执行该命令,如果返回 0,容器被认为是 healthy,如果返回 1,则为 unhealthy。

对于提供 HTTP 服务接口的应用,常用的 Health Check 是通过 curl 检查 HTTP 状态码,比如:

curl --fail http://localhost:8080/ || exit 1

如果 curl 命令检测到任何一个错误的 HTTP 状态码,则返回 1,Health Check 失败。
 

 

https://blog.csdn.net/ksj367043706/article/details/88777604

 healthcheck命令执行的结果有以下几种:

    0: success - the container is healthy and ready for use,容器成功运行,状态健康
    1: unhealthy - the container is not working correctly,容器启动异常
    2: reserved - do not use this exit code,未使用

 

但是,按照第一篇文章以及网上其他文章示例,将healthcheck中执行的命令改为curl,在容器外自己执行是没有问题,但是eureka容器启动后的状态依然始终卡在health:starting状态。
因此有了这样一个疑问:

healthcheck中指定的指令,是在容器内执行的还是容器外执行的?

各位还真不要以为这个问题显而易见。因为查了CSDN和网上许多文章,包括docker-compose.yaml官网的文档,都没有提及这个问题。

那么,或者是官方和各位高手都认为这个问题显而易见,或者是天下文章一大抄,各路教程都是转来转去,没有实际操作过。

纸上得来终学浅,在实践中遇到坑,才能真正解决生产实践工程中的问题。

基于这个思路,在启动eureka容器后,我用docker exec -it xxxx /bin/bash,进入容器内,然后执行curl...指令,返回找不到此命令错误,执行示例项目healthcheck中指定的指令,虽然出错,但至少有这个指令。

由此可知:healthcheck中的指令在容器内执行,所以必须是容器内有的指令。也就是说,健康检测探针要打包在容器内。
总结:

1.容器的健康状态取决于healthcheck命令执行的结果。

2.healthcheck执行的命令在容器内执行。

3.很多容器内置了curl作为探针,但有些容器就是没内置。

纸上得来终觉浅,亲自操作才对容器健康检测有了真切的理解。

另外关于health-cmd Health Check 的命令,还有几个相关的参数:

    --timeout 命令超时的时间,默认 30s。

    --interval 命令执行的间隔时间,默认 30s。

    --retries 命令失败重试的次数,默认为 3,如果 3 次都失败了则会将容器标记为 unhealthy。
这里需要注意的是,timeout和interval指定的参数一定要有单位,不能只写数字,即s/m不能省略。这也是实践出来的知识点。

 

 

下面是这两篇文章原文,记下来做为备忘。

 

docker容器的健康状态监控功能healthcheck

2019年03月24日 16:12:39 ksj367043706 阅读数 157

博客作为学习笔记记录,若有理解,表述错误,欢迎指出。

healthcheck是docker1.12版本引入的新功能,用于容器健康状态监测

暂时k8s不支持docker的healthcheck功能,k8s由其之前就提供的liveness和readiness功能来实现healthcheck,docker引入healthcheck功能,估计也是向k8s学习的。

 

docker 的healthcheck

设置选项

  • --interval=DURATION (default: 30s),间隔
  • --timeout=DURATION (default: 30s), 超时时间
  • --start-period=DURATION (default: 0s),初始化时间

          说明:在此期间的探测失败将不计入最大重试次数。但是,如果健康检查在启动期间成功,则认为容器已启动,所有连续的失败都将计入最大重试次数。

  • --retries=N (default: 3),当连续失败指定次数后,容器状态会变成unhealthy

格式:HEALTHCHECK [选项] CMD(分成shell格式和exec格式)。

如果有多个指令,则最后一个生效。

输出: healthcheck命令执行的结果有以下几种:

  • 0: success - the container is healthy and ready for use,容器成功运行,状态健康
  • 1: unhealthy - the container is not working correctly,容器启动异常
  • 2: reserved - do not use this exit code,未使用

 

举个栗子:

用curl来判断web服务是否正常,在dockerfile中定义healthcheck:

 
  1. FROM nginx

  2. RUN apt-get update && apt-get

  3. install -y curl && rm -rf /var/lib/apt/lists/*

  4. HEALTHCHECK --interval=5s --timeout=3s \

  5.   CMD curl -fs http://localhost/ || exit 1

刚运行容器时,容器状态为health:starting

 
  1. $ docker container ls

  2. CONTAINER ID        IMAGE               COMMAND                  CREATED           STATUS                            PORTS               NAMES

  3. 03e28eb00bd0        myweb:v1            "nginx -g 'daemon off"  3 seconds ago       Up 2 seconds (health: starting)  80/tcp, 443/tcp     web

过几秒之后,状态会变成healthy

 
  1. $ docker container ls

  2. CONTAINER ID        IMAGE               COMMAND                  CREATED            STATUS                    PORTS               NAMES

  3. 03e28eb00bd0        myweb:v1            "nginx -g 'daemon off"  18 seconds ago      Up 16 seconds (healthy)   80/tcp, 443/tcp     web

健康指令的输出结果会存储在健康状态里,可以用docker inspect来查看,eg:

$ docker inspect --format '{{json .State.Health}}' web | python -m json.tool
 
  1. #输出为:

  2. {

  3.     "FailingStreak": 0,

  4.     "Log": [

  5.         {

  6.             "End": "2016-11-25T14:35:37.940957051Z",

  7.             "ExitCode": 0,

  8.             "Output": "

  9. html>\n\n\nWelcome to</code></p> </li> <li> <p><code>nginx!\n\n\n\n

    Welcome to

  10. nginx!\n

    If you see this page, the nginx web server is

  11. successfully installed and\nworking. Further configuration is

  12. required.

    \n\n

    For online documentation and support please

  13. refer to\nnginx.org.
    \nCommercial

  14. support is available at\n

  15. href=\"http://nginx.com/\">nginx.com.

    \n\n

    Thank

  16. you for using nginx.

    \n\n\n",

  17.             "Start":

  18. "2016-11-25T14:35:37.780192565Z"

  19.         }

  20.     ],

  21.     "Status": "healthy"

  22. }

  

REF:

https://docker_practice.gitee.io/image/dockerfile/healthcheck.html

https://docs.docker.com/engine/reference/builder/

 

https://docker_practice.gitee.io/image/dockerfile/healthcheck.html

https://docs.docker.com/engine/reference/builder/

你可能感兴趣的:(容器)