つばくろぐ @takamii228

知は力なり

Jenkinsユーザ・カンファレンス東京2018に参加しました #jenkinsstudy #juc2018

f:id:takamii228:20180924211237p:plain

3年ぶりの開催となるJenkinsユーザ・カンファレンス東京2018に参加・登壇発表してきました。

jenkins.jp

私の発表

speakerdeck.com

以前参画していたプロジェクトでの成果をJenkinsの話題を中心にまとめて話しました。

発表の内容は一緒のプロジェクトに参画していた@int128さんの成果がベースなのですが、うまく自分で咀嚼して資料にまとめて発表できたのかなと思います。

50分の枠でしたが、30分くらいで終わってしまって残りは質疑でつなぎました。質疑も活発に出てよかったです。

思いの外会場が広くて緊張しましたが、なんとか無事終わってよかったです。

基調講演①

基調講演ではCloudBees, Inc. CTOの川口さん( @kohsukekawa )より最新のJenkinsにおけるプロジェクトに関して5つ紹介がありました。

1. Jenkins Pipeline

JenkinsのジョブをJenkinsflieで定義して管理・運用するやり方です。FreeStyleよりも管理性が高まります。

2016年に公開されてから利用者は100倍近くに増えたそうです。

BlueOceanを使ったパイプラインは将来的にはJenkinsのコアな部分として統合したいとのことです。

2. Jenkins Evergreen

jenkins.io

Jenkins Evergreenは「Jenkinsのジョブを5分ないし5クリック以内に実行できる」ことを目標にしているJenkinsをより使いやすくするプロジェクトらしい。

Jenkins環境をChromeのように自動アップデートさせるような構想もあるらしい。

3. Jenkins Configuration as Code

jenkins.io

Jenkinsの設定をすべてコードで管理するという構想らしい。ちょうど最近1.0が出た模様。

github.com

これはぜひ触ってみたい。

Jenkinsやプラグインの設定があるYamlとジョブ定義があるJenkinsfileがあれば瞬時に設定済みのJenkinsが作れるしアップデートも楽になりそう。

4. CloudNative Jenkins

JenkinsをGKE、EKS、AKS等のマネージドk8s上で動かすことで運用をより簡易にするプロジェクト。

例えばAWSの場合はArtifactをS3において、ログがCloudWatchLogsに転送されるような感じ。

jenkins.io

5. Jenkins X

jenkins.io

Kubernetes環境でのCI/CDを楽にできるようにするツールの立ち位置。

Kuberentes周りは群衆割拠でついていくのが大変だ・・・。

まとめ

紹介されたプロジェクトは1.x系のFreeStyleジョブの時代と比べて大きく変貌をとげており、川口さんの言葉通り「Jenkinsは昔と違って進化している」、ということを実感しました。

基調講演②

もう一つの基調講演はJenkins Xの開発者である James Rawlings さんの公演でした。

JenkinsXを使ったデモではGitOpsでKubernetes上のStaging環境やProduction環境へ自動でCDされる様子を見せてくれました。

Kubernetes周りのCI/CDはまだまだ未調査なのでJenkinsX以外にどんなものがあるのか、JenkinsXがどういう利点があるのかを調べてみようかなと思います。

発表の中で紹介されていた「Accelarate」という本の翻訳版がもうすぐ出るらしいので読まねば。

Accelerate: The Science Behind Devops: Building and Scaling High Performing Technology Organizations

Accelerate: The Science Behind Devops: Building and Scaling High Performing Technology Organizations

LeanとDevOpsの科学[Accelerate] テクノロジーの戦略的活用が組織変革を加速する (impress top gear)

LeanとDevOpsの科学[Accelerate] テクノロジーの戦略的活用が組織変革を加速する (impress top gear)

その他の発表

以下資料を引用します。資料はあとで公式ブログにアップにもアップされるようです。

slides.com

www.slideshare.net

www.slideshare.net

speakerdeck.com

www.slideshare.net

www.slideshare.net

Twiitter実況

参加者が多かったのか、会場にWiFIと机があったからか実況も活発だったと思います。

togetter.com

私の発表に関するフィードバックもあって嬉しかったです。

まとめ

正直、近年のCI/CDの事例を見てるとGitHub + CircleCIと各社パブリッククラウドのマネージドサービスを使ったデリバリーをよく目にするので、Jenkins大丈夫なのかなという一抹の不安を抱えていました。

でも川口さんの公演やみなさんの発表を聞いて、FreeStyleでポチポチ設定してたJenkinsに始まり、PipelineスクリプトでGitOpsがさらに進み、今後はCloudNativeやKubernetes対応でさらに進化するであろうJenkinsの未来を感じることができました。

このような素晴らしいイベントでの発表の機会をくださったJenkinsユーザ会のみなさん、運営のみなさんありがとうございました。

XP祭りでLT発表した #xpjug

9/8(土)にXP祭りに参加してきました。昨年に引き続き2回目の参加です。

XP祭り2018

午前中予定があったので基調講演は欠席したんですが、評判を聞くところによるとかなり損をしたようで凹みました・・・。

今回はLT発表を申し込んで発表してきました。

実は昨年も発表する気満々だったのですが、タイトル考えている間に枠が埋まってしまって断念してしまった、という経緯があります笑

今年は募集開始と同時に申し込みました。その結果まさかのトリでの発表でした😱

speakerdeck.com

また、恒例の献本は「進化的アーキテクチャ」をいただきました。読んで勉強します!

運営のみなさんもお疲れ様でした。

来年もよろしくお願いいたします。

Jenkins Agentの運用が辛いのでAWS CodeBuildを使う

Jenkins Agentの運用のつらみ

ピーク時に数十人が同時に使うような大きめなプロジェクトでJenkinsをMaster / Agent構成で利用していると以下のようなつらみがあります。

  • 開発が活発な時はビルドキューが溜まってJenkinsのビルドの待ち時間が発生する
  • 開発が落ち着いている時はAgentが遊んでいてサーバの稼働費用が無駄
  • 長期間運用しているとAgentサーバのツールバージョンアップ等のメンテがつらい

PushトリガーによるCI/CD環境を構築すると開発が盛り上がってるときには1日に数十回Jenkins上でビルドが走ります。Pull Requestを投げた後にビルド中にトイレに行って返ってきたら、他の人が先にマージされてて自分のPRにConflictが発生してると「またビルドを待つのか...😇」という残念気持ちになりますよね。

Agentサーバを増やすという解決策もありますがビルドサーバ分のお金がかかりますし、開発の盛り上がりに合わせて手動で上げたり下げたり都度Jenkinsの設定するのも面倒です。

GitHub + CircleCI使えばいいって?

大人の事情で使えない人もいるんですよ!!!

本記事ではこんな課題を持っている人のために、JenkinsからAWS CodeBuildを利用する方法を紹介します。

※注意事項

本記事で紹介する内容は2018年9月7日時点での内容をもとに記載しており、今後のAWSのアップデートによっては最適な解決策でなくなる場合があります。

AWS CodeBuildとは

f:id:takamii228:20180906234114p:plain

AWS CodeBuildはAWSが提供するマネージドのコンテナビルドサービスです。詳細は公式のページに記載されていますが、要点を抜粋すると以下のような特徴があります。

  • 指定したランタイムのコンテナイメージによるコンテナビルドを実行してくれる
  • AWS ECRに登録した自作のコンテナイメージも指定できる
  • 最大20並列でコンテナビルドできる
  • かかる費用はビルド時間単位の従量課金

CodeBuildはマネージドサービスのため運用コストの削減が期待できます。

また費用はビルド時間単位の従量課金制のため、Jenkins AgentとしてEC2を常時複数台起動させておくよりもコスト削減が望めます。

何より、最大20並列で実行できるためビルドの待ち時間をほぼなくすことができます!!!

ビルドで利用するコンテナイメージはAWSでデフォルトで用意されているものがありますが、ランタイムのバージョンが実環境のものと違っていたりモジュールが不足してたりするため、CI/CDで実行する内容に合わせて独自のイメージを作ってECRに登録して使うとよいでしょう。

GitLabとJenkinsとAWS CodeBuildの連携

私の環境ではレポジトリとしてGitLabを使っているので、以下のような構成で連携しています。

Jenkinsのビルドの定義をJenkinsfileに、AWS CodeBuildのビルド定義をbuildspec.ymlに記載してソースレポジトリと一緒に管理しています。

f:id:takamii228:20180906234505p:plain

GitLabへのPushやMerge RequestをトリガーにJenkinsが実行され、Jenkinsで実行されるビルドの中でAWS CodeBuildを実行します。

JenkinsからAWS CodeBuildを呼び出すのはJenkinsのAWS CodeBuild Pluginを使います。これを使うことでAWS CodeBuildのログもJenkins側のログから見ることができます。

github.com

AWS CodeBuildのかゆいところ

次に上記の構成で実際に使ってみてハマった点やTipsを紹介します。

AWS CodeBuildのArtifactはブランチに対応してない

AWS CodeBuildではビルドの成果物をArtifactとして定義することでS3に置いてくれる機能を持っています。しかし、この機能はブランチによる分岐ができません。 そのためJenkinsのMultibranch Pipelineで使う場合には毎回ArtifactがS3にPutされてしまいます。

仕方ないので、Jenkinsfileの中でブランチの情報を環境変数AWS CodeBuildに連携して、ブランチ名を見て分岐してaws s3コマンドでS3にPutするようにしています。

Jenkinsfile

    ...
    stages {
        stage('codebuild') {
            steps {
                awsCodeBuild(
                    credentialsType: 'keys',
                    projectName: 'projectName', 
                    region: 'ap-northeast-1', 
                    sourceControlType: 'project',
                    sourceVersion: env.BRANCH_NAME,
                    envVariables: "[{BRANCH_NAME,${env.BRANCH_NAME}}]",
                )
            }
        }
    ...

buildspec.yml

...
phases:
  ...
  build:
    commands:
      - ./build.sh
      - ./test.sh
  package:
    commands:
      - |
        if [ -z "${BRANCH_NAME%%release/*}" ]; then
          ./package.sh
        fi
  post-package:
    commands:
      - |
        if [ -z "${BRANCH_NAME%%release/*}" ]; then
          aws s3 cp /path/to/artifacts "s3://path_to_artifacts_bucket/${BRANCH_NAME#release/}/artifacts"
        fi
...

GitLabから直接AWS CodeBuildは呼べない

現在AWS CodeBuildのレポジトリとして公式にサポートしているのはAWS CodeCommit、GitHub、BitBucketのみです。

GitLab、GitBucket等のオンプレ向けのGitホスティングサービスとは、GitHub Enterpriseを選択することで連携できていますが、当然WebHookから直接起動することはできません。

逆に言えば、間にJenkinsを間に挟むことでレポジトリへのPushやPull/Merge Request契機でAWS CodeBuildを実行することができるようになっています。

GitBucketとGitLabにはIssueは立っていますが、まだ取り込まれてはいないようです。

並列数の設定をお忘れなく

同時実行できるビルド数はビルドプロジェクトで定義するCompute Typeによって変わります。そのため強いCompute Typeを使う場合は別途上限緩和申請が必要となります。

  • 同時実行ビルドの最大数の制限は、コンピューティングタイプによって異なります。一部のコンピューティングタイプでは、デフォルトは 20 です。新規アカウントの場合、この制限は 1 ~ 5 です。同時ビルドの制限の引き上げをリクエストするには、または「アカウントのアクティブなビルドは X 以上持つことはできません」というエラーが発生した場合は、AWS サポートに連絡してください。

またAWS CodeBuildの並列数はJenkinsの同時ビルド実行数に依存するので、Jenkins側の設定でMasterノードの同時実行数の設定を忘れないようにしましょう。

Cacheを使ってビルド時間を削減する

AWS CodeBuildは実行時間単位で課金されるため、なるべく実行時間が少なくなるような工夫が必要です。

AWS CodeBuildにはビルドでキャッシュしたいフォルダをS3に定義できるので、モジュールやテスト結果等キャッシュ可能な内容はcacheディレクティブに定義しておくと良いでしょう。

buildspec.yml

...
cache:
  paths:
    - /path/to/cache/*

終わりに

Jenkinsを運用する上で、ビルドで待ち時間が発生する・Agentサーバのメンテナンスコストがかかるという課題に対する解決策として、AWS CodeBuildを活用する事例を紹介しました。

JenkinsをAWSで運用している方はぜひ参考にしてみてください。

github.com

おまけ

先日ちょうど @moznion ( id:moznion ) さんもほぼ同じ発表されててとても親近感を感じました。

こちらではAWS CodeBuildに加えてAWS EFS を使う例も紹介されています。

moznion.hatenadiary.com

参考資料