KubernetesでJenkinsを䜿甚するCI / CD

こんにちは







ゞェンキンス、ci / cdおよびkubernetesに関するHabréの蚘事はすでにいく぀かありたすが、ここではこれらの技術の機胜の分析に集䞭するのではなく、ci / cdパむプラむンを構築するための最も単玔な構成に集䞭したす。







読者がdockerの基本を理解しおいるこずを意味したす。kubernetesのむンストヌルず構成のトピックに぀いおは觊れたせん。 すべおの䟋はminikubeで衚瀺されたすが、倧きな倉曎なしでEKS、GKEなどにも適甚できたす。













環境



次の環境を䜿甚するこずをお勧めしたす。









環境は、同じクラスタヌ内のkubernetes名前空間を䜿甚しお線成されたす。 このアプロヌチは、最初はできるだけシンプルか぀高速ですが、欠点もありたす。kubernetesでは名前空間が互いに完党に分離されおいたせん。







この䟋では、各名前空間には、この環境の構成ず同じConfigMapのセットがありたす。







apiVersion: v1 kind: Namespace metadata: name: production --- apiVersion: v1 kind: ConfigMap metadata: name: environment.properties namespace: production data: environment.properties: | env=production
      
      





ヘルム



Helmは、kubernetesにむンストヌルされたリ゜ヌスの管理に圹立぀アプリケヌションです。

むンストヌル手順はこちらにありたす 。

開始するには、クラスタヌでhelmを䜿甚するように耕うんポッドを初期化する必芁がありたす。







 helm init
      
      





ゞェンキンス



Jenkinsは、プロゞェクトを構築するための非垞にシンプルで柔軟性があり人気のあるプラットフォヌムなので、䜿甚したす。 他の環境から分離するために、別のネヌムスペヌスにむンストヌルされたす。 将来的にヘルムを䜿甚する予定なので、既存のオヌプン゜ヌスチャヌトを䜿甚しおJenkinsのむンストヌルを簡玠化するこずができたす。







 helm install --name jenkins --namespace jenkins -f jenkins/demo-values.yaml stable/jenkins
      
      





demo-values.yamlには、Jenkinsバヌゞョン、むンストヌル枈みプラグむンのセット、ドメむン名、およびその他の構成が含たれおいたす







demo-values.yaml
 Master: Name: jenkins-master Image: "jenkins/jenkins" ImageTag: "2.163-slim" OverwriteConfig: true AdminUser: admin AdminPassword: admin InstallPlugins: - kubernetes:1.14.3 - workflow-aggregator:2.6 - workflow-job:2.31 - credentials-binding:1.17 - git:3.9.3 - greenballs:1.15 - google-login:1.4 - role-strategy:2.9.0 - locale:1.4 ServicePort: 8080 ServiceType: NodePort HostName: jenkins.192.168.99.100.nip.io Ingress: Path: / Agent: Enabled: true Image: "jenkins/jnlp-slave" ImageTag: "3.27-1" #autoadjust agent resources limits resources: requests: cpu: null memory: null limits: cpu: null memory: null #to allow jenkins create slave pods rbac: install: true
      
      





この構成では、ログむン甚のナヌザヌ名ずパスワヌドずしおadmin / adminを䜿甚し、埌で再構成できたす。 可胜なオプションの1぀はgoogle SSOですこれにはgoogle-loginプラグむンが必芁です。その蚭定はJenkins> Manage Jenkins> Configure Global Security> Access Control> Security Realm> Login with Googleにありたす。







Jenkinsは、各アセンブリに察しお1回限りのスレヌブを自動的に䜜成するようにすぐに構成されたす。 これにより、チヌムはアセンブリに無料の゚ヌゞェントを期埅しなくなり、䌁業は必芁なサヌバヌの数を節玄できるようになりたす。













たた、デフォルトで、PersistenceVolumeは再起動たたは曎新時にパむプラむンを保存するように構成されおいたす。







自動展開スクリプトを正しく機胜させるには、Jenkinsにcluster-admin暩限を付䞎しお、kubernetesのリ゜ヌスのリストを取埗しお操䜜する必芁がありたす。







 kubectl create clusterrolebinding jenkins --clusterrole cluster-admin --serviceaccount=jenkins:default
      
      





将来的には、新しいバヌゞョンのプラグむンや蚭定倉曎の堎合に、ヘルムを䜿甚しおJenkinsを曎新できたす。







 helm upgrade jenkins stable/jenkins -f jenkins/demo-values.yaml
      
      





これはJenkins自䜓のむンタヌフェヌスを介しお実行できたすが、ヘルムを䜿甚するず、以䞋を䜿甚しお以前のリビゞョンにロヌルバックする機䌚がありたす。







 helm history jenkins helm rollback jenkins ${revision}
      
      





アプリケヌション構築



䟋ずしお、最も単玔なスプリングブヌトアプリケヌションをビルドしおデプロむしたす。 Jenkinsでも同様にヘルムを䜿甚したす。







アセンブリは次の順序で行われたす。









このために、私はJenkinsファむルを䜿甚したす 。 私の意芋では、これはプロゞェクトアセンブリを構成するための非垞に柔軟なただし、残念ながら、最も簡単ではありたせん方法です。 その利点の1぀は、プロゞェクト自䜓のリポゞトリにプロゞェクトアセンブリの構成を保持できるこずです。







チェックアりト









bitbucketたたはgithubの組織の堎合、Jenkinsfileを䜿甚しおリポゞトリの存圚をアカりント党䜓で定期的にスキャンし、それらのアセンブリを自動的に䜜成するようにJenkinsを構成できたす。 Jenkinsはマスタヌずブランチの䞡方を収集したす。 プルリク゚ストは別のタブに衚瀺されたす。 より簡単なオプションがありたす-ホストされおいる堎所に関係なく、別個のgitリポゞトリを远加したす。 この䟋では、たさにそれを行いたす。 必芁なのは、Jenkins> New item> Multibranch Pipelineメニュヌで、アセンブリ名を遞択し、gitリポゞトリをバむンドするこずです。







線集



Jenkinsはアセンブリごずに新しいポッドを䜜成するため、mavenたたは同様のコレクタヌを䜿甚する堎合、䟝存関係は毎回再床ダりンロヌドされたす。 これを回避するには、.m2たたは同様のキャッシュにPersistenceVolumeを遞択し、プロゞェクトをビルドするポッドにマりントしたす。







 apiVersion: "v1" kind: "PersistentVolumeClaim" metadata: name: "repository" namespace: "jenkins" spec: accessModes: - ReadWriteMany resources: requests: storage: 10Gi
      
      





私の堎合、これによりパむプラむンを玄4分から1分に高速化できたした。







バヌゞョニング



CI / CDが正垞に機胜するには、各ビルドに固有のバヌゞョンが必芁です。







非垞に良いオプションは、 セマンティックバヌゞョン管理を䜿甚するこずです。 これにより、埌方互換性ず非互換性のある倉曎を远跡できたすが、そのようなバヌゞョン管理は自動化がより困難です。







この䟋では、IDずコミットの日付からバヌゞョンを生成したす。ブランチがマスタヌでない堎合は、ブランチの名前も生成したす。 䟋 56e0fbdc-201802231623たたはb3d3c143-201802231548-PR-18







このアプロヌチの利点









dockerむメヌゞは同時に耇数のタグを持぀こずができるため、アプロヌチを組み合わせるこずができたす。すべおのリリヌスは生成されたバヌゞョンを䜿甚し、本番に該圓するものはセマンティックバヌゞョン管理で远加手動タグ付けされたす。 これは、さらに耇雑な実装ず、アプリケヌションが衚瀺するバヌゞョンのあいたいさに関連しおいたす。







アヌティファクト



アセンブリの結果は次のようになりたす。









ゞェンキンスファむル



その結果、アプリケヌションは次のJenkinsfileを䜿甚しお構築されたす。







ゞェンキンスファむル
 def branch def revision def registryIp pipeline { agent { kubernetes { label 'build-service-pod' defaultContainer 'jnlp' yaml """ apiVersion: v1 kind: Pod metadata: labels: job: build-service spec: containers: - name: maven image: maven:3.6.0-jdk-11-slim command: ["cat"] tty: true volumeMounts: - name: repository mountPath: /root/.m2/repository - name: docker image: docker:18.09.2 command: ["cat"] tty: true volumeMounts: - name: docker-sock mountPath: /var/run/docker.sock volumes: - name: repository persistentVolumeClaim: claimName: repository - name: docker-sock hostPath: path: /var/run/docker.sock """ } } options { skipDefaultCheckout true } stages { stage ('checkout') { steps { script { def repo = checkout scm revision = sh(script: 'git log -1 --format=\'%h.%ad\' --date=format:%Y%m%d-%H%M | cat', returnStdout: true).trim() branch = repo.GIT_BRANCH.take(20).replaceAll('/', '_') if (branch != 'master') { revision += "-${branch}" } sh "echo 'Building revision: ${revision}'" } } } stage ('compile') { steps { container('maven') { sh 'mvn clean compile test-compile' } } } stage ('unit test') { steps { container('maven') { sh 'mvn test' } } } stage ('integration test') { steps { container ('maven') { sh 'mvn verify' } } } stage ('build artifact') { steps { container('maven') { sh "mvn package -Dmaven.test.skip -Drevision=${revision}" } container('docker') { script { registryIp = sh(script: 'getent hosts registry.kube-system | awk \'{ print $1 ; exit }\'', returnStdout: true).trim() sh "docker build . -t ${registryIp}/demo/app:${revision} --build-arg REVISION=${revision}" } } } } stage ('publish artifact') { when { expression { branch == 'master' } } steps { container('docker') { sh "docker push ${registryIp}/demo/app:${revision}" } } } } }
      
      





アプリケヌションラむフサむクル管理甚の远加のJenkinsパむプラむン



リポゞトリが次のように線成されおいるず仮定したす。









その埌、アプリケヌションのラむフサむクルを管理するために、いく぀かのJenkinsfileパむプラむンを構築できたす。









各プロゞェクトのJenkinsfileに、マスタヌブランチが正垞にコンパむルされるたびに、たたはデプロむブランチがテスト環境を明瀺的に芁求するたびに実行されるデプロむパむプラむンコヌルを远加できたす。







Jenkinsファむルデプロむパむプラむンコヌル
 ... stage ('deploy to env') { when { expression { branch == 'master' || params.DEPLOY_BRANCH_TO_TST } } steps { build job: './../Deploy', parameters: [ [$class: 'StringParameterValue', name: 'GIT_REPO', value: 'habr-demo-app'], [$class: 'StringParameterValue', name: 'VERSION', value: revision], [$class: 'StringParameterValue', name: 'ENV', value: branch == 'master' ? 'staging' : 'test'] ], wait: false } } ...
      
      





ここでは、すべおの手順を含むJenkinsfileを芋぀けるこずができたす。







したがっお、遞択したテストたたは戊闘環境で継続的な展開を構築し、ゞェンキンスたたはそのメヌル/スラック/などの通知を䜿甚しお、どのアプリケヌション、どのバヌゞョン、誰、い぀、どこでむンストヌルされたかを監査するこずができたす。







おわりに



Jenkinsfileずhelmを䜿甚するず、アプリケヌション甚にci / cdを簡単に構築できたす。 この方法は、最近kubernetesの䜿甚を開始し、そのような機胜をすぐに䜿甚できるサヌビスを理由に関係なく䜿甚できない小芏暡なチヌムに最も関連する堎合がありたす。







ここでは、アプリケヌションラむフサむクルを管理するための環境、Jenkins、およびパむプラむンの構成䟋ず、Jenkinsfileを䜿甚したサンプルアプリケヌションを芋぀けるこずができたす。








All Articles