Slide 1

Slide 1 text

GitLab と Weave Flux で GitOps してみた GitLab Meetup Tokyo #10: Summit Aug 2018 Recap

Slide 2

Slide 2 text

自己紹介 ● 遠藤 耕平 ● 株式会社ぐるなび ○ 2010年入社 ○ サーバインフラエンジニア ○ 明日で最後(お世話になりました!)

Slide 3

Slide 3 text

はじめに ● 本資料について ○ 所属組織の公式見解とは一切関係ありません ○ 「GitOpsの全貌を解説!」という内容ではありません ○ 「一緒にGitOpsの扉を開きましょう」(意見交換したいです) ○ 「Weave FluxというのはGitHubだけじゃなくてGitLabでも使えるんだ」を感じてもらいたいです ● 資料は後ほど公開します ● 所用のため懇親会まで残れません。。 m(_ _)m

Slide 4

Slide 4 text

Contents ● 本日のテーマ ● 背景 ● GitOpsとは ● Weave Flux ● GitLabとFlux ● Setup Flux ● GitOpsしてみる ● Tips ● 使ってみた感想 ● まとめ

Slide 5

Slide 5 text

本日のテーマ

Slide 6

Slide 6 text

https://gitlab-jp.connpass.com/event/98160/

Slide 7

Slide 7 text

具体的には... ● KubernetesのmanifestファイルのGit管理について ● Git管理されたmanifestファイルを組み込んだ CI/CD Pipeline ● その流れで辿り着いた GitOpsとは ● GitOpsを実現するWeave FluxとGitLabの連携について

Slide 8

Slide 8 text

※補足 ● manifestファイルとは、Kubernetes上でコンテナを起動するために定義された YAMLファイル ● kubectlコマンドを利用すると manifestファイルをKubernetesにデプロイできる ● Canary, Blue/Green などの機能を持った SpinnakerなどのCDツールもいろいろ

Slide 9

Slide 9 text

会場内アンケート 1. Kubernetesを個人/会社で利用したことがある人? 2. manifestファイルをGit管理している人? 3. Git管理されたmanifestファイルをCI/CD Pipelineに組み込めている人?

Slide 10

Slide 10 text

背景

Slide 11

Slide 11 text

Git Repos Apps Code KubernetesのCI/CD Pipelineについて考えた① Tests Deploy Container Images 初期テンプレートのk8s manifestをデプロイ後、Image Tag のみ修正していくパターンだと...

Slide 12

Slide 12 text

Git Repos Apps Code KubernetesのCI/CD Pipelineについて考えた① Tests Deploy Container Images Image Tag以外のものを更新する場合はPipeline外となって しまう。すると、いつ誰がどんな変更を、誰の許可を得てデプ ロイしたのか一切残らない kubectl apply

Slide 13

Slide 13 text

Git Repos Apps Code KubernetesのCI/CD Pipelineについて考えた① Tests Deploy Container Images 現在の状態のk8s manifestがないと、クラスタの移行やク ラッシュによる再構築に伴う正しいmanifestの再デプロイが 困難 crash.. Migrate

Slide 14

Slide 14 text

KubernetesのCI/CD Pipelineについて考えた① ~対策~ ● KubernetesのmanifestをGit管理する ○ いつ誰が何を変更したのか ○ 誰が変更を許可したのか ○ ロールバックは容易か ○ クラスタの移行やクラッシュ時の再デプロイが可能か ● Git管理したmanifestを正とする ● Pipeline以外からのデプロイは禁止 ○ 必ずGit管理を通じた履歴を残す ○ RBACで権限管理 ● ここは規模やポリシー、文化などにより異なりそうなので情報交換したい

Slide 15

Slide 15 text

KubernetesのCI/CD Pipelineについて考えた② Tests Deploy Container Images アプリケーションのコードとKubernetes manifestを一緒 にGit管理してしまうと... kubectl apply Git Repos Apps Code k8s manifest

Slide 16

Slide 16 text

KubernetesのCI/CD Pipelineについて考えた② Tests Deploy Container Images manifestの変更(たとえばConfigMap)だけでアプ リケーションの中身は変わっていないのにImageが ビルドされてしまう kubectl apply Git Repos Apps Code k8s manifest

Slide 17

Slide 17 text

KubernetesのCI/CD Pipelineについて考えた② ~対策~ ● アプリケーションのコードと Kubernetes manifestのリポジトリを分離する a. アプリケーションコードの修正 → Imageのビルドを目標 b. manifestの修正 → Kubernetesクラスタへのデプロイを目標

Slide 18

Slide 18 text

KubernetesのCI/CD Pipelineについて考えた③ Tests Deploy Container Images kubectl apply Git Repos Apps Code Git Repos k8s manifest pull アプリケーションのコードとKubernetes manifestのGit管理を分けることで境界がスッキリ Merge Request

Slide 19

Slide 19 text

KubernetesのCI/CD Pipelineについて考えた③ ● 全てのオペレーションを Git起点(git push)にできる ● いつ誰が何を変更し、誰が承認してデプロイされたのか把握できる ● 役割に応じてアプリケーションコードと Kubernetes manifestの権限を分けることができる

Slide 20

Slide 20 text

とある不安.. Tests Deploy Container Images kubectl apply Git Repos Apps Code Git Repos k8s manifest pull 『Git管理されている状態』と『実際のKubernetesクラスタの状態』は、本当にイコールか??? Merge Request

Slide 21

Slide 21 text

とある不安.. Tests Deploy Container Images kubectl apply Git Repos Apps Code Git Repos k8s manifest pull ここのラインが制御できているか? (運用上、本当に制御可能か?) Merge Request

Slide 22

Slide 22 text

とある不安.. ~対策~ ● 『Git管理されている状態』と『実際の Kubernetesクラスタ上の状態』を比較・監視する ● 異なっていた場合、Git管理されているmanifestを正とし、以下アクションを行う a. 差分検知のアラート b. 差分を修正

Slide 23

Slide 23 text

とある不安.. ~対策~ ● 『Git管理されている状態』と『実際の Kubernetesクラスタ上の状態』を比較・監視する ● 異なっていた場合、Git管理されているmanifestを正とし、以下アクションを行う a. 差分検知のアラート b. 差分を修正    ..    ....    ………... → GitOpsに行き当たる

Slide 24

Slide 24 text

GitOpsとは

Slide 25

Slide 25 text

What Is GitOps ● “GitOps is a way to do Continuous Delivery, it works by using Git as a source of truth for declarative infrastructure and workloads. For Kubernetes this means using git push instead of kubectl create/apply or helm install/upgrade.” ○ ● “In the “GitOps” model, we use Git to solve for divergence and convergence, aided by a set of “diff” and “sync” tools that compare intended with actual state.” ○

Slide 26

Slide 26 text

How GitOps “diff” and “sync” tools ● “diff”:kubediff ○ Git上のmanifestと稼働中のKubernetesクラスタ上の差分を確認する ○ pythonスクリプトも提供されているので、コマンドラインでの実行も可 ○ PrometheusのAlert ruleで「一定時間、差分が解消されなかったらSlack通知」など ○ 今日はkubediffについて細かく触れませんが、GitLab上にあるmanifestとの比較も可 ● “sync”:Weave Flux ○ 後述のページで説明

Slide 27

Slide 27 text

And more.. ※GitOpsの全てを説明する時間はないので、興味がある方は以下をご参照ください ● Posts in category gitops ○ ● Git push all the things ○ ● Modern best practices for high velocity app dev using cloud native tools ○

Slide 28

Slide 28 text

Weave Flux

Slide 29

Slide 29 text

Weave Flux ● GitOpsを提唱したWeaveworks によって開発 ○ ● “The GitOps Kubernetes operator” ● Git上のmanifest(YAML)とk8sクラスタの状態が自動的に一致することを保証 ○ Git上のmanifest(YAML)を更新したら自動デプロイ ○ 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新 ○ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ ● 2018年9月時点の最新版は v1.6.0

Slide 30

Slide 30 text

Weave Flux for deployment

Slide 31

Slide 31 text

GitLabとFlux

Slide 32

Slide 32 text

GitLabのカバー範囲

Slide 33

Slide 33 text

今日お話しする連携ポイント

Slide 34

Slide 34 text

Setup Flux

Slide 35

Slide 35 text

Install & Settings ● RBAC適用 ● memcachedのデプロイ ● GitLab接続用の秘密鍵をSecretで作成 ● flux-deployment.yamlの修正 ○ Fluxの監視対象にするGitリポジトリURLを指定 ● fluxのデプロイ ● known_hostsの設定 & ConfigMapでの保存 ● flux-deployment.yamlの再修正 ○ ConfigMapの設定有効 ○ (optional) プロキシ設定 ○ (optional) fluxdが参照するnamespaceを制限する     (--k8s-namespace-whitelist)* experimental ● fluxの再デプロイ

Slide 36

Slide 36 text

プライベートリポジトリを利用する場合 ● RBAC適用 ● memcachedのデプロイ ● GitLab接続用の秘密鍵をSecretで作成 ● flux-deployment.yamlの修正 ○ Fluxの監視対象にするGitリポジトリURLを指定 ● fluxのデプロイ ● known_hostsの設定 & ConfigMapでの保存 ● flux-deployment.yamlの再修正 ○ ConfigMapの設定有効 ○ (optional) プロキシ設定 ○ (optional) fluxdが参照するnamespaceを制限する     (--k8s-namespace-whitelist)* experimental ● fluxの再デプロイ

Slide 37

Slide 37 text

イメージの自動更新 ● fluxctlのインストール(※optional) ● イメージの自動更新設定の有効化(※ annotation指定でも可) $ export FLUX_FORWARD_NAMESPACE=flux-test $ fluxctl list-controllers -n flux-test CONTROLLER CONTAINER IMAGE RELEASE POLICY flux-test:deployment/flux-test flux-test gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 ready flux-test:deployment/flux flux quay.io/weaveworks/flux:1.5.0 ready flux-test:deployment/memcached memcached memcached:1.4.25 ready $ fluxctl automate --controller=flux-test:deployment/flux-test $ fluxctl list-controllers -n flux-test CONTROLLER CONTAINER IMAGE RELEASE POLICY flux-test:deployment/flux-test flux-test gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 ready automated flux-test:deployment/flux flux quay.io/weaveworks/flux:1.5.0 ready flux-test:deployment/memcached memcached memcached:1.4.25 ready

Slide 38

Slide 38 text

プライベートなコンテナレジストリの利用 ● GitLab Container Registryも利用可 ● 特にFluxで意識する設定はない ○ KubernetesがイメージをPullする際のcredentialをFluxも使用 ○ ○ Kubernetesとプライベートレジストリの連携については以下参照 ○

Slide 39

Slide 39 text

GitOpsしてみる (※デモではありません)

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

① Git上のmanifest(YAML)を更新したら自動デプロイ

Slide 42

Slide 42 text

$ kubectl get pods,services -n flux-test NAME READY STATUS RESTARTS AGE pod/flux-7bb966d77d-nmt5n 1/1 Running 0 6d pod/memcached-6879d9d8d-m4cmt 1/1 Running 1 6d NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/memcached ClusterIP None 11211/TCP 7d A. Fluxセットアップ直後の状態 ○ Flux以外のリソースはない状態 ○ Flux監視対象のGitリポジトリ上には、まだ何もYAMLがない状態 ① Git上のmanifest(YAML)を更新したら自動デプロイ

Slide 43

Slide 43 text

apiVersion: extensions/v1beta1 kind: Deployment metadata: name: flux-test namespace: flux-test spec: template: metadata: labels: app: flux-test spec: containers: - image: gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 imagePullPolicy: IfNotPresent name: flux-test ports: - containerPort: 9999 imagePullSecrets: - name: regsecret apiVersion: v1 kind: Service metadata: name: flux-test namespace: flux-test labels: app: flux-test spec: selector: app: flux-test ports: - port: 80 targetPort: 9999 name: http apiVersion: v1 data: .dockerconfigjson: eyJJna~略~dmR19 kind: Secret metadata: name: regsecret namespace: flux-test type: kubernetes.io/dockerconfigjson ① Git上のmanifest(YAML)を更新したら自動デプロイ B. デプロイするYAMLをFluxの監視対象としたGitリポジトリにPush

Slide 44

Slide 44 text

DONE ① Git上のmanifest(YAML)を更新したら自動デプロイ

Slide 45

Slide 45 text

. .. …. $ kubectl get pods,services -n flux-test NAME READY STATUS RESTARTS AGE pod/flux-test-5cc6475fbf-nc5f4 1/1 Running 0 16s pod/flux-7bb966d77d-nmt5n 1/1 Running 0 6d pod/memcached-6879d9d8d-m4cmt 1/1 Running 1 6d NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/flux-test ClusterIP 10.43.95.187 80/TCP 16s service/memcached ClusterIP None 11211/TCP 7d ① Git上のmanifest(YAML)を更新したら自動デプロイ C. 数分後、FluxによりGit上のYAMLが自動デプロイ ○ Git上のYAMLがデプロイされ、新しくPod/Serviceが作成される ○ デフォルトのチェック間隔は5分

Slide 46

Slide 46 text

DONE ① Git上のmanifest(YAML)を更新したら自動デプロイ

Slide 47

Slide 47 text

② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

Slide 48

Slide 48 text

A. 監視対象のイメージのタグを更新する ○ Flux監視対象のイメージがautomatedになっていること ○ image tagを0.0.1 → 0.0.2に更新してコンテナレジストリにPush $ fluxctl list-controllers -n flux-test CONTROLLER CONTAINER IMAGE RELEASE POLICY flux-test:deployment/flux-test flux-test gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 ready automated flux-test:deployment/flux flux quay.io/weaveworks/flux:1.5.0 ready flux-test:deployment/memcached memcached memcached:1.4.25 ready $ docker build -t gitlab-registry.my.local/endo-k/flux-test/sample:0.0.2 . $ docker push gitlab-registry.my.local/endo-k/flux-test/sample:0.0.2 ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

Slide 49

Slide 49 text

DONE ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

Slide 50

Slide 50 text

$ kubectl get pods -n flux-test flux-test-XXXX -o jsonpath='{.spec.containers[:1].image}' gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 . .. …. $ kubectl get pods -n flux-test flux-test-XXYY -o jsonpath='{.spec.containers[:1].image}' gitlab-registry.my.local/endo-k/flux-test/sample:0.0.2 ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新 B. 数分後、Fluxによりレジストリ上の新イメージタグが自動デプロイ ○ image tagが0.0.1 → 0.0.2に ○ デフォルトのチェック間隔は5分

Slide 51

Slide 51 text

DONE ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

Slide 52

Slide 52 text

$ git diff HEAD^ diff --git a/flux-test.yaml b/flux-test.yaml index 4ef906b..9be39d9 100644 --- a/flux-test.yaml +++ b/flux-test.yaml @@ -23,7 +23,7 @@ spec: version: v1 spec: containers: - - image: gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 + - image: gitlab-registry.my.local/endo-k/flux-test/sample:0.0.2 imagePullPolicy: IfNotPresent name: flux-test ports: ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新 C. FluxによりGit上のYAMLも自動更新 ○ image tagが0.0.1 → 0.0.2に

Slide 53

Slide 53 text

DONE ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

Slide 54

Slide 54 text

③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ edit

Slide 55

Slide 55 text

$ kubectl edit deployment flux-test -n flux-test . .. …. - image: gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 ③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ A. GitLab上のYAMLと差分を発生させるため、 kubectl editで直接変更 ○ image tagを0.0.2 → 0.0.1に

Slide 56

Slide 56 text

③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ edit DONE

Slide 57

Slide 57 text

※kubediffをいれてると差分を検知している様子が伺えます . .. …. time="2018-09-06T01:05:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:05:27Z" level=info msg="Command exited successfully" time="2018-09-06T01:06:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:06:27Z" level=info msg="Command exited successfully" time="2018-09-06T01:07:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:07:27Z" level=info msg="Command exited with code: 2" time="2018-09-06T01:08:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:08:27Z" level=info msg="Command exited with code: 2" ③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ

Slide 58

Slide 58 text

$ kubectl get pods -n flux-test flux-test-XXXX -o jsonpath='{.spec.containers[:1].image}' gitlab-registry.my.local/endo-k/flux-test/sample:0.0.1 . .. …. $ kubectl get pods -n flux-test flux-test-XXYY -o jsonpath='{.spec.containers[:1].image}' gitlab-registry.my.local/endo-k/flux-test/sample:0.0.2 ③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ B. 数分後、FluxによりGit上のYAMLが自動デプロイ(Git上との差分解消) ○ image tagが0.0.1 → 0.0.2に ○ デフォルトのチェック間隔は5分

Slide 59

Slide 59 text

※kubediffをいれてると差分が解消した様子が伺えます . .. …. time="2018-09-06T01:05:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:05:27Z" level=info msg="Command exited successfully" time="2018-09-06T01:06:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:06:27Z" level=info msg="Command exited successfully" time="2018-09-06T01:07:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:07:27Z" level=info msg="Command exited with code: 2" time="2018-09-06T01:08:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:08:27Z" level=info msg="Command exited with code: 2" time="2018-09-06T01:09:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:09:27Z" level=info msg="Command exited with code: 2" time="2018-09-06T01:10:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:10:27Z" level=info msg="Command exited with code: 2" time="2018-09-06T01:11:26Z" level=info msg="Running '/kubediff' with argments [--namespace=flux-test /data/repo]" time="2018-09-06T01:11:27Z" level=info msg="Command exited successfully" ③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ

Slide 60

Slide 60 text

③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ edit DONE

Slide 61

Slide 61 text

Tips

Slide 62

Slide 62 text

Flux Tips ● イメージを自動更新するタグは正規表現などでフィルタ可能 ○ ● Helmにも対応 ○ ● Fluxで検知したイベントの Slack通知機能はWeave Cloudのみ ○ 代わりにfluxcloudが使えそう “Fluxcloud is a valid upstream for Weave, allowing you to send Flux events to Slack or a webhook without using Weave Cloud.”

Slide 63

Slide 63 text

FluxイベントのSlack通知(fluxcloud)

Slide 64

Slide 64 text

既知の制限事項 ● Git上で削除されたリソースの削除はできない ○ 現状は個別に kubectl delete する必要がありそう ● 1つのfluxデーモンが参照可能なリポジトリは 1つまで ○ 1つのfluxデーモンが参照可能なリポジトリは1つまで

Slide 65

Slide 65 text

使ってみた感想

Slide 66

Slide 66 text

やりたいことは概ね実現できそう ● manifestファイルをGit管理できる ○ 誰がいつ何を変更したのかを把握 ○ クラスタの移行やクラッシュが発生しても迷わずに再デプロイ可 ● Git上のmanifestファイルを正としたCI/CD Pipelineが構築できそう ○ Weave FluxによりPipeline外部からの更新は取り消せる ● Git管理されているmanifestファイルが再デプロイされる ● 「差分検知したから同期を一時停止」みたいなワンクッションは欲しい気もする... ● オンプレミス上のGitLabとの連携も問題なし

Slide 67

Slide 67 text

改善を期待したいところ、注意したいところ ● 削除は対応されてほしい ○ 滅多にない操作なので当面は不要 ○ 対応したらしたで、怖さはある ○ deleteのときだけkubectlや他のツールを使うか? ● たまにしかしないオペレーションは事故りそうでやはり怖い ○ issueの進捗を見守る.. ● 手順通りにテンプレの RBAC適用するとfluxがcluster-admin相当の権限を有するので注意 ○ typoで他Namespace内にPod作成.. → fluxでは削除できない..( → 管理者に削除依頼) ○ Namespace単位で制御したい ● Namespace毎にServiceAccount作りRoleBindingでadminを設定 ● ClusterRolebindingでnamespacesなど必要なリソースに[get list watch]を付与

Slide 68

Slide 68 text

Jenkins X “Jenkins X then automates the management of the Environments and the Promotion of new versions of Applications between Environments via GitOps.” GitOpsを謳っている他のCDツールも試したい Argo CD “Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.”

Slide 69

Slide 69 text

まとめ

Slide 70

Slide 70 text

● KubernetesのmanifestファイルもGit管理しましょう ● GitOpsはGitを正とするCD手法 ● Weave FluxはKubernetesでGitOpsを実現するツール ● GitLabとFluxの連携はとても簡単

Slide 71

Slide 71 text

ご清聴ありがとうございました