Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜

CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜

Kubernetes 環境での CI/CD の方法は色々考えることがありますが、今回は KubeCon + CloudNativeCon 2017 で聞いてきた沢山の CI/CD のセッションと、CyberAgent でのいくつかの実例を含めながら、最小公倍数?最大公約数?的なお話をさせていただきました。
付録として、CI/CD 周りで興味深かったセッションと Keynote をまとめてあります。
@市ヶ谷Geek★Night #16 Kubernetes Christmas!

De266761b955b2636e454a1bc7a99ed4?s=128

Masaya Aoyama (@amsy810)

December 20, 2017
Tweet

Transcript

  1. CI/CD Pipeline を考える 〜KubeCon 2017 + CyberAgent の最大公倍数〜 @市ヶ谷Geek★Night #16

    Kubernetes Christmas!
  2. 青山 真也 (Masaya Aoyama) @amsy810 普段の主な仕事↓ 世界で 138 番目 https://adtech.cyberagent.io/techblog/

    archives/3086
  3. KubeCon で聞いてきた CI/CD セッション(抜粋) Keynote • Cloud Native CD: Spinnaker

    and the Culture Behind the Tech • KubeCon Opening Keynote - Project Update Sessions • Using Containers for Continuous Integration and Continuous Delivery • Deploying to Kubernetes Thousands of Times Per/Day • Continuous Delivery with Kubernetes at Box • Microservices, Service Mesh, and CI/CD Pipelines: Making It All Work Together • Building Better Containers: A Survey of Container Build Tools • GitOps - Operations by Pull Request
  4. GitHub k8s YAML manifest GitHub Application Code dev stg prd

    dev stg prd リポジトリの構成 リポジトリはマイクロサービス毎に分ける リポジトリは Code と Manifest で分割 • 厳密には同リポジトリでディレクトリを分割も可 • ただし、同居は CI/CD の際にハンドリングが不便 Manifest には実際に適用されている YAML を保存 • テンプレートだと現状のクラスタがわかりにくい
  5. GitHub k8s YAML manifest GitHub Application Code dev stg prd

    dev stg prd ブランチの構成 dev, stg, prd ブランチは ・Namespace にマッピングさせる or ・Kubernetes Cluster にマッピングさせる ブランチの Manifest の状態 = クラスタの状態  (マージされたタイミングで自動反映)
  6. GitHub k8s YAML manifest GitHub Application Code stg prd stg

    prd CI/CD Pipeline の例 ① Code の stg ブランチに対して PR を出してマージされる
  7. GitHub k8s YAML manifest GitHub Application Code stg prd stg

    prd CI/CD Pipeline の例 ② Code:stg のマージをきっかけに、   Manifest を自動生成して Manifest:stg へ自動マージ   Docker Image のビルドと Registry に Push
  8. GitHub k8s YAML manifest GitHub Application Code stg prd stg

    prd CI/CD Pipeline の例 ③ Manifest:stg ブランチへのマージ   = stg クラスタ or NS への反映 stg クラスタの状態 prd クラスタの状態
  9. GitHub k8s YAML manifest GitHub Application Code stg prd stg

    prd CI/CD Pipeline の例 ④ Code を stg から prd にマージ ⑤ Manifest が自動生成されて Manifest:prd に PR
  10. GitHub k8s YAML manifest GitHub Application Code stg prd stg

    prd CI/CD Pipeline の例 ⑥ Manifest:prd の PR がマージされたタイミングで  prd クラスタに反映
  11. GitHub k8s YAML manifest GitHub Application Code dev stg prd

    dev stg prd CI/CD Pipeline の例 厳密には ・dev が自動マージする程度 ・stg が prd 前の E2E / Performance Test の場 ・prd が本番
  12. GitHub k8s YAML manifest GitHub Application Code dev stg prd

    dev stg prd その他ベストプラクティス • Entrypoint を設定してそのまま起動可能にする • 設定は ConfigMap や Secret に寄せる ◦ 設定は Env や ConfigMap で渡すだけ • 脱 Dockerfile ◦ 別のツールで生成しましょう • local / dev / prd で同じイメージを利用する • Commit と Image Tag を紐付ける ◦ ロールバックを容易に • Manifest の Validation を行なう ◦ K8s のリソース文法的、意図的内容
  13. GitHub k8s YAML manifest GitHub Application Code dev stg prd

    dev stg prd その他ベストプラクティス • latest タグは使わない • local でビルドして push はしない(自動化必須) • kubectl は基本的に使わない • Replica 数は Manifest YAML に書かない ◦ Scale は Manifest で行わない • テスト等も行いマージしやすい仕組みづくり ◦ Performance Test, E2E
  14. その他印象に残っている話 Spinnaker のロードマップ • CI にも力を入れていく • CD 定義をコード化可能に •

    デプロイ定義の抽象化 Canary Release の一方法 • PR が出たら Canary リリース • マージされたら Deploy
  15. is coming soon... 来年はココらへんの話で発表したい! 「GKE 互換のオンプレコンテナ基盤 AKE (Adtech Container Engine)」

    https://developers.cyberagent.co.jp/blog/archives/12058/ 「Kubernetes をいじって Hardware LoadBalancer で “type LoadBalancer” を実装」 https://adtech.cyberagent.io/techblog/archives/3127 「オンプレでも GKE Like な Ingress を使うために 自作 Ingress Controller を実装」 https://adtech.cyberagent.io/techblog/archives/3758
  16. 参考付録

  17. 4: Cloud Native CD: Spinnaker and the Culture Behind the

    Tech Netflix の Spinnaker が出来るまでのテクノロジーの歴史 • 時間区切りで Deploy タイミングを指定する Time Window • トラフィックガード機能 • Canary / Blue-Green デプロイ • Manual Judgement によるデプロイ判断のフロー • 今後の展望 ◦ CI ◦ Declartive CD (恐らく 宣言的コードによる CD の設定化) ◦ デプロイ方法の詳細を抽象化して提供
  18. 9: KubeCon Opening Keynote - Project Update 1. アプリケーションコードの変更 a.

    git clone HOGE; b. git checkout -b funcA; c. vi test.java; d. git push origin funcA e. PR を出す f. Merge する(Dev 環境へ反映) g. Docker Image の build h. Registry への upload i. リリース Tag を打つ 2. Kubernetes クラスタへの反映 a. 上記で Tag を打ったことで、Kubernetes Manifest YAML が生成されて PR が自動で出される b. マージすると apply される(本番適用) GitHub k8s YAML manifest GitHub Application Code
  19. 9: KubeCon Opening Keynote - Project Update アプリケーション開発者は CI/CD Pipeline

    を確立し、kubectl を使う必要はない  = kubectl は ssh と同等(kubectl exec -it SOMETHING /bin/sh) Replica 数は Kubernetes Manifest YAML には書かない
  20. Using Containers for Continuous Integration and Continuous Delivery Jenkins のスケーリング手法

    • 1 Master に Agent を沢山ぶら下げる ◦ Master が SPOF ◦ Agent の管理が必要 ◦ エージェント数に限界がある • 複数 Master を用意する ◦ SSO ◦ 共通設定や管理の集中化を考える必要がある 結構しんどい。
  21. Using Containers for Continuous Integration and Continuous Delivery

  22. Using Containers for Continuous Integration and Continuous Delivery podTemplate(label: 'mypod')

    { node('mypod') { sh 'Hello world!' } } build task をコンテナとして起動 Groovy で記述可能 PodTemplate と同等の表現力 https://github.com/jenkinsci/kubernetes-plugin
  23. Deploying to Kubernetes Thousands of Times Per/Day Kubernetes を使って High

    Velocity を実現しましょう!  ※ 変更から反映までの間隔を出来るだけ短くすること
  24. Deploying to Kubernetes Thousands of Times Per/Day 1.Image First •

    Immutable なコンテナにする • Entrypoint を設定してそのまま起動できるようにする • local / dev / prd で同じイメージを利用する • latest タグは使わない • GitHub の特定のコミットと Image Tag を紐付けておく • local でビルドして push はしない(自動化必須)
  25. Deploying to Kubernetes Thousands of Times Per/Day 2.Shift Left テストは出来るだけ前倒ししましょう

    Bottleneck
  26. Deploying to Kubernetes Thousands of Times Per/Day 3.Maintain Application Portability

    クラスタが消し飛んだときに復旧できますか? (会場では x hour ~ x day の声) ちゃんと移動出来るようにメンテナンスはし続けて下さい • 設定ファイルはコンテナイメージに内包せず ConfigMap / Secret を使う ◦ Docker Build は出来るだけ避ける ◦ 環境変化に強い設計にする • Helm Charts 化も検討しましょう • ディザスタリカバリのテストもしましょう
  27. Deploying to Kubernetes Thousands of Times Per/Day 4.Outsource Cluster Management

    • クラスタの管理は専門チームに任せる • スケーラビリティや冗長化の計画を持っておく • Certified Kubernetes Conformance Program に準拠した構成にしましょう
  28. Deploying to Kubernetes Thousands of Times Per/Day CodeFresh  Kubernetes に特化した

    Spinnaker + CircleCI + DockerHub のようなもの • Github のコード変更 • Docker Image の作成 • Deployment の Config や Helm Charts を生成 • (Performance Test) • Kubernetes クラスタにデプロイ
  29. Deploying to Kubernetes Thousands of Times Per/Day

  30. Continuous Delivery with Kubernetes at Box Kubernetes Cluster の状態 =

    Github になるように構築 Docker Build 時に YAML を自動生成して manifest Github に PR をする方式 (このセッション?) Kubernetes Cluster GitHub k8s YAML manifest =
  31. Continuous Delivery with Kubernetes at Box Kubernetes クラスタに Agent を仕込んでおく

     クラスタの状態となる Github を設定 エージェントが Github を監視して反映 障害時にも Agent を入れるだけで復旧可能 Kubernetes Cluster GitHub k8s YAML manifest =
  32. Microservices, Service Mesh, and CI/CD Pipelines: Making It All Work

    Together Istio + BRIGADE + kashti (WebUI) を使った ServiceMesh + CI/CD 環境 Istio を使うことで • トラフィックコントロール ◦ Canary リリース • Chaos テストのために Fault injection(遅延やドロップ) ◦ 障害試験 • メトリクスのスコアリング ◦ パフォーマンス低下の検知 ◦ 複雑な ServiceMesh 内でのパフォーマンスチェック
  33. Microservices, Service Mesh, and CI/CD Pipelines: Making It All Work

    Together Istio + BRIGADE + kashti (WebUI) を使った ServiceMesh + CI/CD 環境 BRIGADE を使うことで • Event driven な CI/CD Pipeline ◦ DockerHub の変更を検知 ◦ Github の変更を検知 • JavaScript による Pipeline 定義 ◦ コード化が可能 • 全てを網羅 ◦ Go binary の作成、Docker Image の作成、Helm Charts の作成、Slack 通知 events.on("exec", () => { var job = new Job("test", "alpine:3.4") job.tasks = [ "echo Hello", "echo World" ] job.run() })
  34. Microservices, Service Mesh, and CI/CD Pipelines: Making It All Work

    Together あとこのセッションでちょっと納得したのは • PR で Canary リリース • Merge で正式リリース というのは良さそうだなと思いました
  35. Building Better Containers: A Survey of Container Build Tools 現状の

    Dockerfile の問題 • イメージの再現性が乏しい • Bash での Programmability • イメージフォーマット間での連携が弱い Dockerfile 使ってコンテナイメージ作る時代はきっと終わるよ! [ソースからイメージビルド] source-to-image (s2i) buildkit habitat 詳しくは凄い量になるので、 付録の SpreadSheet で。 [従来方式] buildah nixos-container ansible-container smith (distroless)
  36. GitOps - Operations by Pull Request GitOps の 3 つの法則

    • システム全体が正常に稼働する状態を Git で管理する • 実際の状態と Git の状態(想定する状態)の差分を比較してアラート発行 • 全ての変更操作は PR 経由で実行する
  37. GitOps - Operations by Pull Request GitOps の 3 つの柱

    • Pipeline • Observility • Controll
  38. GitOps - Operations by Pull Request Pipeline • 1 Repository

    は 1 app / service で構成 • ブランチは prd / stg / dev などで切る • ブランチは Namespace か Cluster にマップさせる • stg に展開するときは stg ブランチにマージしたら自動で行われる • ブランチはプロテクトしてレビューを必須にする
  39. GitOps - Operations by Pull Request

  40. GitOps - Operations by Pull Request Observility メトリクス等を駆使して PR をマージしていいかを判断する

    レスポンスタイムが 100ms 以下かどうか等 Controll すべては Git を介して行い Kuberentes を直接操作しない
  41. Developer Tooling for Kubernetes Configuration Validation(kubeval) • Manifest YAML のフォーマットが正しいかどうか

    Unit Test(kubetest) • podSpec のチェック • label 設定のチェック • 特権コンテナを使っていないかのチェック • etc… jsonnet や helm charts などでもテスト可能