Background
通常情況下,我們會(huì)使用一個(gè)容器運(yùn)行一種服務(wù),比如一個(gè)容器運(yùn)行數(shù)據(jù)庫(kù)服務(wù)唠叛,一個(gè)容器作為web服務(wù)器等等, 因此一個(gè)容器被setup起來(lái)并不能代表其中的服務(wù)毫無(wú)問(wèn)題浪箭,因此如何check容器中的服務(wù)器是否正常才是最重要的問(wèn)題控漠。
容器的狀態(tài)
我們都知道矗积,通過(guò)docker ps
你可以看到所有正在運(yùn)行的容器全肮,以及容器的部分信息:
[圖片上傳失敗...(image-f10236-1555504132810)]
有兩個(gè)列是需要關(guān)注的:
COMMAND:
通常為了容器中的service正常啟動(dòng),我們會(huì)使用CMD/ENTRYPOINT
設(shè)置一段指令棘捣。容器啟動(dòng)之后辜腺,通常會(huì)根據(jù) Dockerfile 中的 CMD 或 ENTRYPOINT 啟動(dòng)一個(gè)進(jìn)程,Command描述的就是這個(gè)進(jìn)程執(zhí)行的指令柱锹。-
STATUS
描述的是當(dāng)前容器的狀態(tài),以及容器在多久之前進(jìn)入這樣的狀態(tài)哪自。也可以說(shuō)他描述的是上面COMMAND
指令執(zhí)行的情況。命令顯示:
有的容器正在運(yùn)行禁熏,狀態(tài)為 UP壤巷。
有的容器已經(jīng)正常停止了,狀態(tài)是 Exited (0)瞧毙‰驶或者說(shuō)
COMMAND執(zhí)行的指令正常退出
有的則因發(fā)生故障停止了,退出代碼為非 0宙彪,例如 Exited (137)矩动、Exited (1) 等。
雖然释漆,我們通常會(huì)通過(guò)CMD悲没、ENTRYPOINT
設(shè)置COMMAND
指令是容器server的啟動(dòng)指令,我們也能通過(guò)STATUS
看到啟動(dòng)指令是否執(zhí)行成功男图。但是及時(shí)COMMAND沒(méi)有出錯(cuò)STATUS是up
也不能等同于這個(gè)server可以提供服務(wù)
Health Check
What
Docker允許指定一個(gè)命令作為health check
命令示姿,Docker可以通過(guò)這個(gè)指令執(zhí)行的成功與否來(lái)判定容器當(dāng)前的狀態(tài)。
Docker 支持的 Health Check 可以是任何一個(gè)單獨(dú)的命令逊笆,Docker 會(huì)在容器中執(zhí)行該命令栈戳,如果返回 0,容器被認(rèn)為是 healthy难裆,如果返回 1子檀,則為 unhealthy。
當(dāng)一個(gè)容器有指定健康檢查 (HEALTHCHECK) 時(shí)乃戈,它除了普通的容器狀態(tài)之外褂痰,還有:
-
starting
: Initial status when the container is still starting -
healthy
: 如果health check成功 -
unhealthy
: If a single run of the takes longer than the specified timeout then it is considered unhealthy. If a health check fails then the will run retries number of times and will be declared unhealthy if the still fails.
這些狀態(tài)你可以通過(guò)docker ps
看到。
how to check health
In Dockerfile
- 給鏡像設(shè)置HEALTHCHECK
HEALTHCHECK [option] CMD <command>
- command是HEAlthcheck的指令:如果你的service是restful api偏化,指令可以是
curl heartbeat api
- option:
- --interval=<interval>: 兩次健康檢查命令執(zhí)行的間隔時(shí)間. default value 是 30 seconds.
- --timeout=<interval>: 設(shè)置某一個(gè)次health check執(zhí)行的timeout時(shí)間脐恩,一旦超時(shí)代表這一次healthcheck失敗. default value 是 30 seconds.
- --retries=<number of times>: 設(shè)置health check連續(xù)失敗次數(shù)一旦達(dá)到設(shè)置的值容器狀態(tài)就會(huì)變成
unhealthy
. default value 是 3. - --start-period=<interval>: The initialization time of application startup. Failed health check during the startup is not counted. The default value is 0 second (introduced since version 17.05).
- command是HEAlthcheck的指令:如果你的service是restful api偏化,指令可以是
Note
The HEALTHCHECK 只能在Dockerfile中出現(xiàn)一次,如果你設(shè)置了多次侦讨,那么就會(huì)直接使用最后一個(gè)命令
- 如果本身鏡像中有HEALTHCHECK驶冒,下面的指令可以禁止HEALTHCHECK
HEALTHCHECK NONE
一旦容器被正常啟動(dòng),初始狀態(tài)就是starting
. Docker engine會(huì)自動(dòng)的根據(jù)你設(shè)定的--interval
, 每個(gè)interval
時(shí)間運(yùn)行一次這個(gè)health check command韵卤, 并且根據(jù)每次運(yùn)行的結(jié)果及時(shí)的update你的容器的status
舉個(gè)例子:
FROM elasticsearch:5.5
HEALTHCHECK --interval=5s --timeout=2s --retries=12 \
CMD curl --silent --fail localhost:9200/_cluster/health || exit 1
In docker compose
docker compose 2.1版本之后才支持health check
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
- test: 定義了health check的指令骗污,只能是string或者一個(gè)list。如果是list沈条,第一個(gè)參數(shù)只能是
NONE, CMD or CMD-SHELL
healthcheck:
test: curl -f https://localhost || exit 1
interval: 1m30s
timeout: 10s
retries: 3
start_period: 40s
可以使用如下指令disable掉image的healthcheck
healthcheck:
disable: true