3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Flux+GitLabでGitOpsを試す

Last updated at Posted at 2023-03-26

先日、GitLabがFluxとの統合を発表した。まだ具体的な機能は見当たっていないが、Flux(beta)というページもあり、近いうちにGitLabからいい感じでFluxが使えるようになるのだと思われる。
このメモはその来たるべき未来に備えて、Flux+GitLabを使ってGitOpsを試した時のもの。
なお、GitLabオフィシャルのチュートリアルはこちら

Fluxとは

FluxはKubernetes向けのContinuos Deliveryツールで、CNCFのプロジェクトにもなっている。
CNCFのGraduated Projectであるため、ある程度成熟されていることはCNCFからもお墨付きである。

よく比較される対象としてArgoCDがあるが、ArgoCDはリッチなUIやOIDC連携など機能的には豊富であるが独自拡張している面が強く、Fluxはk8sの標準リソースを中心にGitOpsを実現しており、軽さやシンプルさではFluxが勝ると思われる。
なお、Tanzu Mission Control(TMC)のContinuosDelivery機能でもFluxを採用している(確認した際の記事はこちら)。TMCのCD機能とこのメモでやってることは大体同じだが、TMCの方がGUIで設定可能で導入の難度は低い。

Fluxのインストール

FluxCDのkubernetesクラスタへの導入はHelmでもyamlでもなく、fluxコマンドで行う。
最初にコマンドをインストールする。インストール方法はこちら
自環境はMacなのでbrewでinstallする。

brew install fluxcd/tap/flux

補完機能を入れる人は以下も実施する。

echo "source <(flux completion bash)" >> ~/.bashrc
. ~/.bashrc

次にFluxがGitLabにアクセスするためのPersonal Access Tokenを発行する。参考にしたドキュメントはこの辺りになる。
適当にアカウントを作成し(ここではflux-testとした)、apiに対して読み書きを許可したTokenを発行する。
1679655622953.png
ここで発行したTokenはFluxの設定をGitリポジトリに格納するために使う。
発行したアクセスTokenを環境変数に設定する。

export GITLAB_TOKEN="xxxxxxxxxxxxxxx"

次にFluxの設定を書き込むリポジトリを用意する。空のリポジトリを作成し、先程作成したユーザ(flux-test)が参照できるように権限設定する。

準備が出来たらインストールをfluxコマンドで実施する。

flux bootstrap gitlab \
  --hostname=gitlab.gitlab.hogeeee.info \
  --owner=myapp \
  --repository=flux-config \
  --branch=main \
  --token-auth

オプションは以下の意味となる。

  • --hostname:GitLabのURL
  • --owner:GitLabのユーザ名かグループ名(上の実行例ではグループ名を指定)
  • --repository:リポジトリ名
  • --branch:ブランチ名
  • --token-auth:同期する際にSSHキーではなくPersonalAccessTokenで同期する
  • --path:リポジトリのパス(サブグループ等直下にない場合に指定する)
    ※今回は--pathは未使用。

インストールに成功すると、指定したリポジトリ内にファイルが作成される。

gotk-components.yamlを見るとFluxがデプロイするコンポーネントに関するManifestであることが分かる。
また、以下のコンポーネントがクラスタに展開される。

$ kubectl get pod -n flux-system
NAME                                       READY   STATUS    RESTARTS   AGE
helm-controller-fcfbdb98f-hmvn7            1/1     Running   0          12m
kustomize-controller-644db84bbb-mtlq8      1/1     Running   0          12m
notification-controller-6766ff88ff-wxgjf   1/1     Running   0          12m
source-controller-5c596db589-9w7j9         1/1     Running   0          12m

インストールされたコンポーネントは以下のような関係性になっている。(画像は公式サイトより引用)

1679796910648.png

各コンポーネントの役割は以下である(多分)。

  • Helm Controller:HelmChartの管理や各種動作の自動実行
  • Kustomize Controller:k8sクラスタにKustomizeでManifestを適用する
  • Notification Controller:各種ソースからの通知を受け取って各コントローラにハンドリングする
  • Source Controller:各種ソース(Helm, Git等)の認証管理や変更検知

GitOpsの確認

次にGitに格納したManifestがデプロイできるかを確認する。

Manifestを格納するリポジトリを作成し、Cloneする。

git clone https://gitlab.gitlab.hogeeee.info/myapp/flux-demo-manifest.git

サンプルとなるManifestを格納する。kubectl-neatプラグインを使っているが、入れていない人は省いてリダイレクトしてもらってOK。

cd flux-demo-manifest
kubectl create deploy nginx --image nginx --replicas 1 --dry-run=client -o yaml | kubectl neat -f - > ./nginx-deploy.yaml
git add *
git commit -m "initial commit"
git push origin main

次にデプロイ用のTokenを作成する。リポジトリのSettings->Deploy tokensからread_repositoryの権限をつけて作成する。

作成後、表示されたUsernameとTokenを控えておく。
次に、flux-demoというNamespaceを作成し、そこにFluxがGitを見に行くのに使うTokenを登録する。

kubectl create ns flux-demo
flux create secret git flux-deploy-authentication \
         --url=https://gitlab.gitlab.hogeeee.info/myapp/flux-demo-manifest \
         --namespace=flux-demo \
         --username="gitlab+deploy-token-5" \
         --password="xxxxxxxxx"

--username--passwordは先程GitLabで作成したDeployトークンのユーザ名とTokenを設定する。

次にFluxが見に行くGitのリポジトリ情報を登録する。

cat << EOF > ./git-repo.yaml
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: web-app-manifests
  namespace: flux-demo
spec:
  interval: 1m0s
  ref:
    branch: main
  secretRef:
    name: flux-deploy-authentication
  url: https://gitlab.gitlab.hogeeee.info/myapp/flux-demo-manifest
EOF
kubectl apply -f ./git-repo.yaml

先程作成したSecretを見に行くので、Secretと同じNamespaceにデプロイする。
最後に、Kustomizationを作成して、実際にGitに格納したManifestをデプロイする。

cat << EOF > ./kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: nginx-source-kustomization
  namespace: flux-demo
spec:
  interval: 1m0s
  path: ./
  prune: true
  sourceRef:
    kind: GitRepository
    name: web-app-manifests
    namespace: flux-demo
  targetNamespace: flux-demo
EOF
kubectl apply -f ./kustomization.yaml

暫く待つとPodが作成される。

$ kubectl get pod -n flux-demo
NAME                    READY   STATUS    RESTARTS   AGE
nginx-8f458dc5b-pwd2l   1/1     Running   0          61s

なお、Kustomizationリソースはデプロイ直後はエラーを出力し、しばらくしてリコンサイルしてReconciliationSucceededに遷移する。イベントは以下のようになっていた。

Events:
  Type     Reason                   Age                   From                  Message
  ----     ------                   ----                  ----                  -------
  Warning  ArtifactFailed           106s (x5 over 5m46s)  kustomize-controller  failed to verify archive: computed checksum '918828706d3dda025af38db7a922fc4147a106893ef23950d805c2eefcc920c6' doesn't match provided 'eb37990198ab8bba00ebf28212088df917f5953c00bcb8fd9f3b17be36ef21a3' (check whether file size exceeds max download size)
  Normal   Progressing              46s                   kustomize-controller  Deployment/flux-demo/nginx created
  Normal   ReconciliationSucceeded  46s                   kustomize-controller  Reconciliation finished in 137.13567ms, next run in 1m0s

リコンサイルが効いている確認として、deploymentを削除してみる。

kubectl delete deploy nginx -n flux-demo

Kustomizationのintervalを1分で設定していたので、1分程度待てばdeploymentが再作成されてPodも立ち上がる。

$ kubectl get pod -n flux-demo
NAME                    READY   STATUS    RESTARTS   AGE
nginx-8f458dc5b-lfnds   1/1     Running   0          9s

次にGit側のManifestにも修正を加えてみる。レプリカ数を3に変更してリポジトリにpushする。

vi nginx-deploy.yaml
git add nginx-deploy.yaml
git commit -m "changed replicas"
git push origin main

しばらくすると、GitRepositoryリソースの方で新しいrevisionを取得した旨が表示される。

$ kubectl describe gitrepositories web-app-manifests -n flux-demo
:(省略)
Events:
  Type    Reason                      Age                   From               Message
  ----    ------                      ----                  ----               -------
  Normal  NewArtifact                 21m                   source-controller  stored artifact for commit 'initial commit'
  Normal  info                        20m (x2 over 21m)     source-controller  Fetched revision: main/269944292b0b955d01d10f5b820e0d1a69039892
  Normal  GitOperationSucceeded       2m44s (x19 over 20m)  source-controller  no changes since last reconcilation: observed revision 'main@sha1:269944292b0b955d01d10f5b820e0d1a69039892'
  Normal  NewArtifact                 104s                  source-controller  stored artifact for commit 'changed replicas'
  Normal  info                        103s                  source-controller  Fetched revision: main/ed5af1bd776d1f4d20a366964637b72f4339181b

GitRepositoryリソースで変更をキャッチ後、Kustomizationにも伝搬し、以下のようなイベント出力とともにdeploymentリソースが再デプロイされる。

  Normal   ReconciliationSucceeded  8m10s                kustomize-controller  Reconciliation finished in 109.090363ms, next run in 1m0s
  Normal   Progressing              7m10s (x3 over 15m)  kustomize-controller  Deployment/flux-demo/nginx created
  Normal   ReconciliationSucceeded  7m10s                kustomize-controller  Reconciliation finished in 136.902853ms, next run in 1m0s
  Normal   Progressing              3m54s                kustomize-controller  Deployment/flux-demo/nginx configured

最終的にPod数も3つになり、Git上の変更を自動で拾ってクラスタに反映していることが確認できる。

$ kubectl get pod -n flux-demo
NAME                    READY   STATUS    RESTARTS   AGE
nginx-8f458dc5b-22qf2   1/1     Running   0          5m27s
nginx-8f458dc5b-lfnds   1/1     Running   0          8m43s
nginx-8f458dc5b-zsqbl   1/1     Running   0          5m27s

Gitにpush後の即時反映

CI/CDパイプラインに組み込むことを考えた場合、GitRepositoryKustomizationそれぞれのリソースのintervalを待たずにデプロイしたいケースが考えられる。その場合、GitRepository.spec.suspendという一時停止のパラメタがあるので、これをtrue->falseにすることで即時反映が可能となる。

 kubectl patch gitrepository --type merge -p "{\"spec\":{\"suspend\":true}}" web-app-manifests -n flux-demo
 kubectl patch gitrepository --type merge -p "{\"spec\":{\"suspend\":false}}" web-app-manifests -n flux-demo
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?