首页 文章

用sudo运行jenkins管道代理

提问于
浏览
3

我有一个在Docker容器中运行的Jenkins服务器,并且可以访问docker和主机系统,到目前为止它运行良好 . 现在我想在docker容器中设置一个测试脚本的管道 .

Jenkinsfile:

pipeline {
    agent { docker 'nginx:1.11' }
    stages {
        stage('build') {
            steps {
                sh 'nginx -t'
            }
        }
    }
}

Error Message:

> + docker pull nginx:1.11
> 
> Warning: failed to get default registry endpoint from daemon (Got
> permission denied while trying to connect to the Docker daemon socket
> at unix:///var/run/docker.sock: Get
> http://%2Fvar%2Frun%2Fdocker.sock/v1.29/info: dial unix
> /var/run/docker.sock: connect: permission denied). Using system
> default: https://index.docker.io/v1/
> 
> Got permission denied while trying to connect to the Docker daemon
> socket at unix:///var/run/docker.sock: Post
> http://%2Fvar%2Frun%2Fdocker.sock/v1.29/images/create?fromImage=nginx&tag=1.11:
> dial unix /var/run/docker.sock: connect: permission denied
> 
> script returned exit code 1

我的问题是jenkins需要使用sudo运行docker命令,但是如何说使用sudo运行命令的代理?

6 回答

  • 1

    你可以解决这个问题:

    1-在_293776中将jenkins添加到sudoers文件中:

    RUN echo "jenkins ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

    2-在 Jenkinsfile 中添加一个额外步骤,为jenkins提供使用docker的正确权限:

    pipeline {
    
        agent none
    
        stages {
    
            stage("Fix the permission issue") {
    
                agent any
    
                steps {
                    sh "sudo chown root:jenkins /run/docker.sock"
                }
    
            }
    
            stage('Step 1') {
    
                agent {
                    docker {
                        image 'nezarfadle/tools'
                        reuseNode true
                    }
                }
    
                steps {
                    sh "ls /"
                }
    
            }
    
        }
    }
    
  • 2

    我'd solve the problem differently, matching the jenkins group id inside the container to that of the docker socket you'已安装了一个卷 . 我使用以root身份运行的入口点,查找套接字的gid,如果这与当前容器中的gid不匹配,它会在容器内部进行更正 groupmod . 然后我将权限下放给 jenkins 用户以启动Jenkins . 此入口点在每次启动时运行,但对启动的Jenkins应用程序相当透明 .

    执行此操作的所有步骤都包含在此github仓库中:https://github.com/sudo-bmitch/jenkins-docker/

  • 0

    我遇到了同样的问题 . 在分析了控制台日志之后,我发现原因是Docker Jenkins插件启动了一个带有特定选项 -u 107:112 的新容器:

    ...
    docker run -t -d -u 107:112 ...
    ...
    

    尝试了很多选项后,例如:将 jenkins 添加到sudo组(由于 jenkins 用户在容器中不存在而无法正常工作),将 USER root 添加到 Dockerfile ,...但是没有一个能够解决问题 .

    最后,我找到了一个在 docker agent 中使用 args 来覆盖 -u 选项的解决方案 . 这是我的 Jenkinsfile

    pipeline {
        agent {
            docker {
                image 'ubuntu'
                args '-u root:sudo -v $HOME/workspace/myproject:/myproject'
            }
        }
        stages {
            stage("setup_env") {
                steps {
                    sh 'apt-get update -y'
                    sh 'apt-get install -y git build-essential gcc cmake make'
                }
            }
    
            stage("install_dependencies") {
                steps {
                    sh 'apt-get install -y libxml2-dev'
                }
            }
            stage("compile_dpi") {
                steps {
                    sh 'cd /myproject && make clean && make -j4'
                }
            }
    
            stage("install_dpi") {
                steps {
                    sh 'cd /myproject && make install'
                }
            }
    
            stage("test") {
                steps {
                    sh 'do some test here'
                }
            }
        }
        post {
            success {
                echo 'Do something when it is successful'
                bitbucketStatusNotify(buildState: 'SUCCESSFUL')
            }
            failure {
                echo 'Do something when it is failed'
                bitbucketStatusNotify(buildState: 'FAILED')
            }
        }
    }
    

    这里可能存在安全问题,但在我的案例中并不是问题 .

  • 0

    我可能已经找到了一个相当不错的解决方案 .

    设置

    我将Jenkins作为容器运行,并使用它在正在运行的dockerhost上构建容器 . 为此,我将 /var/run/docker.sock 作为卷传递给容器 .

    Just to reiterate the disclaimer some other people already stated: Giving access to the docker socket is essentially like giving root access to the machine - be careful!

    我假设你已经在你的Jenkins Image中安装了docker .

    解决方案

    这是基于这样一个事实,即docker二进制文件不在 $PATH 的第一个目录中 . 我们基本上放置一个运行 sudo docker 的shell脚本,而不仅仅是普通的 docker 命令(并传递参数) .

    将这样的文件添加到您的jenkins存储库并将其命名为 docker_sudo_overwrite.sh

    #! /bin/sh 
    # This basically is a workaround to add sudo to the docker command, because aliases don't seem to work 
    # To be honest, this is a horrible workaround that depends on the order in $PATH
    # This file needs to be place in /usr/local/bin with execute permissions
    sudo /usr/bin/docker $@
    

    然后像这样扩展你的Jenkins Dockerfile

    # Now we need to allow jenkins to run docker commands! (This is not elegant, but at least it's semi-portable...)
    USER root
    
    ## allowing jenkins user to run docker without specifying a password
    RUN echo "jenkins ALL=(ALL) NOPASSWD: /usr/bin/docker" >> /etc/sudoers
    
    # Create our alias file that allows us to use docker as sudo without writing sudo
    COPY docker_sudo_overwrite.sh /usr/local/bin/docker
    RUN chmod +x /usr/local/bin/docker
    
    # switch back to the jenkins-user
    USER jenkins
    

    这使jenkins服务用户能够以root用户身份运行docker二进制文件(不提供密码) . 然后我们将我们的脚本复制到 /usr/local/bin/docker ,"overlays"实际二进制文件并使用 sudo 运行它 . 如果它有帮助,你可以在Github上查看我的例子 .

  • 9

    我刚才有同样的问题 . 您需要将jenkins用户添加到docker组:

    DOCKER_SOCKET=/var/run/docker.sock
    DOCKER_GROUP=docker
    JENKINS_USER=jenkins
    
    if [ -S ${DOCKER_SOCKET} ]; then
    DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCKET})
    sudo groupadd -for -g ${DOCKER_GID} ${DOCKER_GROUP}
    sudo usermod -aG ${DOCKER_GROUP} ${JENKINS_USER}
    fi
    
    # Start Jenkins service
    sudo service jenkins restart
    

    运行上面的操作后,管道成功启动了docker

  • 0

    同样的问题在这里 .

    [...]
    agent { docker 'whatever_I_try_doesnt_work'} # sudo, jenkins user in dockerroot group etc
    [...]
    

    所以我的解决方法是将其添加为管道构建阶段中的一个步骤,如下所示:

    pipeline {
        agent any
        stages {
            stage('Build') {
                steps {
                    sh 'sudo docker pull python:3.5.1'
                }
            }
        }
    }
    

相关问题