Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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 のリソース文法的、意図的内容

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

その他印象に残っている話 Spinnaker のロードマップ ● CI にも力を入れていく ● CD 定義をコード化可能に ● デプロイ定義の抽象化 Canary Release の一方法 ● PR が出たら Canary リリース ● マージされたら Deploy

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

参考付録

Slide 17

Slide 17 text

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 の設定化) ○ デプロイ方法の詳細を抽象化して提供

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

9: KubeCon Opening Keynote - Project Update アプリケーション開発者は CI/CD Pipeline を確立し、kubectl を使う必要はない  = kubectl は ssh と同等(kubectl exec -it SOMETHING /bin/sh) Replica 数は Kubernetes Manifest YAML には書かない

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

Using Containers for Continuous Integration and Continuous Delivery

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Deploying to Kubernetes Thousands of Times Per/Day Kubernetes を使って High Velocity を実現しましょう!  ※ 変更から反映までの間隔を出来るだけ短くすること

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

Deploying to Kubernetes Thousands of Times Per/Day 2.Shift Left テストは出来るだけ前倒ししましょう Bottleneck

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

Deploying to Kubernetes Thousands of Times Per/Day

Slide 30

Slide 30 text

Continuous Delivery with Kubernetes at Box Kubernetes Cluster の状態 = Github になるように構築 Docker Build 時に YAML を自動生成して manifest Github に PR をする方式 (このセッション?) Kubernetes Cluster GitHub k8s YAML manifest =

Slide 31

Slide 31 text

Continuous Delivery with Kubernetes at Box Kubernetes クラスタに Agent を仕込んでおく  クラスタの状態となる Github を設定 エージェントが Github を監視して反映 障害時にも Agent を入れるだけで復旧可能 Kubernetes Cluster GitHub k8s YAML manifest =

Slide 32

Slide 32 text

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 内でのパフォーマンスチェック

Slide 33

Slide 33 text

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() })

Slide 34

Slide 34 text

Microservices, Service Mesh, and CI/CD Pipelines: Making It All Work Together あとこのセッションでちょっと納得したのは ● PR で Canary リリース ● Merge で正式リリース というのは良さそうだなと思いました

Slide 35

Slide 35 text

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)

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

GitOps - Operations by Pull Request GitOps の 3 つの柱 ● Pipeline ● Observility ● Controll

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

GitOps - Operations by Pull Request

Slide 40

Slide 40 text

GitOps - Operations by Pull Request Observility メトリクス等を駆使して PR をマージしていいかを判断する レスポンスタイムが 100ms 以下かどうか等 Controll すべては Git を介して行い Kuberentes を直接操作しない

Slide 41

Slide 41 text

Developer Tooling for Kubernetes Configuration Validation(kubeval) ● Manifest YAML のフォーマットが正しいかどうか Unit Test(kubetest) ● podSpec のチェック ● label 設定のチェック ● 特権コンテナを使っていないかのチェック ● etc… jsonnet や helm charts などでもテスト可能