DockerコンテナでJenkinsインスタンスを実行したい。
Jenkins自体が、テストを実行するスレーブとしてdockerコンテナーを起動できるようにしたいのです。
これを行う最良の方法は、使用することです
docker run -v /var/run.docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image
私が使用しているDockerfile
は
FROM jenkins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt
USER root
RUN apt-get update && apt-get install -y docker.io
RUN usermod -aG docker jenkins
USER jenkins
実行中のコンテナでbashセッションを開始し、docker info
私のイメージで私が得る
$ docker info
FATA[0000] Get http:///var/run/docker.sock/v1.18/info: dial unix /var/run/docker.sock: permission denied. Are you trying to connect to a TLS-enabled daemon without TLS?
そして、ルートとしてbashセッションを実行すると
docker exec -u 0 -ti cocky_mccarthy bash
root@5dbd0efad2b0:/# docker info
Containers: 42
Images: 50
...
したがって、Jenkinsユーザーを追加しているdocker
グループは内部dockerのグループであるため、ソケットはSudo
なしでは読み取りできません。 Jenkins dockerプラグインなどがSudo
を使用するように設定されていないため、これは一種の問題です。
Sudo
?なしでイメージから使用できるようにソケットをマウントするにはどうすればよいですか?
少し遅れますが、これは同じ問題に苦しんでいる他のユーザーを助けるかもしれません:
ここでの問題は、Dockerホストのdocker
グループが、コンテナ内のdocker
グループのIDとは異なるグループIDを持っていることです。デーモンはグループの名前ではなくIDのみを対象とするため、これらのIDが誤って一致した場合にのみソリューションが機能します。
これを解決する方法は、Dockerエンジンの起動時に -Hオプション を使用してUNIXソケットを使用する代わりにtcpを使用することです。これには非常に注意する必要があります。
これを修正するより安全な方法は、コンテナ内のdocker
グループが、コンテナ外のdocker
グループと同じグループIDを持つようにすることです。これを行うには、docker build
のビルド引数を使用します。
Dockerfile:
FROM jenkinsci
ARG DOCKER_GROUP_ID
USER root
RUN curl -o /root/docker.tgz https://get.docker.com/builds/Linux/x86_64/docker-1.12.5.tgz && tar -C /root -xvf /root/docker.tgz && mv /root/docker/docker /usr/local/bin/docker && rm -rf /root/docker*
RUN curl -L https://github.com/docker/compose/releases/download/1.7.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose
RUN groupadd -g $DOCKER_GROUP_ID docker && gpasswd -a jenkins docker
USER jenkins
そして、それを使用して構築する
docker build --build-arg DOCKER_GROUP_ID=`getent group docker | cut -d: -f3` -t my-jenkins-image .
この後、イメージを実行し、非ルートとしてdockerにアクセスできます
docker run -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 -ti my-jenkins-image
このソリューションは、イメージの作成時に正しいグループIDをdockerデーモンに提供することに依存しているため、このイメージは使用されているマシンでビルドする必要があります。イメージを作成し、それをプッシュし、他の誰かがそれをマシン上でプルすると、グループIDが再び一致しない可能性があります。
あなたのdockerfileを使用しましたが、小さな編集をしました:
FROM jenkins
COPY plugins.txt /usr/share/jenkins/plugins.txt
RUN /usr/local/bin/plugins.sh /usr/share/jenkins/plugins.txt
USER root
RUN apt-get update
RUN groupadd docker && gpasswd -a jenkins docker
USER jenkins
イメージをビルドした後、使用して開始できます(centos7を使用しています)。
docker run -d \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/usr/bin/docker:ro \
-v /lib64/libdevmapper.so.1.02:/usr/lib/x86_64-linux-gnu/libdevmapper.so.1.02 \
-v /lib64/libudev.so.0:/usr/lib/x86_64-linux-gnu/libudev.so.0 \
-p 8080:8080 \
--name jenkins \
--privileged=true -t -i \
test/jenkins
イメージ内にパッケージdocker.ioをインストールしようとしました。ただし、このパッケージはホスト上にもあります(そうしないと、その上でdockerコンテナーを実行することはできません)。したがって、Dockerファイルにインストールするのではなく、これをコンテナにマウントすることをお勧めします。マウントされた/ lib64/...はCentos 7固有のものだと思います。
$ docker exec -it 9fc27d5fcec1 bash
jenkins@9fc27d5fcec1:/$ whoami
jenkins
jenkins@9fc27d5fcec1:/$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9fc27d5fcec1 test "/bin/tini -- /usr/lo" 6 minutes ago Up 6 minutes 0.0.0.0:8080->8080/tcp, 50000/tcp jenkins