用sudo运行jenkins管道代理

Cor*_*ool 8 jenkins docker jenkins-pipeline

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

Jenkinsfile:

pipeline {
    agent { docker 'nginx:1.11' }
    stages {
        stage('build') {
            steps {
                sh 'nginx -t'
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

> + 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
Run Code Online (Sandbox Code Playgroud)

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

luo*_*v89 13

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

...
docker run -t -d -u 107:112 ...
...
Run Code Online (Sandbox Code Playgroud)

添加:尝试多种选择,如后jenkins到sudo的用户组(它没有工作,因为jenkins用户不存在的容器),加入USER rootDockerfile...但他们没有做的伎俩.

最后,我找到了一个在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')
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 如果Jenkins没有在服务器上以root身份运行,那么您将遇到问题,因为Jenkins将无法清除其工作区.当你执行`scm checkout`时,它在容器外部完成,jenkins使用`-u`将自己的用户映射到容器中.如果您构建项目,那些文件将在本地系统上为root,并且Jenkins将在后续构建中失败. (5认同)

Saj*_*ani 5

正如其他人所建议的,问题是 jenkins 无权运行 docker 容器。让我们先回顾一下启动 jenkins 的方式,然后看看每种方式可以做什么。

1. 手动运行jenkins

当然,您可以按照此处的建议使用 java 下载并运行 jenkins 。在此方法中,您可以执行以下操作来允许 jenkins 用户使用 docker:

A。授予 jenkins 用户 root 访问权限:

我不建议这种方式,毕竟你让你的管道访问一切!所以你可能不希望这种情况发生。

b. 将 jenkins 用户添加到 docker 组

就像这里解释的那样,您可以以非 root 用户身份管理 docker。只需将您的用户添加到 docker 组即可。如果你知道谁将使用 docker,我推荐它(因为你以某种方式给了他 docker 的 root 访问权限)。

C。让docker无根

这是 docker 最近添加到其武器库中的一个新功能。您可以在这里详细阅读它的含义。老实说,我不喜欢这个功能!原因是你不能(至少我找不到办法)让它为容器中的用户工作(因为你需要停止 docker 服务才能实现它),而且我在使用时配置 dns 时遇到了一些困难无根模式。但如果你不在容器中应该没问题。

2.在docker中运行jenkins

这个方法其实比较麻烦!我对在 jenkins 容器中使用 docker 的方式苦苦挣扎,但最终得到了所需的结果,所以值得付出努力。

要在 jenkins 中运行 docker(它本身也是一个 docker 容器),您可以通过三种方式:

1.使用dind(docker中的docker)

这非常简单,您运行 dind 镜像并将 jenkins 容器中的 docker 连接到 dind,无需任何特殊权限处理,您可以随意使用 docker。

2.使用dood(docker之外的docker)

将 docker 路径挂载为 jenkins 的 docker run 脚本中的卷,请注意,您需要使用我上面解释的两种方法之一(手动运行 jenkins)才能使用 docker,这可能有点棘手但可能。

3.在不同的环境中作为docker运行代理并在jenkins中连接远程代理

最后可以单独运行代理并在 jenkins 中连接远程代理。虽然这并不能完全回答您的问题,但这是您可以使用的一种方法。

这些仅在 jenkins 中运行 docker 的方法,在运行 docker 作为代理后,您可能会遇到一些问题,例如代理容器本身存在权限问题,这很可能是由于代理的用户造成的(如果您愿意,您可以通过命令访问用户

docker exec -it [agent container id] whoami
Run Code Online (Sandbox Code Playgroud)

例如,在此示例中,代理中的用户是节点

agent { 
  docker { image 'node:14-alpine' } 
}

steps{
  sh 'npm i -g random'
}

Run Code Online (Sandbox Code Playgroud)

所以它会抛出一个错误,因为节点用户没有全局安装 npm 模块的权限(我知道,这很奇怪!)

正如luongnv89提到的,你可以像这样更改运行 docker 的用户

agent { 
  docker { image 'node:14-alpine' args '-u root' } 
}
Run Code Online (Sandbox Code Playgroud)

希望这有助于理解整个情况。


And*_*rey 1

我刚刚遇到了同样的问题。您需要将 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
Run Code Online (Sandbox Code Playgroud)

运行上述命令后,pipelines成功启动docker