2016-11-26 02:02:43 +08:00
# # # HEALTHCHECK 健 康 检 查
格 式 :
* ` HEALTHCHECK [选项] CMD <命令> ` : 设 置 检 查 容 器 健 康 状 况 的 命 令
* ` HEALTHCHECK NONE ` : 如 果 基 础 镜 像 有 健 康 检 查 指 令 , 使 用 这 行 可 以 屏 蔽 掉 其 健 康 检 查 指 令
` HEALTHCHECK ` 指 令 是 告 诉 Docker 应 该 如 何 进 行 判 断 容 器 的 状 态 是 否 正 常 , 这 是 Docker 1.12 引 入 的 新 指 令 。
在 没 有 ` HEALTHCHECK ` 指 令 前 , Docker 引 擎 只 可 以 通 过 容 器 内 主 进 程 是 否 退 出 来 判 断 容 器 是 否 状 态 异 常 。 很 多 情 况 下 这 没 问 题 , 但 是 如 果 程 序 进 入 死 锁 状 态 , 或 者 死 循 环 状 态 , 应 用 进 程 并 不 退 出 , 但 是 该 容 器 已 经 无 法 提 供 服 务 了 。 在 1.12 以 前 , Docker 不 会 检 测 到 容 器 的 这 种 状 态 , 从 而 不 会 重 新 调 度 , 导 致 可 能 会 有 部 分 容 器 已 经 无 法 提 供 服 务 了 却 还 在 接 受 用 户 请 求 。
而 自 1.12 之 后 , Docker 提 供 了 ` HEALTHCHECK ` 指 令 , 通 过 该 指 令 指 定 一 行 命 令 , 用 这 行 命 令 来 判 断 容 器 主 进 程 的 服 务 状 态 是 否 还 正 常 , 从 而 比 较 真 实 的 反 应 容 器 实 际 状 态 。
当 在 一 个 镜 像 指 定 了 ` HEALTHCHECK ` 指 令 后 , 用 其 启 动 容 器 , 初 始 状 态 会 为 ` starting ` , 在 ` HEALTHCHECK ` 指 令 检 查 成 功 后 变 为 ` healthy ` , 如 果 连 续 一 定 次 数 失 败 , 则 会 变 为 ` unhealthy ` 。
` HEALTHCHECK ` 支 持 下 列 选 项 :
2016-12-15 09:42:50 +08:00
* ` --interval=<间隔> ` : 两 次 健 康 检 查 的 间 隔 , 默 认 为 30 秒 ;
2016-11-26 02:02:43 +08:00
* ` --timeout=<时长> ` : 健 康 检 查 命 令 运 行 超 时 时 间 , 如 果 超 过 这 个 时 间 , 本 次 健 康 检 查 就 被 视 为 失 败 , 默 认 30 秒 ;
* ` --retries=<次数> ` : 当 连 续 失 败 指 定 次 数 后 , 则 将 容 器 状 态 视 为 ` unhealthy ` , 默 认 3 次 。
和 ` CMD ` , ` ENTRYPOINT ` 一 样 , ` HEALTHCHECK ` 只 可 以 出 现 一 次 , 如 果 写 了 多 个 , 只 有 最 后 一 个 生 效 。
在 ` HEALTHCHECK [选项] CMD ` 后 面 的 命 令 , 格 式 和 ` ENTRYPOINT ` 一 样 , 分 为 ` shell ` 格 式 , 和 ` exec ` 格 式 。 命 令 的 返 回 值 决 定 了 该 次 健 康 检 查 的 成 功 与 否 : ` 0 ` : 成 功 ; ` 1 ` : 失 败 ; ` 2 ` : 保 留 , 不 要 使 用 这 个 值 。
假 设 我 们 有 个 镜 像 是 个 最 简 单 的 Web 服 务 , 我 们 希 望 增 加 健 康 检 查 来 判 断 其 Web 服 务 是 否 在 正 常 工 作 , 我 们 可 以 用 ` curl ` 来 帮 助 判 断 , 其 ` Dockerfile ` 的 ` HEALTHCHECK ` 可 以 这 么 写 :
` ` ` Dockerfile
FROM nginx
RUN apt - get update && apt - get install - y curl && rm - rf / var / lib / apt / lists / *
HEALTHCHECK -- interval = 5 s -- timeout = 3 s \
CMD curl - fs http : //localhost/ || exit 1
` ` `
这 里 我 们 设 置 了 每 5 秒 检 查 一 次 ( 这 里 为 了 试 验 所 以 间 隔 非 常 短 , 实 际 应 该 相 对 较 长 ) , 如 果 健 康 检 查 命 令 超 过 3 秒 没 响 应 就 视 为 失 败 , 并 且 使 用 ` curl -fs http://localhost/ || exit 1 ` 作 为 健 康 检 查 命 令 。
使 用 ` docker build ` 来 构 建 这 个 镜 像 :
` ` ` bash
$ docker build - t myweb : v1 .
` ` `
构 建 好 了 后 , 我 们 启 动 一 个 容 器 :
` ` ` bash
$ docker run - d -- name web - p 80 : 80 myweb : v1
` ` `
2018-01-15 22:00:53 +08:00
当 运 行 该 镜 像 后 , 可 以 通 过 ` docker container ls ` 看 到 最 初 的 状 态 为 ` (health: starting) ` :
2016-11-26 02:02:43 +08:00
` ` ` bash
2018-01-15 22:00:53 +08:00
$ docker container ls
2016-11-26 02:02:43 +08:00
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03e28 eb00bd0 myweb : v1 "nginx -g 'daemon off" 3 seconds ago Up 2 seconds ( health : starting ) 80 / tcp , 443 / tcp web
` ` `
2018-01-15 22:00:53 +08:00
在 等 待 几 秒 钟 后 , 再 次 ` docker container ls ` , 就 会 看 到 健 康 状 态 变 化 为 了 ` (healthy) ` :
2016-11-26 02:02:43 +08:00
` ` ` bash
2018-01-15 22:00:53 +08:00
$ docker container ls
2016-11-26 02:02:43 +08:00
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03e28 eb00bd0 myweb : v1 "nginx -g 'daemon off" 18 seconds ago Up 16 seconds ( healthy ) 80 / tcp , 443 / tcp web
` ` `
如 果 健 康 检 查 连 续 失 败 超 过 了 重 试 次 数 , 状 态 就 会 变 为 ` (unhealthy) ` 。
为 了 帮 助 排 障 , 健 康 检 查 命 令 的 输 出 ( 包 括 ` stdout ` 以 及 ` stderr ` ) 都 会 被 存 储 于 健 康 状 态 里 , 可 以 用 ` docker inspect ` 来 查 看 。
` ` ` bash
$ docker inspect -- format ' { { json . State . Health } } ' web | python - m json . tool
{
"FailingStreak" : 0 ,
"Log" : [
{
"End" : "2016-11-25T14:35:37.940957051Z" ,
"ExitCode" : 0 ,
"Output" : "<!DOCTYPE html>\n<html>\n<head>\n<title>Welcome to nginx!</title>\n<style>\n body {\n width: 35em;\n margin: 0 auto;\n font-family: Tahoma, Verdana, Arial, sans-serif;\n }\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" ,
"Start" : "2016-11-25T14:35:37.780192565Z"
}
] ,
"Status" : "healthy"
}
` ` `