GitOps ソフトウェアの Flux v1 にはイメージレジストリを監視してイメージタグを自動的に最新化する「Automate image updates(自動イメージ更新)機能」が組み込まれている.別名で「Image Ops」と言ったりもする.具体的には Deployment YAML などの annotations
に fluxcd.io/automated: "true"
を設定すると有効化できていた.
現在使われている Flux v2 にも「Automate image updates(自動イメージ更新)機能」は組み込まれている.しかし Flux v1 と互換性はなく,完全に異なる仕組みになっている.今回は以下のドキュメントを参考にしながら Flux v2 の「Automate image updates(自動イメージ更新)機能」を試していく!
環境
今回は kubeadm を使って構築した Kubernetes v1.23.1 クラスタを使う.
- Kubernetes v1.23.1
全体構成
全体構成をまとめておく.まず,Flux v2 の「Automate image updates(自動イメージ更新)機能」は CRD (Custom Resource Definitions) を使う.以下の2種類のコントローラーでイメージレジストリを監視したり,GitHub リポジトリを更新したりする.そして ImageRepository や ImageUpdateAutomation などの CRD も組み合わせて使う.公式ドキュメントから引用した図がわかりやすい!
- Image Reflector controller(イメージレジストリを監視する)
- Image Automation controller(Git リポジトリを更新する)
Flux CLI をセットアップする
準備として Flux CLI をセットアップしておく.さらに今回使う代表的なサブコマンドも以下にまとめておく.
- flux bootstrap github | Flux
- flux reconcile kustomization | Flux
- flux create image repository | Flux
- flux create image update | Flux
$ curl -s https://fluxcd.io/install.sh | sudo bash $ flux --version flux version 0.28.5
Flux v2 をセットアップする
最初は Kubernetes クラスタに Flux v2 をセットアップする.flux bootstrap github
コマンドを使うと Flux v2 のセットアップと Flux の設定を管理する GitHub リポジトリを自動的に作れる.今回はドキュメントの通りに GitHub リポジトリ flux-image-updates
を使うことにする.セットアップをするときは既に紹介した「Automate image updates(自動イメージ更新)機能」のコントローラもセットアップする必要があるため --components-extra=image-reflector-controller,image-automation-controller
オプションも追加する.
image-reflector-controller
(イメージレジストリを監視する)image-automation-controller
(Git リポジトリを更新する)
$ export GITHUB_USER=kakakakakku $ flux bootstrap github \ --components-extra=image-reflector-controller,image-automation-controller \ --owner=${GITHUB_USER} \ --repository=flux-image-updates \ --branch=main \ --path=clusters/my-cluster \ --read-write-key \ --personal
セットアップ後に確認すると flux-system
Namespace にコントローラが起動されていた.
$ kubectl get pod image-reflector-controller-86db8b6f78-n62lf -n flux-system NAME READY STATUS RESTARTS AGE image-reflector-controller-86db8b6f78-n62lf 1/1 Running 0 10m $ kubectl get pod image-automation-controller-77fd9657c6-7ft2m -n flux-system NAME READY STATUS RESTARTS AGE image-automation-controller-77fd9657c6-7ft2m 1/1 Running 0 10m
そして,自動的に作られた GitHub リポジトリ flux-image-updates
は以下のようなディレクトリ構成になっている.Flux v2 は kustomize を使って構成されるため,設定ファイルとして gotk-components.yaml
と gotk-sync.yaml
も追加されている.
. └── clusters └── my-cluster └── flux-system ├── gotk-components.yaml # Flux v2 コンポーネント群 (Service, Deployment, CustomResourceDefinition など) ├── gotk-sync.yaml # Flux v2 同期コンポーネント群 (GitRepository, Kustomization) └── kustomization.yaml # Kustomize 設定 (Kustomization)
アプリケーションを追加する
さっそくアプリケーションを追加する.今回はサンプルとして stefanprodan/podinfo
を使う.
作った GitHub リポジトリ flux-image-updates
に Deployment YAML を ./clusters/my-cluster/podinfo-deployment.yaml
として追加する.ポイントは Pod のイメージタグで spec.containers.image
に GitHub Container Registry の ghcr.io/stefanprodan/podinfo:5.0.0
を指定している.5.0.0
を覚えておく!
$ git clone https://github.com/${GITHUB_USER}/flux-image-updates $ cd flux-image-updates $ cat <<EOF > ./clusters/my-cluster/podinfo-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: podinfo namespace: default spec: selector: matchLabels: app: podinfo template: metadata: labels: app: podinfo spec: containers: - name: podinfod image: ghcr.io/stefanprodan/podinfo:5.0.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 9898 protocol: TCP EOF
GitHub リポジトリに Deployment YAML を追加して少し待つ(もしくは flux reconcile kustomization
コマンドを使って同期する)と Flux v2 によって Pod がデプロイされる.実際にイメージタグは 5.0.0
になっている.
$ git add -A && \ git commit -m "add podinfo deployment" && \ git push origin main $ flux reconcile kustomization flux-system --with-source $ kubectl get deployments.apps podinfo NAME READY UP-TO-DATE AVAILABLE AGE podinfo 1/1 1 1 10s $ kubectl get deployments.apps podinfo -o yaml | grep 'image:' - image: ghcr.io/stefanprodan/podinfo:5.0.0
ImageRepository オブジェクトを追加する
次に flux create image repository
コマンドを使って ImageRepository
オブジェクトを追加する.
$ flux create image repository podinfo \ --image=ghcr.io/stefanprodan/podinfo \ --interval=1m \ --export > ./clusters/my-cluster/podinfo-registry.yaml
./clusters/my-cluster/podinfo-registry.yaml
は以下となる.ImageRepository
オブジェクトは指定したイメージリポジトリを監視して「新しいタグ」があるかを確認する.
--- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImageRepository metadata: name: podinfo namespace: flux-system spec: image: ghcr.io/stefanprodan/podinfo interval: 1m0s
ImagePolicy オブジェクトを追加する
さらに flux create image policy
コマンドを使って ImagePolicy
オブジェクトを追加する.
$ flux create image policy podinfo \ --image-ref=podinfo \ --select-semver=5.0.x \ --export > ./clusters/my-cluster/podinfo-policy.yaml
./clusters/my-cluster/podinfo-policy.yaml
は以下となる.ImagePolicy
オブジェクトは「どういうポリシーで新しいイメージタグを探すか」を指定する.今回は policy.semver.range: 5.0.x
なので「セマンティックバージョニング」で「パッチバージョンの最新」を探す.
--- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImagePolicy metadata: name: podinfo namespace: flux-system spec: imageRepositoryRef: name: podinfo policy: semver: range: 5.0.x
GitHub Container Registry を確認すると 5.0.x
の最新は 5.0.3
だった.
ちなみに「セマンティックバージョニング」 以外に <branch>-<sha1>-<timestamp>
などのフォーマットを指定して,任意の「並べ替え可能な条件」もできる.詳しくはドキュメントに載っている.
ImageRepository と ImagePolicy を適用する
GitHub リポジトリに ImageRepository
YAML と ImagePolicy
YAML を追加して少し待つ(もしくは flux reconcile kustomization
コマンドを使って同期する)と Flux v2 によってデプロイされる.準備 OK!
$ git add -A && \ git commit -m "add podinfo image scan" && \ git push origin main $ flux reconcile kustomization flux-system --with-source $ flux get image repository podinfo NAME LAST SCAN SUSPENDED READY MESSAGE podinfo 2022-04-18T00:00:00Z False True successful scan, found 33 tags $ flux get image policy podinfo NAME LATEST IMAGE READY MESSAGE podinfo ghcr.io/stefanprodan/podinfo:5.0.3 True Latest image tag for 'ghcr.io/stefanprodan/podinfo' resolved to: 5.0.3
ImageUpdateAutomation オブジェクトを追加する
Flux v2 の「Automate image updates(自動イメージ更新)機能」を有効化するためには Deployment YAML の spec.containers.image
に # {"$imagepolicy": "flux-system:podinfo"}
のようにコメントを書く必要がある.
spec: containers: - name: podinfod image: ghcr.io/stefanprodan/podinfo:5.0.0 # {"$imagepolicy": "flux-system:podinfo"}
そして flux create image update
コマンドを使って ImageUpdateAutomation
オブジェクトを追加する.
$ flux create image update flux-system \ --git-repo-ref=flux-system \ --git-repo-path="./clusters/my-cluster" \ --checkout-branch=main \ --push-branch=main \ --author-name=fluxcdbot \ --author-email=fluxcdbot@users.noreply.github.com \ --commit-template="{{range .Updated.Images}}{{println .}}{{end}}" \ --export > ./clusters/my-cluster/flux-system-automation.yaml
./clusters/my-cluster/flux-system-automation.yaml
は以下となる.ImageUpdateAutomation
オブジェクトは「どういう設定で GitHub リポジトリにコミットをするか」を指定する.
--- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImageUpdateAutomation metadata: name: flux-system namespace: flux-system spec: git: checkout: ref: branch: main commit: author: email: fluxcdbot@users.noreply.github.com name: fluxcdbot messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}' push: branch: main interval: 1m0s sourceRef: kind: GitRepository name: flux-system update: path: ./clusters/my-cluster strategy: Setters
自動イメージ更新を待つ
GitHub リポジトリに ImageUpdateAutomation
YAML を追加して少し待つ(もしくは flux reconcile kustomization
コマンドを使って同期する)と Flux v2 によってデプロイされる.少し待っていると 5.0.0
から 5.0.3
に更新された!👏
$ git add -A && \ git commit -m "add image updates automation" && \ git push origin main $ kubectl get deployments.apps podinfo -o yaml | grep 'image:' - image: ghcr.io/stefanprodan/podinfo:5.0.0 (少し待つ...) $ kubectl get deployments.apps podinfo -o yaml | grep 'image:' - image: ghcr.io/stefanprodan/podinfo:5.0.3
GitHub の podinfo-deployment.yaml
も Flux v2 によって更新されていた.
spec: containers: - name: podinfod image: ghcr.io/stefanprodan/podinfo:5.0.3 # {"$imagepolicy": "flux-system:podinfo"}
GitHub の差分も載せておく!
マイナーバージョンとパッチバージョンの最新を探す
今度は ImagePolicy
オブジェクトを更新して「マイナーバージョンとパッチバージョンの最新」を探す.policy.semver.range: 5.0.x
から policy.semver. range: ^5
にした.
--- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImagePolicy metadata: name: podinfo namespace: flux-system spec: imageRepositoryRef: name: podinfo policy: semver: range: ^5
GitHub リポジトリに ImageUpdateAutomation
YAML を追加して少し待つ(もしくは flux reconcile kustomization
コマンドを使って同期する)と Flux v2 によってデプロイされる.少し待っていると 5.0.3
から 5.2.1
に更新された!👏
$ git add -A && \ git commit -m "update image policy" && \ git push origin main $ kubectl get deployments.apps podinfo -o yaml | grep 'image:' - image: ghcr.io/stefanprodan/podinfo:5.0.0 (少し待つ...) $ kubectl get deployments.apps podinfo -o yaml | grep 'image:' - image: ghcr.io/stefanprodan/podinfo:5.2.1
まとめ
Flux v2 でも「Automate image updates(自動イメージ更新)機能」を使って「Image Ops」を実現できることを確認できた.しかし Flux v1 と互換性はなく,多くの CRD (Custom Resource Definitions) を組み合わせた構成になっている点は覚えておくと良さそう.以下のドキュメントに Flux v1 → Flux v2 にマイグレーションする手順が載っている.