Docker 容器的健康狀態檢查
導讀 | 在很多實際場景下,僅使用程式級健康檢查機制還遠遠不夠。比如,容器程式雖然依舊執行卻由於應用死鎖無法繼續響應使用者請求,這樣的問題是無法透過程式監控發現的。 |
自 1.12 版本之後,Docker 引入了原生的健康檢查實現。對於容器而言,最簡單的健康檢查是程式級的健康檢查,即檢驗程式是否存活。Docker Daemon 會自動監控容器中的 PID1 程式,如果 docker run 中指明瞭 restart policy,可以根據策略自動重啟已結束的容器。在很多實際場景下,僅使用程式級健康檢查機制還遠遠不夠。比如,容器程式雖然依舊執行卻由於應用死鎖無法繼續響應使用者請求,這樣的問題是無法透過程式監控發現的。
容器啟動之後,初始狀態會為 starting (啟動中)。Docker Engine 會等待 interval 時間,開始執行健康檢查 ,並週期性執行。如果單次檢查返回值非 0 或者執行需要比指定 timeout 時間還長,則本次檢查被認為失敗。如果健康檢查連續失敗超過了 retries 重試次數,狀態就會變為 unhealthy (不健康)。
注:
- 一旦有一次健康檢查成功,Docker 會將容器置回 healthy (健康)狀態
- 當容器的健康狀態發生變化時,Docker Engine 會發出一個 health_status 事件。透過檢查容器監控狀態有以下兩種方式:
可以在 Dockerfile 中宣告應用自身的健康檢測配置。HEALTHCHECK指令宣告瞭健康檢測命令,用這個命令來判斷容器主程式的服務狀態是否正常,從而比較真實的反應容器實際狀態。
HEALTHCHECK指令格式:
- HEALTHCHECK [選項] CMD <命令>:設定檢查容器健康狀況的命令
- HEALTHCHECK NONE:如果基礎映象有健康檢查指令,使用這行可以遮蔽掉
注 :在 Dockerfile 中HEALTHCHECK只可以出現一次,如果寫了多個,只有最後一個生效。
使用包含HEALTHCHECK指令的 Dockerfile 構建出來的映象,在例項化 Docker 容器的時候,就具備了健康狀態檢查的功能。啟動容器後會自動進行健康檢查。引數參考:
HEALTHCHECK 支援下列選項:
- --interval=<間隔>:兩次健康檢查的間隔,預設為 30 秒;
- --timeout=<間隔>:健康檢查命令執行超時時間,如果超過這個時間,本次健康檢查就被視為失敗,預設 30 秒;
- --retries=<次數>:當連續失敗指定次數後,則將容器狀態視為 unhealthy,預設 3 次。
- --start-period=<間隔>: 應用的啟動的初始化時間,在啟動過程中的健康檢查失效不會計入,預設 0 秒;
引數作用解釋如下:
- 執行狀態檢查首先會在容器啟動後的 interval 秒內執行,然後在前一次檢查完成後的 interval 秒內再次執行。
- 如果一次狀態檢查花費的時間超過 timeout 秒,則認為這次檢查失敗。
- 容器的執行狀態檢查連續失敗 retries 次才會被視為不健康。
- start period 為需要時間啟動的容器提供初始化時間。在此期間的探測失敗將不計入最大重試次數。
但是,如果在啟動期間健康檢查成功,則認為容器已啟動,所有連續失敗的情況都將計算到最大重試次數。
在HEALTHCHECK [選項] CMD後面的命令,格式和ENTRYPOINT一樣,分為 格式,和 exec 格 式。命令的返回值決定了該次健康檢查的成功與否:
- 0:成功;
- 1:失敗;
- 2:保留值,不要使用
假設有個映象是個最簡單的 Web 服務,我們希望增加健康檢查來判斷其 Web 服務是否在正常工作,我們可以用 curl 來幫助判斷,其 Dockerfile 的HEALTHCHECK可以這麼寫:
FROM nginx:1.23 HEALTHCHECK --interval=5s --timeout=3s --retries=3 \ CMD curl -fs || exit 1
這裡設定了每 5 秒檢查一次(這裡為了試驗所以間隔非常短,實際應該相對較長),如果健康檢查命令超過 3 秒沒響應,並且重試 3 次都沒響應就視為失敗,並且使用curl -fs || exit 1作為健康檢查命令。
使用docker build來構建這個映象:
docker build -t myweb:v1 .
構建好後啟動容器:
docker run -d --name web myweb:v1
當執行該映象後,可以透過docker container ls看到最初的狀態為(health: starting):
docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7068d793c6e4 myweb:v1 "/docker-entrypoint.…" 3 seconds ago Up 2 seconds (health: starting) 80/tcp web
在等待幾秒鐘後,再次docker container ls,就會看到健康狀態變化為了(healthy):
$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7068d793c6e4 myweb:v1 "/docker-entrypoint.…" 18 seconds ago Up 16 seconds (healthy) 80/tcp web
如果健康檢查連續失敗超過了重試次數,狀態就會變為(unhealthy)。
為了幫助排障,健康檢查命令的輸出(包括stdout以及stderr)都會被儲存於健康狀態裡,可以用 docker inspect來檢視。
$ docker inspect --format '{{json .State.Health}}' web | python -m json.tool { "FailingStreak": 0, "Log": [ { "End": "2022-08-20T14:02:38.19224648+08:00", "ExitCode": 0, "Output": "xxx", "Start": "2022-08-20T14:02:38.116041192+08:00" }, { "End": "2022-08-20T14:02:43.271105619+08:00", "ExitCode": 0, "Output": "xxx", "Start": "2022-08-20T14:02:43.200932585+08:00" } ], "Status": "healthy" }
另外一種方法是在 docker run 命令中,直接指明 healthcheck 相關策略:
$ docker run -d \ --name=myweb \ --health-cmd="curl -fs || exit 1" \ --health-interval=5s \ --health-retries=12 \ --health-timeout=2s \ nginx:1.23
透過執行docker run --help | grep health命令檢視相關的引數及解釋如下:
- --health-cmd string:執行檢查健康狀況的命令
- --health-interval duration:執行間隔時間(ms|s|m|h)(預設為 0s)
- --health-retries int:需要報告不健康的連續失敗次數
- --health-start-period duration :容器在開始健康重試倒數計時之前初始化的起始週期(ms|s|m|h)(預設 0)
- --health-timeout duration:允許一次檢查執行的最大時間(ms|s|m|h)(預設為 0s)
- --no-healthcheck:禁用任何容器指定的HEALTHCHECK,會使得 Dockerfile 構建出來的HEALTHCHECK功能失效。
如果是以 supervisor 來管理容器的多個服務,想透過子服務的狀態來判斷容器的監控狀態,可以使用supervisorctl status來做判斷,比如:
$ docker run --rm -d \ --name=myweb \ --health-cmd="supervisorctl status" \ --health-interval=5s \ --health-retries=3 \ --health-timeout=2s \ nginx:v1
按照此引數的設定,如果supervisorctl status檢查子服務有一個不為正常的RUNNING狀態,那麼在等待大約 15 秒左右,容器的監控狀態就會從(healthy)變為(unhealthy)
在 docker-composer 中,可以使用以下方式來實現對容器的健康狀況檢查(以透過 supervisor 管理子程式的容器為例):
version: '3' services: web: image: nginx:v1 container_name: web healthcheck: test: ["CMD", "supervisorctl", "status"] interval: 5s timeout: 2s retries: 3
執行成功後,等待數秒查詢容器的狀態:
$ docker-compose ps Name Command State Ports -------------------------------------------------------------------------------- web supervisord -c /etc/superv ... Up (healthy) 443/tcp, 80/tcp
當透過手動supervisorctl stop停掉裡面的一些子服務,導致裡面的子服務狀態不全為RUNNING狀態時,再檢視容器的狀態:
# docker-compose ps Name Command State Ports ---------------------------------------------------------------------------------- web supervisord -c /etc/superv ... Up (unhealthy) 443/tcp, 80/tcp
原文來自:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2913077/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle SCN健康狀態檢查Oracle
- Java應用在docker環境配置容器健康檢查JavaDocker
- Docker容器的退出狀態碼及解決方法Docker
- oracle物理dg狀態檢查Oracle
- 叢集故障處理之處理思路以及健康狀態檢查(三十二)
- Linux檢查Docker映象,容器的磁碟空間LinuxDocker
- 極速體驗docker容器健康Docker
- 【docker專欄6】詳解docker容器狀態轉換管理命令Docker
- RAC常見命令檢查狀態
- 2.檢查網路狀態
- linux檢查埠狀態命令Linux
- 檢查Capital許可狀態API
- 容器HEALTHCHECK指令對接ASP.NET Core健康檢查能力ASP.NET
- 網路狀態的檢查和MJRefresh
- 如何檢測機械硬碟和固態硬碟的健康狀況?硬碟
- 檢視Docker容器的資訊Docker
- JavaScript 的狀態容器 ReduxJavaScriptRedux
- EntityFramework Core健康檢查Framework
- Health Monitor 健康檢查
- uptime命令檢視Linux伺服器健康狀態Linux伺服器
- 有容雲AppSoar容器健康檢查與排程策略APP
- 使用Spring Boot實現動態健康檢查HealthChecksSpring Boot
- 檢查asm磁碟組狀態的檢視v$asm_diskgroupASM
- docker 容器的使用與檢視Docker
- 11G RAC檢查各元件狀態元件
- SOFABoot 健康檢查能力分析boot
- .Net Core基礎的健康檢查
- docker檢視容器IP地址Docker
- 檢查Oracle的鎖狀態並清除問題會話Oracle會話
- 檢查 Docker 版本,重灌 DockerDocker
- Kubernetes-POD的健康檢查
- 資料庫健康檢查(轉)資料庫
- MySQL資料庫健康檢查--MySQL巡檢MySql資料庫
- goldengate 程式(捕捉,傳輸,複製)的狀態檢查命令Go
- docker檢視容器日誌命令Docker
- 解決pod健康檢查問題
- 構建api gateway之 健康檢查APIGateway
- redis健康檢查與故障轉移Redis