# 创建容器配置健康检查<a name="ZH-CN_TOPIC_0184808228"></a>

Docker提供了用户定义的对容器进行健康检查的功能。在Dockerfile中配置HEALTHCHECK CMD选项，或在容器创建时配置--health-cmd选项，在容器内部周期性地执行命令，通过命令的返回值来监测容器的健康状态。

## 配置方法<a name="zh-cn_topic_0182302402_section20733184718277"></a>

-   在Dockerfile中添加配置，如：

    ```
    HEALTHCHECK --interval=5m --timeout=3s --health-exit-on-unhealthy=true \
       CMD curl -f http://localhost/ || exit 1
    ```

    可配置的选项：

    1.  --interval=DURATION，默认 30s，相邻两次命令执行的间隔时间。另外，容器启动后，经过interval时间进行第一次检查。
    2.  --timeout=DURATION，默认 30s，单次检查命令执行的时间上限，超时则任务命令执行失败。
    3.  --start-period=DURATION，默认 0s，容器初始化时间。初始化期间也会执行健康检查，健康检查失败不会计入最大重试次数。但是，如果在初始化期间运行状况检查成功，则认为容器已启动。之后所有连续的检查失败都将计入最大重试次数。
    4.  --retries=N，默认 3，健康检查失败最大的重试次数。
    5.  --health-exit-on-unhealthy=BOOLEAN，默认false，检测到容器非健康时是否杀死容器
    6.  CMD，必选，在容器内执行的命令。返回值为0表示成功，非0表示失败。

        在配置了HEALTHCHECK后创建镜像，HEALTHCHECK相关配置会被写入镜像的配置中。通过docker inspect可以看到。如：

        ```
        "Healthcheck": {
            "Test": [
                "CMD-SHELL",
                "/test.sh"
            ]
        },
        ```


-   在容器创建时的配置：

    ```
    docker run -itd --health-cmd "curl -f http://localhost/ || exit 1" --health-interval 5m --health-timeout 3s --health-exit-on-unhealthy centos bash
    ```

    可配置的选项：

    1.  --health-cmd，必选，在容器内执行的命令。返回值为0表示成功，非0表示失败。
    2.  --health-interval，默认 30s，最大为int64上限（纳秒）相邻两次命令执行的间隔时间。
    3.  --health-timeout，默认 30s，最大为int64上限（纳秒），单次检查命令执行的时间上限，超时则任务命令执行失败。
    4.  --health-start-period，默认 0s，最大为int64上限（纳秒），容器初始化时间。
    5.  --health-retries，默认 3，最大为int32上限，健康检查失败最大的重试次数。
    6.  --health-exit-on-unhealthy，默认false，检测到容器非健康时是否杀死容器。

        容器启动后，HEALTHCHECK相关配置会被写入容器的配置中。通过docker inspect可以看到。如：

        ```
        "Healthcheck": {
            "Test": [
                "CMD-SHELL",
                "/test.sh"
            ]
        },
        ```



## 检查规则<a name="zh-cn_topic_0182302402_section11838258122711"></a>

1.  容器启动后，容器状态中显示health:starting。
2.  经过start-period时间后开始，以interval为间隔周期性在容器中执行CMD。即：当一次命令执行完毕后，经过interval时间，执行下一次命令。
3.  若CMD命令在timeout限制的时间内执行完毕，并且返回值为0，则视为一次检查成功，否则视为一次检查失败。检查成功后，容器状态变为health:healthy。
4.  若CMD命令连续retries次检查失败，则容器状态变为health:unhealthy。失败后容器也会继续进行健康检查。
5.  容器状态为health:unhealthy时，任意一次检查成功会使得容器状态变为health:healthy。
6.  设置--health-exit-on-unhealthy的情况下，如果容器因为非被杀死退出（退出返回值137）后，健康检查只有容器在重新启动后才会继续生效。
7.  CMD执行完毕或超时时，docker daemon会将这次检查的起始时间、返回值和标准输出记录到容器的配置文件中。最多记录最新的5条数据。此外，容器的配置文件中还存储着健康检查的相关参数。

通过docker ps可以看到容器状态。

```
[root@bac shm]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                         PORTS               NAMES
7de2228674a2        testimg             "bash"              About an hour ago   Up About an hour (unhealthy)                       cocky_davinci
```

运行中的容器的健康检查状态也会被写入容器配置中。通过docker inspect可以看到。

```
"Health": {
    "Status": "healthy",
    "FailingStreak": 0,
    "Log": [
        {
            "Start": "2018-03-07T07:44:15.481414707-05:00",
            "End": "2018-03-07T07:44:15.556908311-05:00",
            "ExitCode": 0,
            "Output": ""
        },
        {
            "Start": "2018-03-07T07:44:18.557297462-05:00",
            "End": "2018-03-07T07:44:18.63035891-05:00",
            "ExitCode": 0,
            "Output": ""
        },
        ......
}
```

>![](public_sys-resources/icon-note.gif) **说明：**   
>-   容器内健康检查的状态信息最多保存5条。会保存最后得到的5条记录。  
>-   容器内健康检查相关配置同时最多只能有一条生效。Dockerfile中配置的靠后的条目会覆盖靠前的；容器创建时的配置会覆盖镜像中的。  
>-   在Dockerfile中可以通过 HEALTHCHECK NONE来取消引用的镜像中的健康检查配置。在容器运行时可以通过配置--no-healthcheck来取消镜像中的健康检查配置。不允许在启动时同时配置健康检查相关选项与--no-healthcheck选项。  
>-   带有健康检查配置的容器启动后，若docker daemon退出，则健康检查不会执行，一直等待。docker daemon再次启动后，容器健康状态会变为starting。之后检查规则同上。  
>-   构建容器镜像时若健康检查相关参数配置为空，则按照默认值处理。  
>-   容器启动时若健康检查相关参数配置为0，则按照默认值处理。  

