Docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock

后端 未结 30 1564
孤独总比滥情好
孤独总比滥情好 2020-11-27 09:00

I am new to docker. I just tried to use docker in my local machine(Ubuntu 16.04) with Jenkins.

I configured a new job with below pipeline script.



        
相关标签:
30条回答
  • 2020-11-27 09:40

    often need a reboot to take effect on the new user group and user.

    0 讨论(0)
  • 2020-11-27 09:42

    2019-05-26

    This worked for me !

    Example docker-compose:

    version: "3"
    services:
      jenkins:
        image: jenkinsci/blueocean
        privileged: true
        ports:
          - "8080:8080"
        volumes:
          - $HOME/learning/jenkins/jenkins_home:/var/jenkins_home
        environment:
          - DOCKER_HOST=tcp://socat:2375
        links:
          - socat
    
      socat:
         image: bpack/socat
         command: TCP4-LISTEN:2375,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock
         volumes:
            - /var/run/docker.sock:/var/run/docker.sock
         expose:
            - "2375"
    
    0 讨论(0)
  • 2020-11-27 09:44

    Simply adding docker as a supplementary group for the jenkins user

    sudo usermod -a -G docker jenkins
    

    is not always enough when using a Docker image as the Jenkins Agent. That is, if your Jenkinsfile starts with pipeline{agent{dockerfile or pipeline{agent{image:

    pipeline {
        agent {
            dockerfile {
                filename 'Dockerfile.jenkinsAgent'
            }
        }
        stages {
    
    

    This is because Jenkins performs a docker run command, which results in three problems.

    • The Agent will (probably) not have the Docker programs installed.
    • The Agent will not have access to the Docker daemon socket, and so will try to run Docker-in-Docker, which is not recommended.
    • Jenkins gives the numeric user ID and numeric group ID that the Agent should use. The Agent will not have any supplementary groups, because docker run does not do a login to the container (it's more like a sudo).

    Installing Docker for the Agent

    Making the Docker programs available within the Docker image simply requires running the Docker installation steps in your Dockerfile:

    # Dockerfile.jenkinsAgent
    FROM debian:stretch-backports
    # Install Docker in the image, which adds a docker group
    RUN apt-get -y update && \
     apt-get -y install \
       apt-transport-https \
       ca-certificates \
       curl \
       gnupg \
       lsb-release \
       software-properties-common
    
    RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
    RUN add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/debian \
       $(lsb_release -cs) \
       stable"
    
    RUN apt-get -y update && \
     apt-get -y install \
       docker-ce \
       docker-ce-cli \
       containerd.io
    
    ...
    

    Sharing the Docker daemon socket

    As has been said before, fixing the second problem means running the Jenkins Docker container so it shares the Docker daemon socket with the Docker daemon that is outside the container. So you need to tell Jenkins to run the Docker container with that sharing, thus:

    pipeline {
        agent {
            dockerfile {
                filename 'Dockerfile.jenkinsAgent'
                args '-v /var/run/docker.sock:/var/run/docker.sock'
            }
        }
    
    

    Setting UIDs and GIDs

    The ideal fix to the third problem would be set up supplementary groups for the Agent. That does not seem possible. The only fix I'm aware of is to run the Agent with the Jenkins UID and the Docker GID (the socket has group write permission and is owned by root.docker). But in general, you do not know what those IDs are (they were allocated when the useradd ... jenkins and groupadd ... docker ran when Jenkins and Docker were installed on the host). And you can not simply tell Jenkins to user user jenkins and group docker

    args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'
    

    because that tells Docker to use the user and group that are named jenkins and docker within the image, and your Docker image probably does not have the jenkins user and group, and even if it did there would be no guarantee it would have the same UID and GID as the host, and there is similarly no guarantee that the docker GID is the same

    Fortunately, Jenkins runs the docker build command for your Dockerfile in a script, so you can do some shell-script magic to pass through that information as Docker build arguments:

    pipeline {
        agent {
            dockerfile {
                filename 'Dockerfile.jenkinsAgent'
                additionalBuildArgs  '--build-arg JENKINSUID=`id -u jenkins` --build-arg JENKINSGID=`id -g jenkins` --build-arg DOCKERGID=`stat -c %g /var/run/docker.sock`'
                args '-v /var/run/docker.sock:/var/run/docker.sock -u jenkins:docker'
            }
        }
    

    That uses the id command to get the UID and GID of the jenkins user and the stat command to get information about the Docker socket.

    Your Dockerfile can use that information to setup a jenkins user and docker group for the Agent, using groupadd, groupmod and useradd:

    # Dockerfile.jenkinsAgent
    FROM debian:stretch-backports
    ARG JENKINSUID
    ARG JENKINSGID
    ARG DOCKERGID
    ...
    # Install Docker in the image, which adds a docker group
    RUN apt-get -y update && \
     apt-get -y install \
       apt-transport-https \
       ca-certificates \
       curl \
       gnupg \
       lsb-release \
       software-properties-common
    
    RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
    RUN add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/debian \
       $(lsb_release -cs) \
       stable"
    
    RUN apt-get -y update && \
     apt-get -y install \
       docker-ce \
       docker-ce-cli \
       containerd.io
    
    ...
    # Setup users and groups
    RUN groupadd -g ${JENKINSGID} jenkins
    RUN groupmod -g ${DOCKERGID} docker
    RUN useradd -c "Jenkins user" -g ${JENKINSGID} -G ${DOCKERGID} -M -N -u ${JENKINSUID} jenkins
    
    0 讨论(0)
  • 2020-11-27 09:45

    On the server where Jenkins is running, I used

    sudo setfacl -m user:tomcat:rw /var/run/docker.sock
    

    And then run each docker container with

    -v /var/run/docker.sock:/var/run/docker.sock
    

    Using setfacl seems a better option, and no "-u user" is needed. The containers then run as the same user that is running Jenkins. But I would appreciate any feedback from the security experts.

    0 讨论(0)
  • 2020-11-27 09:47

    Change the access permission of the docker.sock file

    chmod 777 /var/run/docker.sock
    

    or u can use sudo in the start of the command.

    chmod 777 will allow all actions for all users while chmod 666 will allow all users to read and write but cannot execute the file.

    0 讨论(0)
  • 2020-11-27 09:47

    Step 1: add your username to the docker group:

    sudo usermod -a -G docker $USER
    

    Then logout and login again.

    Step 2: Then change docker group ID :

    newgrp docker
    
    0 讨论(0)
提交回复
热议问题