1
votes

I try to run Docker inside my Jenkins slave container on Centos7.1. This are the steps I performed in my dockerfile:

FROM java:8
ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000
RUN groupadd -g ${gid} ${group} \
&& useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user}
RUN groupadd -g 983 docker \
&& gpasswd -a ${user} docker

So I have a user jenkins (id1000) in a group jenkins (gid1000) + in a group docker (gid983). Why did I chose gid 983? Well if I check /etc/group on my host I see:

docker:x:983:centos

In my docker-compose script I'm mounting my docker socket so that's why I used the same gid as on my host.

Part of docker-compose:

volumes:
  - /var/run/docker.sock:/var/run/docker.sock
  - /usr/bin/docker:/usr/bin/docker

When I exec inside my container as root:

root@c4af16c386d7:/var/jenkins_home# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
jenkins-slave       1.0                 94a5d6606f86        10 minutes 
jenkins             2.7.1               b4974ba62598        3 weeks ago         741 MB
java                8-jdk               264282a59a95        7 weeks ago         669.2 MB

But as jenkins user:

Cannot connect to the Docker daemon. Is the docker daemon running on this host?

In my container:

cat /etc/passwd
jenkins:x:1000:1000::/var/jenkins_home:/bin/bash

cat /etc/group
jenkins:x:1000:
docker:x:983:jenkins

Addition:

$ docker exec -it ec52d4125a02 bash
root@ec52d4125a02:/var/jenkins_home# whoami
root
root@ec52d4125a02:/var/jenkins_home# su jenkins
jenkins@ec52d4125a02:~$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                      NAMES
a23521523249        jenkins:2.7.1       "/bin/tini -- /usr/lo"   20 minutes ago      Up 20 minutes       0.0.0.0:8080->8080/tcp, 0.0.0.0:32777->22/tcp, 0.0.0.0:32776->50000/tcp    jenkins-master
ec52d4125a02        jenkins-slave:1.0   "setup-sshd"             20 minutes ago      Up 20 minutes       0.0.0.0:32775->22/tcp, 0.0.0.0:32774->8080/tcp, 0.0.0.0:32773->50000/tcp   jenkins-slave

but:

$ docker exec -it -u jenkins ec52d4125a02 bash
jenkins@ec52d4125a02:~$ docker ps
Cannot connect to the Docker daemon. Is the docker daemon running on this host?

In the first case my jenkins user:

uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins),983(docker)

In the second case:

uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins)
1
You're missing several key pieces needed to be able to recreate your issue. In particular, the FROM line in your Dockerfile. I've done something similar with the main differences that my Jenkins image does an install of Docker rather than mount the executable and my commands are debian based. Is your $DOCKER_HOST variable defined inside your container? - BMitch
The variable isn't defined. I actually try to use docker as jenkinsuser in a jenkins-slave which I create with docker compose. It's just a container with java and SSH-access which has a jenkins-user + group and mounted docker volumes. It does not really contain jenkins in the dockerfile (it comes from the master). I've added my FROM + I don't use that variable. - lvthillo
@BMitch I also added an addition to my question. - lvthillo
I ran your Dockerfile in my lab. Running with the jenkins user shows gid 983 in the output of id. Can't reproduce your problem. - BMitch

1 Answers

0
votes

First, why do you need to spin containers from inside another with Jenkins? Here's why this is not a good idea.

Having that said and you still want to go ahead. First thing is that there are several steps you need to take to run Docker inside a Docker container. For example, have you started this container in --priviledged mode?

You should try using Jerome Petazzoni's Docker in Docker as it does everything you need.

You can then combine DInD's stuff with a Jenkins installation. Here's an example that I've put together by mashing up Jerome's DInD with other things and assembling a docker container that has Jenkins, Docker Compose and other useful stuff:

Dockerfile:

FROM ubuntu:xenial
ENV UBUNTU_FLAVOR xenial

#== Ubuntu flavors - common
RUN  echo "deb http://archive.ubuntu.com/ubuntu ${UBUNTU_FLAVOR} main universe\n" > /etc/apt/sources.list \
  && echo "deb http://archive.ubuntu.com/ubuntu ${UBUNTU_FLAVOR}-updates main universe\n" >> /etc/apt/sources.list

MAINTAINER Rogério Peixoto

ENV JENKINS_HOME /var/jenkins_home
ENV JENKINS_SLAVE_AGENT_PORT 50000

ARG user=jenkins
ARG group=jenkins
ARG uid=1000
ARG gid=1000

# Jenkins is run with user `jenkins`, uid = 1000
# If you bind mount a volume from the host or a data container,
# ensure you use the same uid
RUN groupadd -g ${gid} ${group} \
&& useradd -d "$JENKINS_HOME" -u ${uid} -g ${gid} -m -s /bin/bash ${user}

 # useful stuff.
 RUN apt-get update -q && apt-get install -qy \
    apt-transport-https \
    ca-certificates \
    curl \
    lxc \
    supervisor \
    zip \
    git \
    iptables \
    locales \
    nano \
    make \
    openssh-client \
    openjdk-8-jdk-headless \
  && rm -rf /var/lib/apt/lists/*

# Install Docker from Docker Inc. repositories.
RUN curl -sSL https://get.docker.com/ | sh

# Install the wrapper script from https://raw.githubusercontent.com/docker/docker/master/hack/dind.
ADD ./wrapdocker /usr/local/bin/wrapdocker
RUN chmod +x /usr/local/bin/wrapdocker

# Define additional metadata for our image.
VOLUME /var/lib/docker

ENV JENKINS_VERSION 2.8
ENV JENKINS_SHA 4d83a40319ecf4eaab2344a18c197bd693080530

RUN mkdir -p /usr/share/jenkins/ \
  && curl -SL http://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war -o /usr/share/jenkins/jenkins.war
# RUN echo "$JENKINS_SHA  /usr/share/jenkins/jenkins.war" | sha1sum -c -

ENV JENKINS_UC https://updates.jenkins.io
RUN mkdir -p /usr/share/jenkins/ref \
  && chown -R ${user} "$JENKINS_HOME" /usr/share/jenkins/ref

RUN usermod -a -G docker jenkins
ENV DOCKER_COMPOSE_VERSION 1.8.0-rc1

# Install Docker Compose
RUN curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose

RUN apt-get install -y python-pip && pip install supervisor-stdout

EXPOSE 8080
EXPOSE 50000

ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD ["/usr/bin/supervisord"]

supervisord.conf

[supervisord]
nodaemon=true

[program:docker]
priority=10
command=wrapdocker
startsecs=0
exitcodes=0,1

[program:chown]
priority=20
command=chown -R jenkins:jenkins /var/jenkins_home
startsecs=0

[program:jenkins]
priority=30
user=jenkins
environment=JENKINS_HOME="/var/jenkins_home",HOME="/var/jenkins_home",USER="jenkins"
command=java -jar /usr/share/jenkins/jenkins.war
stdout_events_enabled = true
stderr_events_enabled = true

[eventlistener:stdout]
command=supervisor_stdout
buffer_size=100
events=PROCESS_LOG
result_handler=supervisor_stdout:event_handler

You can get wrapdocker file here

Put all that in the same directory and build it:

docker build -t my_dind_jenkins .

Then run it:

docker run -d --privileged \ 
    --name=master-jenkins \
    -p 8080:8080 \
    -p 50000:50000 my_dind_jenkins