Weaveworks社が提唱する kubernetes のベストプラクティスで , Single Source of Truth として Git を採用し,Kubernetes リソースなどを継続的にデリバリーしていく GitOps がある。 今回はそんな GitOpsを実現するツールである Flux のv2が出てきたのでチュートリアルを試し、 v1との比較を行っていく。
なお、 GitOps の説明や過去にv1を検証した内容は以下の記事等に紹介がある。
Get started
今回は Flux v2の動作を確認するために「Get started」の内容に沿って実施していく。 toolkit.fluxcd.io
事前準備
localに kubernetes 環境を構築する。 今回は minikube を使って cluster の構築を行う。 kubernetes.io
$ kubectl version --short Client Version: v1.19.3 Server Version: v1.19.2
次に Flux を操作するためのクライアントをインストールする。
v1の時は fluxctl
だったが、v2からは flux
に変更されている。
$curl -s https://toolkit.fluxcd.io/install.sh | sudo bash $flux --version flux version 0.2.3
最後にチュートリアルで使う GitHub リポジトリをフォークしておく。 github.com
セットアップ
flux
を使って, Flux に対応した環境か確認する。
$ flux check --pre ► checking prerequisites ✔ kubectl 1.19.4 >=1.18.0 ✔ Kubernetes 1.19.2 >=1.16.0 ✔ prerequisites checks passed
環境の問題はなさそうなので,環境変数GITHUB_TOKEN
GITHUB_USER
GITHUB_REPO
を設定して flux bootstrap
コマンドを実行する。
$ export GITHUB_TOKEN=<your-token> $ export GITHUB_USER=<your-username> $ export GITHUB_REPO=<repository-name> $ flux bootstrap github \ --owner=${GITHUB_USER} \ --repository=${GITHUB_REPO} \ --branch=main \ --personal \ --path=clusters/staging ► connecting to github.com ✔ repository cloned ✚ generating manifests ✔ components are up to date ► installing components in flux-system namespace namespace/flux-system created networkpolicy.networking.k8s.io/allow-scraping created networkpolicy.networking.k8s.io/allow-webhooks created networkpolicy.networking.k8s.io/deny-ingress created role.rbac.authorization.k8s.io/crd-controller-flux-system created rolebinding.rbac.authorization.k8s.io/crd-controller-flux-system created clusterrolebinding.rbac.authorization.k8s.io/cluster-reconciler-flux-system created customresourcedefinition.apiextensions.k8s.io/buckets.source.toolkit.fluxcd.io created customresourcedefinition.apiextensions.k8s.io/gitrepositories.source.toolkit.fluxcd.io created customresourcedefinition.apiextensions.k8s.io/helmcharts.source.toolkit.fluxcd.io created customresourcedefinition.apiextensions.k8s.io/helmrepositories.source.toolkit.fluxcd.io created service/source-controller created deployment.apps/source-controller created customresourcedefinition.apiextensions.k8s.io/kustomizations.kustomize.toolkit.fluxcd.io created deployment.apps/kustomize-controller created customresourcedefinition.apiextensions.k8s.io/helmreleases.helm.toolkit.fluxcd.io created deployment.apps/helm-controller created customresourcedefinition.apiextensions.k8s.io/alerts.notification.toolkit.fluxcd.io created customresourcedefinition.apiextensions.k8s.io/providers.notification.toolkit.fluxcd.io created customresourcedefinition.apiextensions.k8s.io/receivers.notification.toolkit.fluxcd.io created service/notification-controller created service/webhook-receiver created deployment.apps/notification-controller created Waiting for deployment "source-controller" rollout to finish: 0 of 1 updated replicas are available... deployment "source-controller" successfully rolled out Waiting for deployment "kustomize-controller" rollout to finish: 0 of 1 updated replicas are available... deployment "kustomize-controller" successfully rolled out deployment "helm-controller" successfully rolled out Waiting for deployment "notification-controller" rollout to finish: 0 of 1 updated replicas are available... deployment "notification-controller" successfully rolled out ✔ install completed ► configuring deploy key ✔ deploy key configured ► generating sync manifests ✔ sync manifests pushed ► applying sync manifests ◎ waiting for cluster sync ✔ bootstrap finished $ kubectl get all -n flux-system NAME READY STATUS RESTARTS AGE pod/helm-controller-7fc55767cc-bfzck 1/1 Running 0 4m51s pod/kustomize-controller-6b85bf79f9-t6qs4 1/1 Running 0 4m51s pod/notification-controller-7bb8667967-6xqdb 1/1 Running 0 4m48s pod/source-controller-6cdb6c8889-hpsxx 1/1 Running 0 4m53s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/notification-controller ClusterIP 10.108.140.72 <none> 80/TCP 4m50s service/source-controller ClusterIP 10.104.224.8 <none> 80/TCP 4m53s service/webhook-receiver ClusterIP 10.103.160.216 <none> 80/TCP 4m48s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/helm-controller 1/1 1 1 4m51s deployment.apps/kustomize-controller 1/1 1 1 4m53s deployment.apps/notification-controller 1/1 1 1 4m48s deployment.apps/source-controller 1/1 1 1 4m53s NAME DESIRED CURRENT READY AGE replicaset.apps/helm-controller-7fc55767cc 1 1 1 4m51s replicaset.apps/kustomize-controller-6b85bf79f9 1 1 1 4m52s replicaset.apps/notification-controller-7bb8667967 1 1 1 4m48s replicaset.apps/source-controller-6cdb6c8889 1 1 1 4m53s
bootstrap
コマンドで flux-system のnamespaceが作成されて, GitOpsを実施するための kustomize , helm のcontrollerが作成されている。
この他にもv2では監視機能が強化されたこともあって notificationのcontrollerが作成されている。 Flux v1 は flux-agentとmemcacheのみだったのに対して役割に応じてcontrollerが増えているようだ。
Flux v2 の全体構成は公式に掲載されている図が非常に分かりやすい。
Flux v2より引用
なお、bootstrap
で対象にしたrepository で管理されているmanifestがclusterに展開されていることが分かる。
$ flux get kustomizations --all-namespaces NAMESPACE NAME REVISION SUSPENDED READY MESSAGE flux-system apps main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1 False True Applied revision: main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1 flux-system flux-system main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1 False True Applied revision: main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1 flux-system infrastructure main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1 False True Applied revision: main/32112c9d1a3f89fdd35f91fe3ae5d0b8096923b1 $ flux get helmreleases --all-namespaces NAMESPACE NAME REVISION SUSPENDED READY MESSAGE nginx nginx 5.6.14 False True release reconciliation succeeded podinfo podinfo 5.0.3 False True release reconciliation succeeded redis redis 11.3.4 False True release reconciliation succeeded
GitOps実践
初期状態の確認
まず, bootstrap
でデプロイされた初期のappにアクセスするためにport-forward
する。
$ kubectl -n podinfo port-forward svc/podinfo 9898:9898 Forwarding from 127.0.0.1:9898 -> 9898 Forwarding from [::1]:9898 -> 9898 Handling connection for 9898 Handling connection for 9898
ブラウザからlocalhost:9898
にアクセスすると、下記のようなサンプルアプリケーション画面が表示される。なお、初期状態ではv5.0.3
と表示される。
マニフェストの修正
GitOps対象のリポジトリ flux2-kustomize-helm-example の中にあるマニフェスト flux2-kustomize-helm-example/workloads/apps/staging/podinfo-values.yaml
を修正する。chart.spec.version: ">=1.0.0-alpha"
をchart.spec.version: "5.0.0"
に変更し、repositoryにpushしておく。
podinfoを確認すると変更されたことが確認できる
$ flux get helmreleases --all-namespaces NAMESPACE NAME REVISION SUSPENDED READY MESSAGE nginx nginx 5.6.14 False True release reconciliation succeeded podinfo podinfo 5.0.0 False True release reconciliation succeeded redis redis 11.3.4 False True release reconciliation succeeded
再度、ブラウザから確認する
$ kubectl -n podinfo port-forward svc/podinfo 9898:9898 Forwarding from 127.0.0.1:9898 -> 9898 Forwarding from [::1]:9898 -> 9898
versionが 5.0.0
に変更していることが分かる
これによりgitの結果を正とした GitOpsが実現できている
モニタリングを設定
Flux v1では flux agentの監視が困難であり、同期の失敗を検知/修正するまでに時間がかかっていたが、 Flux v2 になってからは Prometheus
による監視と Grafana
のダッシュボードが提供された。チュートリアルでは扱っていないが、有用な仕組みなので試してみる。
flux2のリポジトリにあるmanifestから作成する
$ flux create source git monitoring \ > --interval=30m \ > --url=https://github.com/fluxcd/flux2 \ > --branch=main ✚ generating GitRepository source ► applying GitRepository source ✔ GitRepository source created ◎ waiting for GitRepository source reconciliation ✔ GitRepository source reconciliation completed ✔ fetched revision: main/37fb0f632b7acd192a314388c8f6bab5a6376764 $ flux create kustomization monitoring \ --interval=1h \ --prune=true \ --source=monitoring \ --path="./manifests/monitoring" \ --health-check="Deployment/prometheus.flux-system" \ --health-check="Deployment/grafana.flux-system" ✚ generating Kustomization ► applying Kustomization ✔ Kustomization created ◎ waiting for Kustomization reconciliation ✔ Kustomization monitoring is ready ✔ applied revision main/37fb0f632b7acd192a314388c8f6bab5a6376764 kubectl -n flux-system port-forward svc/grafana 3000:3000
ブラウザでダッシュボードにアクセスすると GitOps
状態が確認できる。
Control planeのダッシュボード
http://localhost:3000/d/gitops-toolkit-control-plane/gitops-toolkit-control-plane
Cluster reconciliationのダッシュボード
http://localhost:3000/d/flux-cluster/flux-cluster-stats
v1との比較
導入のしやすさ
v2になってbootstrap
コマンドが追加されたことによって、コマンド1つで設定できるため、v1と比較してnamespaceの準備等がなくなり、簡単に設定できるようになった。
監視
Flux v1 のlogを監視して、errorが発生した場合にトラブルシューティングするなど、泥臭いことをやっていた(少なくとも自分の環境では)。
Flux v2でPrometheus
とGrafana
が提供されたので、metricsの取得やダッシュボードによる可視化が可能になり、保守性が高まった。
また、slackへの通知などの機能も提供されたので、障害発生から検知までの時間短縮に繋がる。
構成
Flux v1はflux agentが1つだったことに対して、Flux v2では役割毎にcontrol plane
が分かれた。個人的には役割が明確になったため、トラブルシューティングが簡単になり、かつ自分たちの環境にマッチした最小構成を構築するのが容易になったと感じた。
まとめ
Flux v2のチュートリアルを実施してみたが、Flux v1の時よりも導入は容易になったと感じる。 CLIに関しての変更はv1ユーザーにとっては破壊的変更なため、v2へ移行するには時間がかかりそうだ。しかし、移行した場合は、監視や通知といったこれまで苦戦していた部分が提供されているので、時間をかけてしっかり移行していきたいと思う。
移行の手順は用意されているのでcluserの移行だけなら簡単そう。
pipelineやその他の仕組みでFlux CLI
を使っている場合は、考慮が必要そう。