使用Systemd執行Docker容器
本文講的是使用Systemd執行Docker容器,【編者的話】現今Docker的每個主要發行版都在轉移到Systemd上,使用Systemd執行Docker更有便於主機系統初始化以及程式管理等。但Systemd在監控容器上有一弊端,它不監控容器,而監控的是客戶端,導致了若客戶端與容器脫離聯絡後無論容器是否執行正常Systemd均會將該容器停掉等問題。但可以通過Systemd-Docker來解決。
你可以通過Shell指令碼或者Docker Compose(目前它還不能用於生產環境)來執行Docker容器,但在一些使用者場景下,你也可以使用主機系統初始化/程式管理。現在看起來,好像主流的Linux發行版本都準備使用Systemd,所以接下來我將深入介紹下Docker和Systemd。
如果你的一個非容器化的服務依賴於容器,那這個時候使用Systemd就可能是最好的解決方案。更有趣的是,純容器應用的開發者也注意到Systemd的價值。最後提醒下大家,CoreOS就建立在Systemd和Docker之上。
在『官方的Docker文件之使用Systemd』中,你可以看到官方推薦手動建立Docker容器,並只在service檔案中使用docker start以及docker stop。我不贊同這個建議,因為這使得主機之間的遷移配置或使用一個新容器重啟服務更加困難----如果service檔案包含了所有的依賴元件會更好。這是通過CoreOS的方法,我將在這部落格展示一個案例。
我們以一個基於『Systemd』的Docker化的Redis為例來進行說明。例子中我將使用CentOS 7,我想其它的發行版也應該類似。你幾乎需要以下所有的service file:
[Unit] Description=Redis Container After=Docker.service Requires=Docker.service [Service] TimeoutStartSec=0 Restart=always ExecStartPre=-/usr/bin/Docker stop redis ExecStartPre=-/usr/bin/Docker rm redis ExecStartPre=/usr/bin/Docker pull redis ExecStart=/usr/bin/Docker run --rm --name %n redis [Install] WantedBy=multi-user.target
這裡需要注意的事情有:
- 很明顯,容器依賴於Docker的執行,因此Requires 這行。After這行也需要注意避免競爭條件。
- 在我們啟動容器之前,我們首先停掉並移除任何存在相同名稱的容器,然後拉取最新的版本的映象。以”-”開頭的意味著如果命令執行失敗,系統不會終止。
- 這意味著我們的容器將每次都從頭開始。如果你希望儲存資料,你需要使用volumes或volume 容器,亦或改變code(如果存在),重啟舊的容器。
- 我們使用TimeoutStartSec=0實現永不超時,例如Docker pull可能需要一段時間。
如果你儲存這檔案到/etc/Systemd/system/Docker.redis.service並且執行systemctl start Docker.redis,Systemd將啟動Redis 容器(記住,如果它需要拉取redis映象這可能需要花一些時間)。那麼我們就可以手動訪問它,或另設一個依賴於它的服務。例如,如果我們有一個是執行在一個容器並且依賴於redis服務的應用foo,我們就可以使用以下服務檔案:
[Unit] Description=Foo Service After=Docker.service Requires=Docker.service After=Docker.redis.service Requires=Docker.redis.service [Service] TimeoutStartSec=0 Restart=always ExecStartPre=-/usr/bin/Docker stop foo ExecStartPre=-/usr/bin/Docker rm foo ExecStartPre=/usr/bin/Docker pull foo ExecStart=/usr/bin/Docker run --name foo \ --link Docker.redis.ervice:redis --rm\ foo [Install] WantedBy=multi-user.target
如果redis容器發生故障,Systemd將自動重啟redis service和依賴foo的服務。
這配置工作花費大部分時間,這有一個主要問題。Systemd不會監控自身的容器,它監控的是客戶端。無論出於何種原因如果客戶端與容器脫離(比如網路問題),Systemd將停掉這個容器,即使它可能正常執行。相反,如果容器掛了但客戶端仍正常執行,Systemd不會做任何操作。我們真正需要監控的是容器,而不是客戶端。正好這有一個解決方法---Systemd-Docker。
System-Docker的工作原理是當它啟動時通過包裝Docker命令和移動容器程式到Systemd服務單元的cgroup上。我們的redis例項看起來是這樣的:
[Unit] Description=Redis After=Docker.service Requires=Docker.service [Service] TimeoutStartSec=0 ExecStartPre=/usr/bin/Docker pull redis ExecStart=/usr/local/bin/Systemd-Docker --cgroups name=Systemd run --rm --name %n redis Restart=always RestartSec=10s Type=notify NotifyAccess=all [Install] WantedBy=multi-user.target
這是簡單的,但有一個問題是,Systemd-Docker命令隱瞞事實,那就是具有相同名字的停止了的容器將被刪除。我不得不新增--cgroups name=system 引數到存在這一問題的CentOS7和cgroups(其他發行版應該不需要這個引數)。如果你想嘗試Systemd-Docker,注意,你當前必須從頭構建,由於在我寫本博文時,“go get”功能是不完整的提供給了Docker的一個依賴。
總之,如果你想使用Systemd,顯然你需要在用之前思考得全面點。如果你只是使用一些工具不需要執行時超可靠的,這篇博文的的配置規則就可以了。否則你需要使用Systemd-Docker或解決監控容器的其他方法。
[1].在這種情況下執行,我們可以參照一個不需要修改或第三方工具的快速解決方案,請參閱下面問題的更多資訊:
• https://github.com/Docker/Docker/issues/7245
• https://github.com/Docker/Docker/pull/10427
• https://github.com/ibuildthecl ... es/25
原文連結:Running Docker Containers with Systemd(翻譯:陳藝華)
原文釋出時間為:2015-04-21
本文作者:CDocer
本文來自雲棲社群合作伙伴DockerOne,瞭解相關資訊可以關注DockerOne。
原文標題:使用Systemd執行Docker容器
相關文章
- 使用docker執行CentOS容器DockerCentOS
- 使用 systemd 執行 Horizon
- 使用docker構建jenkins映象並執行容器DockerJenkins
- Docker命令-docker exec-在執行的容器中執行命令Docker
- 使用容器Docker進行開發Docker
- 如何在Docker容器中執行GUI程式DockerGUI
- 在Docker容器中使用Hadoop執行Python MapReduce作業DockerHadoopPython
- Docker容器中執行.net framework控制檯程式DockerFramework
- Docker容器中執行.Net Core應用程式Docker
- Docker基礎:查詢映象和執行容器Docker
- 使用 LXD 容器執行 Ubuntu CoreUbuntu
- Laravel 專案 使用 Windows docker 執行php 容器 及 mysql 容器時,連不起資料庫。LaravelWindowsDockerPHPMySql資料庫
- 在Docker容器內執行 vi 編輯器 | BaeldungDocker
- 從已執行容器獲取 docker run 引數Docker
- 在Docker中,如何停止所有正在執行的容器?Docker
- Docker中Mysql容器內如何執行SQL檔案?DockerMySql
- docker學習2|在容器中部署nginx並儲存、執行容器DockerNginx
- 使用普通使用者執行 dockerDocker
- docker執行容器後agetty程式cpu佔用率100%Docker
- Youki:用 Rust 編寫的更快Docker容器執行時RustDocker
- 進入正在執行的Docker容器的4種方式Docker
- 如何把 Java Web 應用放在 docker 容器中執行JavaWebDocker
- 通過Docker容器執行持續整合/持續部署Docker
- 使用TestContainers進行容器Docker測試 – EmmanouilAIDockerUI
- 使用docker建立和執行跨平臺的容器化的mssql資料庫DockerSQL資料庫
- 使用 docker-sync 解決 docker for Mac 啟動的虛擬容器程式執行緩慢的問題DockerMac
- Docker-容器使用Docker
- 在Docker容器中執行ASP.NET MVC應用程式DockerASP.NETMVC
- Docker Hello World容器執行報錯的解決辦法Docker
- 如何在Docker容器啟動時自動執行指令碼Docker指令碼
- docker學習3:Docker容器使用Docker
- Docker極簡入門:使用Docker執行Java程式DockerJava
- 在 Azure 上使用 Docker 執行 MonoDockerMono
- 並行執行 Job - 每天5分鐘玩轉 Docker 容器技術(134)並行Docker
- Docker容器執行時許可權和Linux系統功能DockerLinux
- docker建立容器後如何使用Docker
- (四)Docker安裝使用容器Docker
- 使用iptables管控docker容器Docker