web-dev-qa-db-ja.com

正しいグループを使用して、ドッカーコンテナのボリュームとしてドッカーソケットをマウントする方法

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?なしでイメージから使用できるようにソケットをマウントするにはどうすればよいですか?

22
Ollie Edwards

少し遅れますが、これは同じ問題に苦しんでいる他のユーザーを助けるかもしれません:

ここでの問題は、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が再び一致しない可能性があります。

15
eawenden

あなたの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
5
lvthillo