在(Docker里的)Jenkins里運行Docker

jopen 9年前發布 | 31K 次閱讀 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.596

USER 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”,你將看到類似如下內容:

    在(Docker里的)Jenkins里運行Docker

    好極了!我們已經在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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!