如何使用容器自動刪除功能自動重啟我的 Docker 容器?
我有一個通用 VPS,並且正在 Dockerising 上面的應用程序。上面大約有 5-6 個容器,其他的很少,所以可以根據需要輕鬆地重建盒子。
對於每個應用程序,我都有一個啟動腳本。一個 WordPress 容器如下所示:
#!/bin/bash # Get the host IP address export DOCKER_HOSTIP=`ifconfig docker0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1` echo "Connecting to database on Docker host ${DOCKER_HOSTIP}" docker run \ --add-host=docker:${DOCKER_HOSTIP} \ --network dockernet \ --network-alias jonblog \ --detach \ --restart always \ --rm \ jonblog
但是,這會返回一個錯誤:
衝突的選項:–restart 和–rm
有幾個 Docker 票說這是明智的,但我不明白。我想我的意思很清楚:如果容器沒有執行(例如在啟動時),那麼我想啟動它。如果它死了,那麼我希望容器被刪除,並從基礎映像創建一個新的容器。無論如何,容器應該是不可變的——我希望保留的任何狀態,比如媒體文件和日誌,都將被寫入卷。
所以,我想我應該放棄這個
--restart
標誌,然後使用程序管理器來停止和啟動 Docker 容器。我可以在這裡使用Monit嗎?我希望能夠做類似的事情:CHECK PROCESS jonblog MATCHING jonblog START PROGRAM = "/root/docker/jonblog/host-start.sh" STOP PROGRAM = "docker stop jon-blog"
但是,這會檢查系統程序表,而不是
docker ps
,因此它不會找到與指定字元串匹配的內容。我可以讓它docker ps
定期執行,並匹配輸出中的行嗎?如果它被證明是強大的,我很樂意使用另一個工具。比如我覺得Supervisor有點重量級,但如果那更能和Docker一起工作,我願意用它。
關於 –rm 的說明
我想要的原因
--rm
是在Dockerisation過程中,我停止了目前執行的容器,load
一個新版本的鏡像,重新執行上面的腳本。這意味著 Docker 會被通知restart
每個容器的策略。我發現重啟機器後,我會同時執行 15 個左右略有不同的應用程序版本,這不是本意。我想我可以
docker update --restart never
在舊容器上使用來防止這種情況發生,但是當我的容器停止時,我把它留在周圍,我會盡快讓它自動刪除。我可以使用某種 cron 作業定期清理舊的,但考慮到 Docker 可以為我做這件事,這感覺有點笨拙。尋求一系列答案
一個非常有幫助的評論建議我應該研究 Minikube,它顯然簡化了 Kubernetes 的設置,即使在某種程度上熟練的個人可以在五分鐘內啟動並執行。
我仍然很想看到更多輕量級的解決方案被提出,所以我有一系列的答案可供選擇。如前所述,我想知道像 Monit 這樣的流程主管是否可以工作的答案。
從頭到尾,我可以編寫一個 shell 循環,
docker ps
每五秒寫入一個文件,持續一分鐘,然後每分鐘在 Cron 上執行它。grep
然後我可以使用MonitCHECK PROGRAM
系統檢查來掃描該文件。這有點駭人聽聞,但如果它有問題,我可以很容易地理解它。這個建議有什麼進展嗎?
我有一個適合我目前對 Docker 理解的答案。評論中建議我嘗試 Minikube,儘管毫無疑問這可以快速啟動,但我擔心這將是一個學習的兔子洞,會讓我在 tar 中困住數週。我的工程原理之一是知道一個人何時達到了填充新資訊的認知極限!
因此,我著手以一種簡單的方式解決這個問題。我有兩個選擇:
- 使用 Docker 中的容器自動刪除功能,並設置我自己的重啟系統
- 使用 Docker 重啟策略,並設置我自己的容器刪除系統
我從第一個開始,認為流程主管 Monit 會很好用,部分原因是它是輕量級的,部分原因是我熟悉它。但是,它開始感覺像是錯誤的解決方案,因為我要解決核心問題,即它無法乾淨地獲取 Docker 容器程序列表。
事實上,第二個選項更清潔,並且由於停止容器清理實際上並不是優先事項而放大了這一點 - 它只是為了保持整潔。當然,我為此使用了 Docker;這是
Dockerfile
:# Docker build script for Docker Tidy FROM alpine:3.6 RUN apk update RUN apk add docker # See this for BusyBox cron schedules # https://gist.github.com/andyshinn/3ae01fa13cb64c9d36e7 COPY bin/docker-tidy.sh /etc/periodic/daily/ RUN chmod +x /etc/periodic/daily/docker-tidy.sh # Start Cron in the foreground ENTRYPOINT ["crond", "-l", "2", "-f"]
這是
bin/docker-tidy.sh
:#!/bin/sh # # With thanks to: # http://www.doublecloud.org/2015/05/simple-script-to-list-and-remove-all-stopped-docker-containers/ docker rm -v $(docker ps -a -q -f status=exited)
最後,我的解決方案的一個缺點是,如果在停止容器清理之前重新啟動主機,這些容器似乎也會重新啟動。因此,我在啟動新容器之前重置了這些容器的重啟策略。
例如,這是我在主機上啟動 Docker Tidy 容器本身的方式。在實踐中,我已將策略更改程式碼整理到自己的腳本中,但這將給出總體構想:
#!/bin/bash # Removes the restart policy from previous containers CONTAINER_LABEL=docker-tidy-instance docker ps --all --filter label=$CONTAINER_LABEL --quiet | xargs --no-run-if-empty docker update --restart no docker run \ --label $CONTAINER_LABEL \ --volume /var/run/docker.sock:/var/run/docker.sock \ --detach \ --restart always \ docker-tidy