Docker in Docker

因為之前要把 jenkins 放在 docker 當中, 而 jenkins 要運行的 jobs 又用到了 docker. 所以研究了一下如何在 docker 中使用 docker. 方法主要有兩個, 以下會介紹一下.

  • 使用官方提供的docker image
  • 使用 host 的 docker binary 和 socket

1. 使用官方提供的docker image

docker 官方提供了一個 docker image: https://hub.docker.com/_/docker/
他的概念就是把 主要的 docker (server) 放在一個獨立的 container 中, 然後把其他要用到 docker 的 container 連接 docker (server). 建立了 client <-> server 的關係. 當你要做 docker 的操作時, 就會通過 client 控制 docker (server). 只要是連接到同一個 docker (server) 的 container 都可以看到相同的資訊 (有甚麼 image / 有甚麼 container 正在運行等等).

連結當中的使用方法十分清楚, 我就不多說了.

這個方法有以下幾個特點:

  • 可以有多個的 docker server
  • docker server 的狀態和 host 的 docker 狀態各自獨立
  • 所有要操作 docker (server) 的 image 都要建基於 docker 所提供的 image. 假設今天你有一個應用, 它會用到 docker. 那你在為他建立 image (寫 Dockerfile) 時, 要以狀態中的 image 為基本. 當然, 你可以參考他的做法, 然後自行實現.

2. 使用 host 的 docker binary 和 socket

若果你不想建立一個專門放 docker 的 container, 直接用 host 的 docker 也可以的話, 可以參考這一個方法.

做法也不困難, 只是把 host 的 docker binary 和 socket 與要用 docker 的 container blind 在一起.

以下用整合 jenkins 和 docker 為例子. 注意一下, libsystemd-journal0libapparmor-dev 是 docker 會用到 share library. 有時候會因為環境不同的問題, 而找不到. 如果在整合時沒有任何問題, 不安裝也是可以的.

另外, jenkins 在操作 docker 時一定要加入 sudo. 有高手知道如何能不用 sudo 的話, 請務必指教一下在下,

Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM jenkins:2.0

MAINTAINER KitFung <kitfung@oursky.com>

USER root
RUN apt-get update \
&& apt-get install -y sudo libsystemd-journal0 libapparmor-dev \
&& rm -rf /var/lib/apt/lists/*
RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
RUN groupadd docker \
&& gpasswd -a jenkins docker

USER jenkins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt

在建立 container 時用以下指令

start.sh
1
2
3
4
5
docker run -d -p 8080:8080 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/usr/bin/docker \
-v $(which docker-compose):/usr/bin/docker-compose \
kitfung/jenkins_in_docker

當成功運行 jenkins 時, 可以建立一個 job. 運行 sudo docker run hello-world 去試驗一下是否成功.

最後放上我整合 docker 和 jenkins 的repo https://github.com/KitFung/jenkin_in_docker