web-dev-qa-db-ja.com

sudoでjenkinsパイプラインエージェントを実行する

Dockerコンテナで実行しているJenkins Serverがあり、ホストシステムのdockerにアクセスできますが、これまでのところうまく機能しています。ここで、Dockerコンテナ内のスクリプトをテストするパイプラインをセットアップします。

Jenkinsfile:

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

エラーメッセージ:

> + 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でコマンドを実行しているエージェントを言う方法は?

8
CordlessWool

同じ問題に直面しました。コンソールログを分析した結果、Docker Jenkinsプラグインが特定のオプション-u 107:112で新しいコンテナーを開始することが理由であることがわかりました。

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

次のような多くのオプションを試した後、jenkinsをSudoグループに追加します(jenkinsユーザーがコンテナに存在しないため機能しませんでした)、USER root into Dockerfile、...しかし、それらのどれもトリックを行いません。

最後に、docker agentargsを使用して-オプションを上書きするソリューションを見つけました。これは私の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')
        }
    }
}

ここにはセキュリティの問題があるかもしれませんが、私の場合は問題ではありません。

13
luongnv89

コンテナ内のjenkinsグループIDを、ボリュームをマウントしたdockerソケットのグループIDと一致させて、問題を別の方法で解決します。ルートとして実行し、ソケットのgidを検索し、現在のコンテナー内のgidのそれと一致しない場合、コンテナー内でそれを修正するgroupmodを実行するエントリポイントを使用してこれを行います。次に、jenkinsユーザーに権限をドロップして、Jenkinsを起動します。このエントリポイントはすべてのスタートアップで実行されますが、起動されるJenkinsアプリに対してはかなり透過的に実行されます。

これを実行するすべての手順は、このgithubリポジトリに含まれています。 https://github.com/Sudo-bmitch/jenkins-docker/

4
BMitch

次の方法で回避できます。

1- Dockerfileでsudoersファイルにジェンキンを追加します。

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

2- Jenkinsfileに追加のステップを追加して、ジェンキンに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 /"
            }

        }

    }
}
3
Nezar Fadle

私のために働いたのは

node() {
    String jenkinsUserId = sh(returnStdout: true, script: 'id -u jenkins').trim()
    String dockerGroupId = sh(returnStdout: true, script: 'getent group docker | cut -d: -f3').trim()
    String containerUserMapping = "-u $jenkinsUserId:$dockerGroupId "
    docker.image('image')
        .inside(containerUserMapping + ' -v /var/run/docker.sock:/var/run/docker.sock:ro') {
             sh "..."
         }
}

この方法では、コンテナ内のユーザーは引き続きjenkinsユーザーID +グループIDを使用して、共有データとの権限の競合を回避しますが、Dockerソケット(/var/run/docker.sockへのアクセスに必要なコンテナー内のdockerグループのメンバーでもあります)

追加のスクリプトやdockerfilesを必要としないため、このソリューションを好む

2
Hillkorn

私はちょうど同じ問題を抱えていました。 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

上記を実行すると、パイプラインが正常にドッカーを開始します

1
Andrey

私はこれに対してかなり良い解決策を見つけたかもしれません。

セットアップ

Jenkinsをコンテナーとして実行し、それを使用して、実行中のdockerhostでコンテナーを構築します。これを行うには、/var/run/docker.sockをボリュームとしてコンテナーに渡します。

免責事項を繰り返しますが、他の人々はすでに述べています:Dockerソケットへのアクセスを許可することは、基本的にマシンへのルートアクセスを許可することに似ています-注意してください!

Jenkins Imageには既にdockerがインストールされていると思います。

解決

これは、Dockerバイナリが$PATHの最初のディレクトリにないという事実に基づいています。基本的に、単純なdockerコマンドの代わりにSudo 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サービスユーザーは、sudoを使用してrootとしてdockerバイナリを実行できます(パスワードを入力しなくても)。次に、スクリプトを/usr/local/bin/dockerにコピーします。これは、実際のバイナリを「オーバーレイ」し、Sudoで実行します。役立つ場合は、 Github の私の例をご覧ください。

1
Maurice

ここで同じ問題。

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

したがって、次善策として、パイプラインのビルドステージのステップの1つとして追加します。

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