如何使用除root以外的其他用户从容器访问docker守护进程

我正在尝试运行构builddocker镜像的Jenkins容器。 我上个星期就开始使用docker,而且我对使用主机的卷以及用户的处理方式有些困惑。

我一直在互联网上search,我发现一个git问题是有人发布了一个解决scheme,从容器中访问docker守护进程。 基本上,这个想法是在Jenkins容器中docker.sock包含docker.sock bin文件夹和来自主机的docker.sock的卷,如下所示:

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

我已经完成了这个工作,但只有当我是根。 当我开始学习docker的时候,我在博客中关注了这个例子,作者不是直接使用jenkins镜像,而是从jenkins镜像本身及其依赖关系中复制了Dockerfiles来解释这个过程。 作为这个过程的一部分,一个jenkins用户被创build,并且它是在启动容器时使用的。 我现在的问题是,我不能让jenkins用户有权访问docker.sock因为它属于root和组中的docker.sock 。 我试图在Dockerfile中添加用户docker,但是在访问docker.sock时,仍然从Jenkins作业中获得了权限被拒绝的错误。 如果我检查在容器中挂载的/var/run/docker.sock ,我可以看到, docker.sock属于组user而不是docker.sock ,所以我不知道挂载目录时到底发生了什么。 我没有用Linux的工作太多,所以我的猜测是用户docker不存在,当目录被挂载,然后它使用默认的user但我可能是完全错误的。

另一件我仍然没有得到的是,如果我创build一个专门用作Jenkins容器的容器,并且没有别的东西应该在那里运行,那么创build特定jenkins用户的目的是什么? 有没有什么原因,我不能直接使用用户的root

这是我使用的Dockerfile。 谢谢。

 FROM centos:7 # Yum workaround to stalled mirror RUN sed -i -e 's/enabled=1/enabled=0/g' /etc/yum/pluginconf.d/fastestmirror.conf RUN rm -f /var/lib/rpm/__* RUN rpm --rebuilddb -v -v RUN yum clean all # see https://bugs.debian.org/775775 # and https://github.com/docker-library/java/issues/19#issuecomment-70546872 ENV CA_CERTIFICATES_JAVA_VERSION 20140324 RUN yum -v install -y \ wget \ zip \ which \ openssh-client \ unzip \ java-1.8.0-openjdk-devel \ git \ && yum clean all #RUN /var/lib/dpkg/info/ca-certificates-java.postinst configure # Install Tini ENV TINI_VERSION 0.9.0 ENV TINI_SHA fa23d1e20732501c3bb8eeeca423c89ac80ed452 # Use tini as subreaper in Docker container to adopt zombie processes RUN curl -fsSL https://github.com/krallin/tini/releases/download/v${TINI_VERSION}/tini-static -o /bin/tini && chmod +x /bin/tini \ && echo "$TINI_SHA /bin/tini" | sha1sum -c - # SET Jenkins Environment Variables ENV JENKINS_HOME /var/jenkins_home ENV JENKINS_SLAVE_AGENT_PORT 50000 ENV JENKINS_VERSION 2.22 ENV JENKINS_SHA 5b89b6967e7af8119c52c7e86223b47665417a22 ENV JENKINS_UC https://updates.jenkins-ci.org ENV COPY_REFERENCE_FILE_LOG $JENKINS_HOME/copy_reference_file.log # SET Java variables ENV JAVA_HOME /usr/lib/jvm/java/jre ENV PATH /usr/lib/jvm/java/bin:$PATH # 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 useradd -d "$JENKINS_HOME" -u 1000 -m -s /bin/bash jenkins #Not working. Folder not yet mounted? #RUN DOCKER_GID=$(stat -c '%g' /var/run/docker.sock) && \ #Using gid from host RUN groupadd -for -g 50 docker && \ usermod -aG docker jenkins # Jenkins home directory is a volume, so configuration and build history # can be persisted and survive image upgrades VOLUME /var/jenkins_home # `/usr/share/jenkins/ref/` contains all reference configuration we want # to set on a fresh new installation. Use it to bundle additional plugins # or config file with your custom jenkins Docker image. RUN mkdir -p /usr/share/jenkins/ref/init.groovy.d # Install Jenkins RUN curl -fL 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 \ && echo "$JENKINS_SHA /usr/share/jenkins/jenkins.war" | sha1sum -c - ENV JAVA_OPTS="-Xmx8192m" ENV JENKINS_OPTS="--logfile=/var/log/jenkins/jenkins.log --webroot=/var/cache/jenkins/war" # Prep Jenkins Directories RUN chown -R jenkins "$JENKINS_HOME" /usr/share/jenkins/ref RUN mkdir /var/log/jenkins RUN mkdir /var/cache/jenkins RUN chown -R jenkins:jenkins /var/log/jenkins RUN chown -R jenkins:jenkins /var/cache/jenkins # Expose Ports for web and slave agents EXPOSE 8080 EXPOSE 50000 # Copy in local config files COPY init.groovy /usr/share/jenkins/ref/init.groovy.d/tcp-slave-agent-port.groovy COPY jenkins.sh /usr/local/bin/jenkins.sh COPY plugins.sh /usr/local/bin/plugins.sh RUN chmod +x /usr/local/bin/plugins.sh RUN chmod +x /usr/local/bin/jenkins.sh # Install default plugins COPY plugins.txt /tmp/plugins.txt RUN /usr/local/bin/plugins.sh /tmp/plugins.txt # Add ssh key RUN eval "$(ssh-agent -s)" RUN mkdir /usr/share/jenkins/ref/.ssh && \ chmod 700 /usr/share/jenkins/ref/.ssh && \ ssh-keyscan github.com > /usr/share/jenkins/ref/.ssh/known_hosts COPY id_rsa /usr/share/jenkins/ref/.ssh/id_rsa COPY id_rsa /usr/share/jenkins/ref/.ssh/id_rsa.pub COPY hudson.tasks.Maven.xml /usr/share/jenkins/ref/hudson.tasks.Maven.xml RUN chown -R jenkins:jenkins /usr/share/jenkins/ref && \ chmod 600 /usr/share/jenkins/ref/.ssh/id_rsa && \ chmod 600 /usr/share/jenkins/ref/.ssh/id_rsa.pub && \ chmod 600 /usr/share/jenkins/ref/hudson.tasks.Maven.xml COPY id_rsa /root/.ssh/id_rsa COPY id_rsa /root/.ssh/id_rsa.pub # ssh keys for root. To use root as the user RUN chmod 600 /root/.ssh/id_rsa && \ chmod 600 /root/.ssh/id_rsa.pub && \ ssh-keyscan github.com > /root/.ssh/known_hosts # Switch to the jenkins user USER jenkins # Tini as the entry point to manage zombie processes ENTRYPOINT ["/bin/tini", "--", "/usr/local/bin/jenkins.sh"] 

显然这个问题是在gid中。 出于某种原因,我认为在主机上的组的docker gid是50但实际上它实际上是100.当我改变它为100时,jenkins工作开始工作。 我仍然不知道为什么docker.sock显示它属于组user而不是容器中的docker 。 如果我在容器中看到cat /etc/group

 root:x:0: ... users:x:100: ... jenkins:x:1000: docker:x:100:jenkins 

并在主机

 root:x:0: lp:x:7:lp nogroup:x:65534: staff:x:50:docker docker:x:100:docker dockremap:x:101:dockremap