34

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 セッションを root として実行すると

docker exec -u 0 -ti cocky_mccarthy bash
root@5dbd0efad2b0:/# docker info
Containers: 42
Images: 50
...

dockerしたがって、Jenkins ユーザーを追加するグループは、内部ドッカーのグループであると推測されるため、ソケットがないと読み取れませんsudo。Jenkins docker プラグインなどが使用するように設定されていないため、これは一種の問題sudoです。

イメージから使用できるようにソケットをマウントするにはどうすればよいsudoですか?

4

2 に答える 2

27

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

ここでの問題は、docker ホスト上のグループが、コンテナー内dockerのグループの ID とは異なるグループ ID を持っていることです。dockerデーモンはグループの名前ではなく ID のみを気にするため、ソリューションはこれらの ID が偶然一致した場合にのみ機能します。

これを解決する方法は、 Docker エンジンの起動時に-H オプションを使用して、UNIX ソケットを使用する代わりに tcp を使用することです。これには細心の注意を払う必要があります。これにより、このポートにアクセスできる人なら誰でもシステムへの root アクセスを取得できるようになります。

これを修正するより安全な方法は、コンテナー内のグループがコンテナー外のグループdockerと同じグループ ID を持つようにすることです。dockerのビルド引数を使用してこれを行うことができます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 に非 root としてアクセスできます

docker run \ 
  -v /var/run/docker.sock:/var/run/docker.sock \ 
  -p 8080:8080 \
  -ti my-jenkins-image

このソリューションは、イメージのビルド時に docker デーモンに正しいグループ ID を提供することに依存しているため、このイメージは、それが使用されているマシン上でビルドする必要があります。イメージをビルドしてプッシュし、他の誰かが自分のマシンでそれをプルすると、グループ ID が再び一致しなくなる可能性があります。

于 2017-01-10T17:36:12.110 に答える
5

私はあなたの 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
于 2016-03-25T14:43:52.480 に答える