[英]Restarting an unhealthy docker container based on healthcheck
我使用的是Docker version 17.09.0-ce
,我看到容器被標記為不健康。 有沒有讓容器重新啟動而不是讓容器保持不健康狀態的選項?
重新啟動 unhealty 容器功能在原始 PR ( https://github.com/moby/moby/pull/22719 ) 中,但在討論后被刪除,並考慮稍后作為 RestartPolicy 的增強完成。
此時您可以使用此解決方法來自動重新啟動不健康的容器: https ://hub.docker.com/r/willfarrell/autoheal/
這是一個示例撰寫文件:
version: '2'
services:
autoheal:
restart: always
image: willfarrell/autoheal
environment:
- AUTOHEAL_CONTAINER_LABEL=all
volumes:
- /var/run/docker.sock:/var/run/docker.sock
只需在此執行docker-compose up -d
您可以通過設置智能 HEALTHCHECK 和適當的重啟策略來自動重啟不健康的容器。
Docker 重啟策略應該是always
或unless-stopped
。
HEALTHCHECK 應該實現一個邏輯,當容器不健康時殺死容器。
在下面的示例中,我使用curl
及其內部重試機制並將其(在失敗/服務不健康的情況下)通過管道傳遞給kill
命令。
HEALTHCHECK --interval=5m --timeout=2m --start-period=45s \
CMD curl -f --retry 6 --max-time 5 --retry-delay 10 --retry-max-time 60 "http://localhost:8080/health" || bash -c 'kill -s 15 -1 && (sleep 10; kill -s 9 -1)'
這里要理解的重要一步是, curl
命令中的重試邏輯是自包含的,這里的Docker重試實際上是強制性的但沒用。 然后如果curl
HTTP 請求失敗 3 次,則執行kill
。 首先它向容器中的所有進程發送一個 SIGTERM,以允許它們正常停止,然后在 10 秒后發送一個 SIGKILL 以完全終止容器中的所有進程。 必須注意的是,當容器的 PID1 死亡時,容器本身也會死亡並調用重啟策略。
kill
文檔: https : //linux.die.net/man/1/killcurl
文檔: https : //curl.haxx.se/docs/manpage.htmldocker
重啟文檔: https : //docs.docker.com/compose/compose-file/compose-file-v2/#restart 陷阱: kill
在 bash 中的行為與在 sh 中的行為不同。 在 bash 中,您可以使用-1
來通知所有 PID 大於 1 的進程死亡。
對於獨立容器,Docker 沒有本地集成來在健康檢查失敗時重新啟動容器,盡管我們可以使用 Docker 事件和腳本來實現相同的功能。 健康檢查更好地與 Swarm 集成。 通過將健康檢查集成到 Swarm 中,當服務中的容器不健康時,Swarm 會自動關閉不健康的容器並啟動一個新容器,以保持服務副本計數中指定的容器計數。
您可以嘗試在您的 Dockerfile 中添加如下內容:
HEALTHCHECK --interval=5s --timeout=2s CMD curl --fail http://localhost || kill 1
不要忘記--restart always
選項。
kill 1
將終止容器中 pid 為 1 的進程並強制容器退出。 通常由 CMD 或 ENTRYPOINT 啟動的進程的 pid 為 1。
不幸的是,此方法可能不會將容器的狀態更改為不健康,因此請小心使用。
Docker 有幾種方法可以獲取有關容器運行狀況的詳細信息。 您可以配置運行狀況檢查及其運行頻率。 此外,可以在容器內運行的應用程序上運行健康檢查,例如 http(這將使用curl --fail
選項。)您可以查看health_status
事件以獲取詳細信息。
有關不健康容器的詳細信息,inspect 命令派上用場, docker inspect --format='{{json .State.Health}}' container-name
(參見https://blog.newrelic.com/2016/08/ 24/docker-health-check-instruction/了解更多詳情。)
您應該首先解決導致“不健康”標簽的錯誤條件(任何時候運行健康檢查命令並獲得退出代碼 1)。 這可能需要也可能不需要 Docker 重新啟動容器,具體取決於錯誤。 如果您正在自動啟動/重新啟動容器,那么捕獲啟動錯誤或記錄它們和健康檢查狀態可以幫助快速解決錯誤。 如果您對自動啟動感興趣,請查看鏈接。
根據https://codeblog.dotsandbrackets.com/docker-health-check/
創建容器並添加“重新啟動:始終”。
在使用healthcheck時,要注意以下幾點:
對於獨立容器,Docker 沒有本地集成來在健康檢查失敗時重新啟動容器,盡管我們可以使用 Docker 事件和腳本來實現相同的功能。 健康檢查更好地與 Swarm 集成。 通過將健康檢查集成到 Swarm 中,當服務中的容器不健康時,Swarm 會自動關閉不健康的容器並啟動一個新容器,以保持服務副本計數中指定的容器計數。
我可以通過使用--force-recreate
選項來解決這個錯誤
docker-compose up --force-recreate <service>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.