gitops-using-flux-and-gitlab

55b7011f037e5da220c314e043e924e5?s=47 endo-k
September 13, 2018

 gitops-using-flux-and-gitlab

「GitLab Meetup Tokyo #10: Summit Aug 2018 Recap」(https://gitlab-jp.connpass.com/event/98160/)こちらのイベントで発表させていただいた資料です

タイトル:GitLabでWeave FluxでGitOpsしてみた

55b7011f037e5da220c314e043e924e5?s=128

endo-k

September 13, 2018
Tweet

Transcript

  1. GitLab と Weave Flux で GitOps してみた GitLab Meetup Tokyo

    #10: Summit Aug 2018 Recap
  2. 自己紹介 • 遠藤 耕平 • 株式会社ぐるなび ◦ 2010年入社 ◦ サーバインフラエンジニア

    ◦ 明日で最後(お世話になりました!)
  3. はじめに • 本資料について ◦ 所属組織の公式見解とは一切関係ありません ◦ 「GitOpsの全貌を解説!」という内容ではありません ◦ 「一緒にGitOpsの扉を開きましょう」(意見交換したいです) ◦

    「Weave FluxというのはGitHubだけじゃなくてGitLabでも使えるんだ」を感じてもらいたいです • 資料は後ほど公開します • 所用のため懇親会まで残れません。。 m(_ _)m
  4. Contents • 本日のテーマ • 背景 • GitOpsとは • Weave Flux

    • GitLabとFlux • Setup Flux • GitOpsしてみる • Tips • 使ってみた感想 • まとめ
  5. 本日のテーマ

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

  7. 具体的には... • KubernetesのmanifestファイルのGit管理について • Git管理されたmanifestファイルを組み込んだ CI/CD Pipeline • その流れで辿り着いた GitOpsとは

    • GitOpsを実現するWeave FluxとGitLabの連携について
  8. ※補足 • manifestファイルとは、Kubernetes上でコンテナを起動するために定義された YAMLファイル • kubectlコマンドを利用すると manifestファイルをKubernetesにデプロイできる • Canary, Blue/Green

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

  10. 背景

  11. Git Repos Apps Code KubernetesのCI/CD Pipelineについて考えた① Tests Deploy Container Images

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

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

    現在の状態のk8s manifestがないと、クラスタの移行やク ラッシュによる再構築に伴う正しいmanifestの再デプロイが 困難 crash.. Migrate
  14. KubernetesのCI/CD Pipelineについて考えた① ~対策~ • KubernetesのmanifestをGit管理する ◦ いつ誰が何を変更したのか ◦ 誰が変更を許可したのか ◦

    ロールバックは容易か ◦ クラスタの移行やクラッシュ時の再デプロイが可能か • Git管理したmanifestを正とする • Pipeline以外からのデプロイは禁止 ◦ 必ずGit管理を通じた履歴を残す ◦ RBACで権限管理 • ここは規模やポリシー、文化などにより異なりそうなので情報交換したい
  15. KubernetesのCI/CD Pipelineについて考えた② Tests Deploy Container Images アプリケーションのコードとKubernetes manifestを一緒 にGit管理してしまうと... kubectl

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

    apply Git Repos Apps Code k8s manifest
  17. KubernetesのCI/CD Pipelineについて考えた② ~対策~ • アプリケーションのコードと Kubernetes manifestのリポジトリを分離する a. アプリケーションコードの修正 →

    Imageのビルドを目標 b. manifestの修正 → Kubernetesクラスタへのデプロイを目標
  18. KubernetesのCI/CD Pipelineについて考えた③ Tests Deploy Container Images kubectl apply Git Repos

    Apps Code Git Repos k8s manifest pull アプリケーションのコードとKubernetes manifestのGit管理を分けることで境界がスッキリ Merge Request
  19. KubernetesのCI/CD Pipelineについて考えた③ • 全てのオペレーションを Git起点(git push)にできる • いつ誰が何を変更し、誰が承認してデプロイされたのか把握できる • 役割に応じてアプリケーションコードと

    Kubernetes manifestの権限を分けることができる
  20. とある不安.. Tests Deploy Container Images kubectl apply Git Repos Apps

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

    Code Git Repos k8s manifest pull ここのラインが制御できているか? (運用上、本当に制御可能か?) Merge Request
  22. とある不安.. ~対策~ • 『Git管理されている状態』と『実際の Kubernetesクラスタ上の状態』を比較・監視する • 異なっていた場合、Git管理されているmanifestを正とし、以下アクションを行う a. 差分検知のアラート b.

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

    差分を修正    ..    ....    ………... → GitOpsに行き当たる
  24. GitOpsとは

  25. 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.” ◦ <https://www.weave.works/blog/managing-helm-releases-the-gitops-way> • “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.” ◦ <https://www.weave.works/blog/gitops-operations-by-pull-request>
  26. How GitOps “diff” and “sync” tools • “diff”:kubediff <https://github.com/weaveworks/kubediff> ◦

    Git上のmanifestと稼働中のKubernetesクラスタ上の差分を確認する ◦ pythonスクリプトも提供されているので、コマンドラインでの実行も可 ◦ PrometheusのAlert ruleで「一定時間、差分が解消されなかったらSlack通知」など ◦ 今日はkubediffについて細かく触れませんが、GitLab上にあるmanifestとの比較も可 • “sync”:Weave Flux ◦ 後述のページで説明
  27. And more.. ※GitOpsの全てを説明する時間はないので、興味がある方は以下をご参照ください • Posts in category gitops ◦ <https://www.weave.works/blog/category/gitops/>

    • Git push all the things ◦ <https://www.slideshare.net/weaveworks/continuous-lifecycle-london-2018-event-keynote-97418556> • Modern best practices for high velocity app dev using cloud native tools ◦ <https://www.slideshare.net/weaveworks/gitops-modern-best-practices-for-high-velocity-app-dev-using-cloud- native-tools>
  28. Weave Flux

  29. Weave Flux • GitOpsを提唱したWeaveworks によって開発 ◦ <https://github.com/weaveworks/flux> • “The GitOps

    Kubernetes operator” • Git上のmanifest(YAML)とk8sクラスタの状態が自動的に一致することを保証 ◦ Git上のmanifest(YAML)を更新したら自動デプロイ ◦ 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新 ◦ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ • 2018年9月時点の最新版は v1.6.0
  30. Weave Flux for deployment <https://github.com/weaveworks/flux>

  31. GitLabとFlux

  32. GitLabのカバー範囲

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

  34. Setup Flux

  35. 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の再デプロイ
  36. プライベートリポジトリを利用する場合 • 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の再デプロイ
  37. イメージの自動更新 • 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
  38. プライベートなコンテナレジストリの利用 • GitLab Container Registryも利用可 • 特にFluxで意識する設定はない ◦ KubernetesがイメージをPullする際のcredentialをFluxも使用 ◦

    <https://github.com/weaveworks/flux/blob/master/site/faq.md#how-do-i-give-flux-access-to-an-image-registry> ◦ Kubernetesとプライベートレジストリの連携については以下参照 ◦ <https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/>
  39. GitOpsしてみる (※デモではありません)

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

  42. $ 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 <none> 11211/TCP 7d A. Fluxセットアップ直後の状態 ◦ Flux以外のリソースはない状態 ◦ Flux監視対象のGitリポジトリ上には、まだ何もYAMLがない状態 ① Git上のmanifest(YAML)を更新したら自動デプロイ
  43. 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
  44. DONE ① Git上のmanifest(YAML)を更新したら自動デプロイ

  45. . .. …. $ 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 <none> 80/TCP 16s service/memcached ClusterIP None <none> 11211/TCP 7d ① Git上のmanifest(YAML)を更新したら自動デプロイ C. 数分後、FluxによりGit上のYAMLが自動デプロイ ◦ Git上のYAMLがデプロイされ、新しくPod/Serviceが作成される ◦ デフォルトのチェック間隔は5分
  46. DONE ① Git上のmanifest(YAML)を更新したら自動デプロイ

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

  48. 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自動更新
  49. DONE ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

  50. $ 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分
  51. DONE ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

  52. $ 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に
  53. DONE ② 新しいコンテナイメージの自動検出 & 自動デプロイ & Git自動更新

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

  55. $ 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に
  56. ③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ edit DONE

  57. ※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)を自動デプロイ
  58. $ 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分
  59. ※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)を自動デプロイ
  60. ③ Kubernetesの状態と差分があればGit上のmanifest(YAML)を自動デプロイ edit DONE

  61. Tips

  62. Flux Tips • イメージを自動更新するタグは正規表現などでフィルタ可能 ◦ <https://github.com/weaveworks/flux/blob/master/site/using.md#filter-pattern-types> • Helmにも対応 ◦ <https://github.com/weaveworks/flux/blob/master/site/helm/get-started.md>

    • 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.” <https://github.com/justinbarrick/fluxcloud>
  63. FluxイベントのSlack通知(fluxcloud)

  64. 既知の制限事項 • Git上で削除されたリソースの削除はできない ◦ 現状は個別に kubectl delete する必要がありそう <https://github.com/weaveworks/flux/blob/master/site/faq.md#will-flux-delete-resources-that-are-no-longer-in-t he-git-repository>

    <https://github.com/weaveworks/flux/issues/738> • 1つのfluxデーモンが参照可能なリポジトリは 1つまで ◦ 1つのfluxデーモンが参照可能なリポジトリは1つまで <https://github.com/weaveworks/flux/blob/master/site/faq.md#does-it-work-only-with-one-git-repository>
  65. 使ってみた感想

  66. やりたいことは概ね実現できそう • manifestファイルをGit管理できる ◦ 誰がいつ何を変更したのかを把握 ◦ クラスタの移行やクラッシュが発生しても迷わずに再デプロイ可 • Git上のmanifestファイルを正としたCI/CD Pipelineが構築できそう

    ◦ Weave FluxによりPipeline外部からの更新は取り消せる • Git管理されているmanifestファイルが再デプロイされる • 「差分検知したから同期を一時停止」みたいなワンクッションは欲しい気もする... • オンプレミス上のGitLabとの連携も問題なし
  67. 改善を期待したいところ、注意したいところ • 削除は対応されてほしい ◦ 滅多にない操作なので当面は不要 ◦ 対応したらしたで、怖さはある ◦ deleteのときだけkubectlや他のツールを使うか? •

    たまにしかしないオペレーションは事故りそうでやはり怖い ◦ issueの進捗を見守る.. <https://github.com/weaveworks/flux/issues/738> • 手順通りにテンプレの RBAC適用するとfluxがcluster-admin相当の権限を有するので注意 ◦ typoで他Namespace内にPod作成.. → fluxでは削除できない..( → 管理者に削除依頼) ◦ Namespace単位で制御したい • Namespace毎にServiceAccount作りRoleBindingでadminを設定 • ClusterRolebindingでnamespacesなど必要なリソースに[get list watch]を付与
  68. Jenkins X “Jenkins X then automates the management of the

    Environments and the Promotion of new versions of Applications between Environments via GitOps.” <https://jenkins.io/projects/jenkins-x/> GitOpsを謳っている他のCDツールも試したい Argo CD “Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.” <https://github.com/argoproj/argo-cd>
  69. まとめ

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

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