1. 程式人生 > >Docker Swarm系列——4.Swarm服務檢查

Docker Swarm系列——4.Swarm服務檢查


在這篇文章中,大家將會了解如何在服務中配置簡單的命令進行容器定期自檢,以表明當前容器是否處於健康狀態。

1. 健康檢查

通過前面幾篇文章的理論和實踐,大家都知道,Docker Swarm會自動判斷服務中容器的健康狀態,從而決定是否刪除重建,以保證設定的副本數replicas。但它是怎麼判斷的呢?

容器都有一個STATUS代表它的執行狀態created, restarting, running, removing, paused, exited, dead,最主要的,是容器執行的狀態碼STOPSIGNAL,只要是Exited(STOPSIGNAL!=0),那就代表異常退出。

通過docker kill http.2.a6i8uov6efb4e0wjioha02o9y

模擬服務中的一個副本異常退出執行,docker ps -a檢視:

...
CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS                      PORTS               NAMES
aad2191ae7d5        nandy/show-host-info:v2         "/app"              18 seconds ago      Exited (2) 4 seconds ago                        http.2.a6i8uov6efb4e0wjioha02o9y
5e0b2da6b4e5        nandy/show-host-info:v2         "/app"              18 seconds ago      Up 17 seconds               80/tcp              http.1.p35na0wooa509aqd53qzr1n50
...

Exited (2)代表容器非正常停止。服務會在第一時間捕獲到這個STOPSIGNAL並立即重建一個新的容器:

...
CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS                      PORTS               NAMES
c08cdedcf461        nandy/show-host-info:v2         "/app"              9 seconds ago       Up 4 seconds                80/tcp              http.2.ak0lef9jebrqz2racsf2vq8fl
aad2191ae7d5        nandy/show-host-info:v2         "/app"              24 seconds ago      Exited (2) 10 seconds ago                       http.2.a6i8uov6efb4e0wjioha02o9y
5e0b2da6b4e5        nandy/show-host-info:v2         "/app"              24 seconds ago      Up 23 seconds               80/tcp              http.1.p35na0wooa509aqd53qzr1n50
...

但是,我們結合實際的伺服器運維經驗思考一下,僅靠容器本身的異常退出與否來判斷,是不是可以確定服務健康(正常響應請求)?如果是服務假死(CPU異常、記憶體異常、觸發程式碼BUG…)而容器並未異常退出呢?如果服務有一個介面,通過定期請求這個介面並返回期望值來判斷呢?

2. 建立服務

這篇文章的主角便是healthcheck。它有5個子選項:

--health-cmd=命令,用於檢查介面的命令。
--health-interval=時間間隔 (預設: 30s),它是每次執行healthcheck的時間間隔。
--health-timeout=時間間隔 (預設: 30s),如果在超時時間之內沒有響應,則代表異常。
--health-retries=N (預設: 3),連續達到多少次異常之後退出。
--health-start-period=時間間隔 (預設:0),容器啟動之後多久進行健康檢查(服務啟動預熱),即執行health-cmd。

建立服務,在之前的基礎上加入容器的健康檢查,注意curl -f http://localhost:80檢查命令,映象中必須先安裝curl

docker service create --network httpnet --name http --replicas 2 -p 81:80 \
    --health-cmd "curl -f http://localhost:80 || exit 1" --health-interval 5s --health-timeout 3s --health-retries 3 --health-start-period 30s \
    nandy/show-host-info:v2

執行docker ps檢視:

CONTAINER ID        IMAGE                             COMMAND             CREATED              STATUS                        PORTS               NAMES
add8115df6f1        nandy/show-host-info:v2           "python run.py"     About a minute ago   Up About a minute (healthy)   80/tcp              http.1.q1jjcnjcrfcxsafzdvtvhi7ho
66e77ee79c0a        nandy/show-host-info:v2           "python run.py"     About a minute ago   Up About a minute (healthy)   80/tcp              http.2.m0oaoqjia0d6m3rzmsh5sr7n6

此時,STATUS的顯示比以往多了(healthy)狀態,同時,為了驗證curl -f http://localhost:80是否每隔5s執行一次,且執行是否正常,我們通過docker logs --tail 5 http.1.q1jjcnjcrfcxsafzdvtvhi7ho檢視一下容器的日誌:

[2018-10-16 17:54:42 +0800] - (sanic.access)[INFO][127.0.0.1:50220]: GET http://localhost/  200 41
[2018-10-16 17:54:47 +0800] - (sanic.access)[INFO][127.0.0.1:50224]: GET http://localhost/  200 41
[2018-10-16 17:54:52 +0800] - (sanic.access)[INFO][127.0.0.1:50228]: GET http://localhost/  200 41
[2018-10-16 17:54:58 +0800] - (sanic.access)[INFO][127.0.0.1:50232]: GET http://localhost/  200 41
[2018-10-16 17:55:03 +0800] - (sanic.access)[INFO][127.0.0.1:50236]: GET http://localhost/  200 41