Jenkinsstudy2018 juc2018 takamii228

553784f5490e80cde79ef80ee70b5ed2?s=47 takamii228
September 23, 2018

Jenkinsstudy2018 juc2018 takamii228

#JenkinsStudy #juc2018 @takamii228

553784f5490e80cde79ef80ee70b5ed2?s=128

takamii228

September 23, 2018
Tweet

Transcript

  1. 2.

    自己紹介 • @takamii228 ◦ SIerのAgile開発を頑張る部署に所属 ◦ 認定スクラムマスター ◦ アジャイル開発における開発基盤整備やプロジェクト支援に従事 •

    なんでもやる雑食エンジニア ◦ CI/CD環境構築、アーキ設計、 AWS設計、Scrum運営、チームビルディング ◦ 仕事でよく使う言語は Java ( Spring )、PHP ( Laravel ) ◦ 開発基盤(GitLab, Jenkins, Mattermost, JIRA, Conflu等) on k8sを運用中 
  2. 4.

    とあるプロジェクトの、何の数字でしょうか? • 491 ◦ 商用環境へデプロイするJenkinsジョブの実行回数( 約1年間 ) • 1592 ◦

    検証環境へデプロイするJenkinsジョブの実行回数( 約2年間 ) • 1991 ◦ クローズされたPull Requestの数( 約2年間 )
  3. 13.

    【参考】OpenAPI Specification(Swagger) REST APIを記述するための規格 • OpenAPI Initiativeが企画 • YAMLファイルでAPI定義を記述する 主要なツール

    • Swagger Editor(エディタ) • Swagger UI(ビュワー) • Swagger Codegen(コード生成ツール)
  4. 15.

    使用したソフトウェアやライブラリ バックエンド フロントエンド 言語 Java PHP フレームワーク Spring Boot -

    ライブラリ Spring Cloud Swagger Codegen Flyway など SwaggerCodegen テストフレームワーク JUnit Spock PHPUnit
  5. 23.

    Multibranch Pipelineとtag push GitBucket / GitLabとMultiBranch Pipelineではtag push契機でジョブが実行されないため、 release/x.y.z branch

    の pushの中でtag pushを実行するようにした GitBucket : https://int128.hatenablog.com/entry/2016/10/06/224444 GitLab : https://takamii.hatenablog.com/entry/2018/07/09/001337 def releaseVersion = env.BRANCH_NAME.startsWith('release/') ? env.BRANCH_NAME.substring('release/'.length()) : null if(releaseVersion){ def userRemoteConfig = scm.userRemoteConfigs.head() withCredentials([usernameColonPassword(credentialsId: userRemoteConfig.credentialsId, variable: 'GIT_CREDENTIAL')]) { def url = userRemoteConfig.url.replace('://', "://${env.GIT_CREDENTIAL}@") sh 'git config user.email gituser@example.com' sh 'git config user.name gituser' sh "git tag -f $releaseVersion" sh "git push $url $releaseVersion -f" sh "git push $url --delete ${env.BRANCH_NAME}" }  }
  6. 31.

    スローテスト問題に対する解決策(1/2) SpringのテストのMockのDIの仕方を改善し、テストケースの実行速度を向上 Field InjectionからConstructor InjectionにしてApplication Contextの再ロード時間を削減 // Field Injection方式 class

    UserInfoServiceSpec extends ServiceSpec { @Autowired UserInfoService userInfoService; @TestConfiguration static class MockConfig { final detachedMockFactory = new DetachedMockFactory() @Bean UserInfoService pointInfoService() { detachedMockFactory.Mock(UserInfoService) } ... //Constructor Injection方式 class UserInfoServiceSpec extends ServiceSpec implements ConstructorInjectionHelper { UserInfoService userInfoService = Mock() def setup() { UserInfoService = newInstanceWithMocks(UserInfoService) } ... https://int128.hatenablog.com/entry/2017/02/16/224842
  7. 33.

    【参考】Jenkinsfileによる並列ジョブ実行 parallelディレクティブで並列実行ジョブを定義できる parallel( apiA: { node { checkout scm stage('test')

    { withEnv(rdsEnv()) { sh './gradlew apiA:check' } } } }, apiB: { node { checkout scm stage('test') { withEnv(rdsEnv()) { sh './gradlew apiB:check' } } } }, batch: { node { checkout scm stage('test') { withEnv(rdsEnv()) { sh './gradlew batch:check' } } } }, } ) https://int128.hatenablog.com/entry/2017/07/12/131402
  8. 34.

    2.ビルドのゴミが溜まってDiskフルが発生問題 問題 • Jenkinsのディスク容量が不足してジョブ実行に失敗した • ビルドログ、Dockerビルドのゴミが残留していた ◦ Docker Buildを使っている場合はイメージのゴミが残り続ける 対処

    • 【暫定】ビルド結果を定期的に削除する設定を追加した • 【恒久】Jenkinsに対して1TBのEBSをアタッチ(お金で解決) ◦ Docker Build部分はAWS CodeBuildに移行した
  9. 37.

    なぜここまで頻繁に商用デプロイできたのか? • JenkinsのCI/CDパイプラインを本格開発前に準備できていた ◦ アーキテクチャが本格開発前に固まっていた ◦ CI/CDパイプラインはコーディングの本格開始前までに準備しておくべき • AWSを使うことで検証環境と商用環境をほぼ差分なく構築できた ◦

    AWSとAnsible使うことでImmutable Infrastractureが構築できた ◦ 差分はあってもインスタンスタイプや環境変数程度だった • 検証環境で実績を積んだJenkinsジョブを商用環境にそのまま利用できた ◦ 検証環境で成功が保証されたものを商用環境でもそのまま利用できた
  10. 43.

    JenkinsのHelm Chart 公式のHelm Chartが用意されている https://github.com/helm/charts/tree/master/stable/jenkins helmfileにPodやJenkinsのdefault設定を上書く設定を記述する - name: jenkins namespace:

    devops chart: stable/jenkins values: - Master: HostName: jenkins.{{ requiredEnv "kubernetes_ingress_domain" }} resources: {requests: {cpu: 50m, memory: 256Mi}, limits: {cpu: 2000m, memory: 4096Mi}} ServiceType: ClusterIP InstallPlugins: - workflow-aggregator:2.5 - credentials-binding:1.16 - git:3.9.1 - gitlab-plugin:1.5.8 - mattermost:2.5.0 - keycloak:2.2.0 Persistence: Size: 50Gi
  11. 44.

    JenkinsをKubernetes上で動かす2つの方法 1. Jenkins Master、Agent共にKubernetes上のPodで動かす ◦ AgentのPodはビルド実行単位で起動させる ◦ Agent Podの設定はKubernetes Plugin経由で設定する

    2. Jenkins MasterのみKubernetes上で動かしてAgentはk8s外で実行する ◦ Agentを従来のAgentサーバで実行する ◦ AWS CodeBuild、GCP CloudBuildなどのクラウドビルドサービスを使う 設定が容易でスケールメリットもあるAWS CodeBuildを採用
  12. 45.

    【参考】AWS CodeBuild AWSが提供するマネージドのコンテナビルドサービス • 指定したランタイムのコンテナイメージによるビルドを実行する • AWS ECRに登録した自作のコンテナイメージも使える • 最大20並列で実行できる

    • かかる費用はビルド時間単位の従量課金制 • Jenkinsからはプラグイン経由でビルド実行できる https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-awsjenkins
  13. 47.

    AWS CodeBuild のかゆいところ • GitLab / GitBucketからは直接連携できないため間に Jenkinsが必要 ◦ 逆にJenkinsを間に挟むことてGit

    Push単位での実行が可能になる • ブランチ制御できないためMultibranch Pipelineと相性が悪い ◦ ブランチの情報を環境変数で渡して if文で制御する //buildspec.yml …. package: commands: - | if [ -z "${BRANCH_NAME%%release/*}" ]; then ./package.sh fi artifacts: commands: - | if [ -z "${BRANCH_NAME%%release/*}" ]; then aws s3 cp artifacts "s3://bucket/${BRANCH_NAME#release/}/artifacts" fi https://github.com/takami228/jenkins-awscodebuild-starter //Jenkinsfile …. stages { stage('codebuild') { steps { awsCodeBuild( credentialsType: 'keys', projectName: 'projectName', region: 'aws-region', sourceControlType: 'project', sourceVersion: env.BRANCH_NAME, envVariables: "[{BRANCH_NAME,${env.BRANCH_NAME}}]", ) } }
  14. 48.
  15. 49.

    参考資料 • @takamii228 ◦ つばくろぐ : https://takamii.hatenablog.com/ ◦ SpeakerDeck :

    https://speakerdeck.com/takamii228 • @int128 ◦ GeekFactory : https://int128.hatenablog.com/ ◦ SpeakerDeck : https://speakerdeck.com/int128
  16. 50.

    ライセンス • The Jenkins logo is licensed under the Creative

    Commons Attribution-ShareAlike 3.0 Unported License. (https://jenkins.io/) • AWS(Amazon Web Services)は、米国その他の諸国における、 Amazon.com, Inc.またはその関連会社の商標です • Dockerは、Docker、Inc.の米国およびその他の国における商標または登録商標です • Mattermostは、Mattermost, Inc. の登録商標です • SonarQubeは、SonarSource S.A.及びその子会社、関連会社の商標または登録商標です • Ansibleは、米国およびその他の国において登録された Red Hat, Inc.の商標です • JIRA、Confluenceは、豪州およびその他の国における Atlassian および/またはその関連会社の登録商標または商標です • The GitLab logo and wordmark artwork are licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.(https://gitlab.com/gitlab-com/gitlab-artwork/blob/master/README.md)