在(Docker里的)Jenkins里運行Docker
【編者的話】在Docker中使用Docker有兩種方式,區別在于環境是否與宿主隔離開來。本文以在Jenkins中使用Docker為例,說明如何通 過加載宿主Docker socket和程序達成重用宿主鏡像的目的。文章最后還討論了這一方式面臨的安全問題,務必在實際使用時加以考慮。
在本文中,我們將快速了解一下如何在一個容器里裝載Docker sock以便創建其“兄弟”容器。我的一個同事稱之為DooD(Docker-outside-of-Docker),以區別于DinD(Docker- in-Docker),后者是在容器中安裝一個完整的隔離的Docker版本。DooD比DinD簡單得多(至少在配置方面),尤其是能重用并緩存宿主上 的鏡像。反之,如果你想實現鏡像對宿主的隱藏和隔離,則最好使用DinD。
為說明DooD的工作方式,我們將在一個Jenkins容器內使用DooD,從而能在Jenkins任務中創建并測試容器。我們希望使用Jenkins用戶來創建這些容器,因此會比使用root用戶稍微麻煩些。這有點很像Pini Reznik在“ 使用Docker、Mesos實現持續交付”中描述的技術,不過我們將使用 sudo來避免Pini面臨的將用戶加入Docker組的問題。
我們使用官方Jenkins鏡像作為基礎,剩下的事情就很簡單了。
創建一個包容以下內容的Dockerfile:
FROM jenkins:1.596USER root RUN apt-get update \ && apt-get install -y sudo \ && rm -rf /var/lib/apt/lists/* RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
USER jenkins COPY plugins.txt /usr/share/jenkins/plugins.txt RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt</pre>
我們需要賦予jenkins用戶sudo權限以便能在容器內運行Docker命令。當然,也可以將jenkins用戶加入到Docker組中來避免在所有Docker命令前使用‘sudo’,不過由于這個組gid的不同會造成不可移植(如Pini文中所述)。
最后兩行用于處理 plugins.txt文件中定義的插件。如果你不需要任何插件可以忽略這兩行,不過我推薦至少包括如下內容:$ cat plugins.txt scm-api:latest git-client:latest git:latest greenballs:latest
如果不想安裝任何插件,可創建個空文件或將相關指令從Dockerfile中刪除。本文并不需要上述插件。
現在來構建并運行容器,將Docker socket和程序映射進來。
$ docker build -t myjenk . ... Successfully built 471fc0d22bff $ docker run -d -v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker -p 8080:8080 myjenk
現在你就有一個運行在 http://localhost:8080的Docker實例可以用來運行Docker命令了。可通過如下步驟快速測試一下:
- 在瀏覽器中打開Jenkins首頁,并點擊“創建一個新任務”鏈接。
- 輸入項目名稱(比如“docker-test”),選擇“構建一個自由風格的軟件項目”并點擊OK。
- 在配置頁面,點擊“增加構建步驟”并選擇“Execute shell”。
- 在命令框里輸入“sudo docker run hello-world”。
- 點擊“保存”。
- 點擊“立即構建”。 </ul>
運氣好的話,應出現一個綠(或藍)球。點擊這個球,并選擇“Console Output”,你將看到類似如下內容:
好極了!我們已經在Jenkins容器內成功運行了Docker命令。請注意,這里存在一個重大的安全問題:Jenkins用戶對宿主具有root權限, 比如Jenkins可以創建裝載宿主任意目錄的容器。因此,務必確保這個容器只對受信用戶訪問,并考慮使用VM來將Jekins與宿主其他部分隔離開。
還有其他的方式,主要是 Docker in Docker(DinD)以及 使用HTTPS與Docker后臺程序通訊。 DinD并不比使用特權模式的容器安全性高,不過確實能避免使用sudo。DinD最主要的劣勢是你無法重用宿主緩存的鏡像(不過如果需要為測試容器提供 一個與宿主隔離的干凈環境,這將很有用)。通過HTTPS暴露socket不需要sudo并且可以使用宿主的鏡像,但因為打開了端口增加了攻擊面,可以說 是最不安全的。
我將在未來的文章中深入說明如何安全地設置HTTPS socket上的Docker。
原文鏈接:Running Docker in Jenkins (in Docker)(翻譯:梁曉勇 審校:魏小紅)
來自:http://dockone.io/article/431