容器狀態是 UP 的,應用就是健康的嗎?
還真不一定!
Docker 只能從容器啟動進程的返回代碼判斷其狀態,而對於容器內部應用的運行情況基本沒有了解。
執行 docker run
命令時,通常會根據 Dockerfile 中的 CMD 或 ENTRYPOINT 啟動一個進程,這個進程的狀態就是 docker ps
STATUS
列顯示容器的狀態。

命令顯示:
-
有的容器正在運行,狀態為
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 失敗。
下面我們通過例子來演示 Health Check 在 swarm 中的應用。
docker service create --name my_db \
--health-cmd "curl --fail http://localhost:8091/pools || exit 1" \
couchbase
--health-cmd
Health Check 的命令,還有幾個相關的參數:
-
--timeout
命令超時的時間,默認 30s。 -
--interval
命令執行的間隔時間,默認 30s。 -
--retries
命令失敗重試的次數,默認為 3,如果 3 次都失敗了則會將容器標記為unhealthy
。swarm 會銷毀並重建unhealthy
的副本。
通過 docker ps
可以查看到容器的狀態為 healthy
:
下面模擬一個 unhealthy
的場景,curl
指向一個不存在的 url。
docker service create --name my_db \
--health-cmd "curl --fail http://localhost:8091/non-exist || exit 1" \
couchbase

副本被 shutdown 了,可以到 swarm-worker1
用 docker inspect
查看具體原因。
root@swarm-worker1:~# docker inspect my_db.1.saebvmn7aql2l2n4kgp6s1lui
容器被標記為 unhealthy
,其原因是 curl 連續三次返回 404 錯誤。
Docker 默認只能通過容器進程的返回碼判斷容器的狀態,Health Check 則能夠從業務角度判斷應用是否發生故障,是否需要重啟。
Health Check 就討論到這里,下一節我們學習如何在容器中使用密碼,私鑰這類敏感數據。
書籍:
1.《每天5分鍾玩轉Docker容器技術》
https://item.jd.com/16936307278.html
2.《每天5分鍾玩轉OpenStack》
https://item.jd.com/12086376.html