mito’s blog

IT技術メインの雑記。思い立ったが吉日。

[Jenkins] パイプラインをDockerコンテナで動かす

はじめに

JenkinsをDokerコンテナで動かすのではなく、JenkinsのパイプラインをDockerコンテナで実行します。


環境

  • Jenkins : 2.332.2
  • OS : AmazonLinux 2 (Master、Node同様)
  • Docker : 20.10.13
  • DockerImage : amazonlinux


ノードの構築

SSH経由でエージェントを起動する場合の手順です。

認証情報に設定したSSHユーザで、Jenkinsのパイプラインがノード上で実行されるため、 dockerグループにSSHユーザを追加します。

# usermod -aG docker ec2-user
# cat /etc/group | grep docker
docker:x:992:ec2-user
# systemctl enable docker
# shutdown -r now

なお、私の環境では再起動しないと反映されませんでした。


Jenkins サーバの設定

DockerPipelineプラグインを追加します。

Docker Pipeline | Jenkins plugin


Jenkins パイプライン

JenkinsパイプラインをDockerコンテナで起動する
  • Jenkinsfile
pipeline {
    agent {
        docker { 
            image 'amazonlinux:latest'
        }
    }

    stages {
        stage('ステージ名') {
            steps {
                echo "ローソンストア100のジンジャーエールがおいしい!"
            }
        }
    }
}


  • 実行結果
    • 起動したDockerコンテナは停止、削除されます
      • Dockerコンテナを起動した後のstageで失敗した場合でも、Dockerコンテナは削除されます
    • ノードにイメージは残ります
Started by user user
[Pipeline] Start of Pipeline
[Pipeline] node
Running on node in /home/ec2-user/workspace/Docker
[Pipeline] {
[Pipeline] isUnix
[Pipeline] withEnv
[Pipeline] {
[Pipeline] sh
+ docker inspect -f . amazonlinux:latest
.
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] withDockerContainer
node does not seem to be running inside a container
$ docker run -t -d -u 1000:1000 -w /home/ec2-user/workspace/Docker -v /home/ec2-user/workspace/Docker:/home/ec2-user/workspace/Docker:rw,z -v /home/ec2-user/workspace/Docker@tmp:/home/ec2-user/workspace/Docker@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** amazonlinux:latest cat
$ docker top 5be09e55754851fa822ec7fd9494aed94cec7bdbcfe48d107ac6d3ed77c90ce5 -eo pid,comm
[Pipeline] {
[Pipeline] stage
[Pipeline] { (ステージ名)
[Pipeline] echo
ローソンストア100のジンジャーエールがおいしい!
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
$ docker stop --time=1 5be09e55754851fa822ec7fd9494aed94cec7bdbcfe48d107ac6d3ed77c90ce5
$ docker rm -f 5be09e55754851fa822ec7fd9494aed94cec7bdbcfe48d107ac6d3ed77c90ce5
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
amazonlinux   latest    ecdeb69c57ad   2 weeks ago   164MB


Jenkinsパイプラインで起動したDockerコンテナに、パッケージをインストールする
  • Jenkinsfile
    • amazonlinuxのイメージにsudoコマンドは入っていないため、rootでコンテナに入ります
pipeline {
    agent {
        docker { 
            image 'amazonlinux:latest'
            args '-u root'
        }
    }

    stages {
        stage('pkg install') {
            steps {
                sh "yum install -y git"
                sh "git --version"
            }
        }
    }
}


  • 実行結果
Started by user user
[Pipeline] Start of Pipeline
[Pipeline] node
Running on node in /home/ec2-user/workspace/Docker
[Pipeline] {
[Pipeline] isUnix
[Pipeline] withEnv
[Pipeline] {
[Pipeline] sh
+ docker inspect -f . amazonlinux:latest
.
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] withDockerContainer
node does not seem to be running inside a container
$ docker run -t -d -u 1000:1000 -u root -w /home/ec2-user/workspace/Docker -v /home/ec2-user/workspace/Docker:/home/ec2-user/workspace/Docker:rw,z -v /home/ec2-user/workspace/Docker@tmp:/home/ec2-user/workspace/Docker@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** amazonlinux:latest cat
$ docker top ea88ffef7d44b9a47d302bb5bc6296fd90c14ac18285f08006deafbf28cca12e -eo pid,comm
[Pipeline] {
[Pipeline] stage
[Pipeline] { (pkg install)
[Pipeline] sh
+ yum install -y git
()

Installed:
  git.x86_64 0:2.32.0-1.amzn2.0.1                                               
()
Complete!
[Pipeline] sh
+ git --version
git version 2.32.0
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
$ docker stop --time=1 ea88ffef7d44b9a47d302bb5bc6296fd90c14ac18285f08006deafbf28cca12e
$ docker rm -f ea88ffef7d44b9a47d302bb5bc6296fd90c14ac18285f08006deafbf28cca12e
[Pipeline] // withDockerContainer
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS


Dockerコンテナ内でgitコマンドが実行されない不具合

[JENKINS-30600] git isn't run inside build container - Jenkins Jira

パイプラインでcheckoutしようとして、この不具合に遭遇しました。
実行できるときもあったので色々試した結果、ジョブ実行時にワークスペースを削除しておくことで 発生しなくなりました(今のところは)

Warning: JENKINS-30600: special launcher org.jenkinsci.plugins.docker.workflow.WithContainerStep$Decorator$1@70e52eb7;
 decorates RemoteLauncher[hudson.remoting.Channel@f2265c7:node] will be ignored 
(a typical symptom is the Git executable not being run inside a designated container)

ノードのワークスペースにcheckoutしたファイルがあったから(ノードで実行してからコンテナにコピーしている)、このファイルを削除してパイプラインでcheckoを実行したけど、失敗しました。わからん。


その他

コンテナからコンテナを操作する方法って、DinDだけでなくDooDやDaemon-less Image Builderもあると知って。