フォーム読み込み中
こんにちは。ソフトバンクの木村です。
この記事は、ソフトバンク Advent Calendar 2023 の 19日目の記事になります。
MSPサービスのオプションサービスである、クラウドネイティブ・アプリケーションプラットフォーム(CNAP)の開発業務を行っています。
CNAPでは、GitOpsを実現するOSSであるFluxのImage Update Automationsを利用し、サービスを構成するコンテナイメージの自動管理を実現しています。
本記事では機能概要や利用方法について解説します。
FluxとはKubernetes上で動作するGitOpsを実現するためのOSSです。
Kubernetes上で複数のアプリケーションを動かす際には、それぞれのアプリケーションごとに Kubernetesのマニフェストや、マニフェストをまとめたKustomization、パッケージとしてまとめた Helmなどを利用して構築作業を実施します。しかし、構築するアプリケーションの数が増えていくと、アプリケーションごとの依存関係などを管理しインストールを行うことが難しくなっていきます。
これらの管理を簡単にし、DevOpsをより効率的に実現する手法の一つがGitOpsになります。GitOpsではすべてのリソースを Gitリポジトリ上で設定ファイルとして管理した上で、管理されたコードをもとにCI/CDを行い構築を自動化します。
Kubernetes上でGitOpsを実現するアプリケーションはOSSを含めていくつか存在しますが、その中の一つがFluxです。Fluxでは各アプリケーションのリポジトリやマニフェストの適用作業そのものをKubernetesのCRDsのマニフェストとして管理することができます。
Fluxでは各アプリケーションのリポジトリについては、例として以下の設定をCRDsで記載できます。
また、各アプリケーションの適用作業については、例として以下の設定をCRDsで記載できます。
また、Flux ではリポジトリや各アプリケーションの適用作業にて、どのタグを参照して構築を行うかをsemver形式で指定することができます。環境に応じて、パッチバージョンのみ最新版を適用しマイナーバージョン以上は自動更新しない、開発版のalphaリリースを含めて適用するなど、細かくバージョンを制御することが可能です。
Image Update AutomationsとはFluxにて設定されたGitリポジトリに対して、イメージのタグの自動更新を行う機能です。
先程の章で説明した通り、Fluxではリポジトリや各アプリケーションの適用作業にてどのタグを参照して構築を行うかsemver形式で指定することができます。
しかし、以下のようにマニフェスト内部で定義しているDeploymentなどのイメージタグの指定についてはsemver形式を利用することができないため、固定のタグを付与して逐次更新するか、latestを設定して最新版のタグを適用することしかできません。
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: podinfo
spec:
selector:
...途中省略...
spec:
containers:
- name: podinfo
# 以下のような書き方はできない
image: ghcr.io/stefanprodan/podinfo:5.0.x
# 以下のような書き方しかできない
image: ghcr.io/stefanprodan/podinfo:latest
image: ghcr.io/stefanprodan/podinfo:5.0.3
そこで、マニフェスト内のイメージタグの更新を自動化する機能として、 FluxではImage Update Automationsという機能が用意されています。
マニフェストに決められてたフォーマットでコメントを記載しておくことで、Image Update Automationsのコンポーネントが、自動的にイメージのタグを更新するGitリポジトリへのコミットを作成します。これにより決められたポリシーでイメージタグの更新を自動化することが可能になります。
Image Update Automationsでは以下の 3つのCRDsの設定に従って、イメージの更新を行います。
この章ではImage Update Automationsのインストール手順について解説します。
Image Update Automations を利用するためには、Fluxのインストール手順にて、
以下の通り --components-extra 引数にImage Update Automationsのコンポーネントを追加で指定します。
$ export GITHUB_TOKEN=[アクセストークン]
$ export GITHUB_ORGNIZATION=[Organization名]
$ export GITHUB_REPOSITORY=[Fluxの管理対象にするリポジトリ名]
$ export GITHUB_BRANCH=[Fluxの管理対象にするブランチ名]
$ export GITHUB_PATH=[Fluxの管理対象にするディレクトリパス]
# Fluxのインストール手順を実施
$ flux bootstrap github \
--components-extra=image-reflector-controller,image-automation-controller \
--token-auth \
--owner=${GITHUB_ORGANIZATION} \
--repository=${GITHUB_REPOSITORY}} \
--branch=${GITHUB_BRANCH} \
--path=${GITHUB_PATH}
# Image Update Automations関連のコンポーネントも含めて、Fluxのコントローラーが全て構築されていることを確認
$ kubectl get deployment -n flux-system
NAME READY UP-TO-DATE AVAILABLE AGE
helm-controller 1/1 1 1 5d1h
image-automation-controller 1/1 1 1 5d1h
image-reflector-controller 1/1 1 1 5d1h
kustomize-controller 1/1 1 1 5d1h
notification-controller 1/1 1 1 5d1h
source-controller 1/1 1 1 5d1h
次に検証用のDeploymentを構築します。今回は試験用にpodinfoという検証用のコンテナイメージを利用します。アップデートの検証のため、イメージのタグは5.0.0というバージョンを指定します。
# Fluxの設定をしたGitリポジトリをclone
git clone https://github.com/${GITHUB_ORGANIZATION}/${GITHUB_REPOSITORY}
cd ${GITHUB_REPOSITORY}
# Deploymentマニフェストを作成
vi ./${GITHUB_PATH}/deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: podinfo
spec:
selector:
matchLabels:
app: podinfo
template:
metadata:
labels:
app: podinfo
spec:
containers:
- name: podinfo
image: ghcr.io/stefanprodan/podinfo:5.0.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 9898
protocol: TCP
DeploymentのマニフェストをGitリポジトリにプッシュし、Fluxが正常に動作してコンテナバージョンが5.0.0のDeploymentが構築されていることを確認します。
# マニフェストをpush
$ git add -A
$ git commit -m "add podinfo deployment"
$ git push origin main
# Fluxに変更を即時に反映するようにコマンド実行
$ flux reconcile kustomization flux-system --with-source
# 実際に構築されたDeploymentのコンテナのバージョンが5.0.0になっていることを確認
$ kubectl get deployment/podinfo -oyaml | grep 'image:'
image: ghcr.io/stefanprodan/podinfo:5.0.0
この章ではImage Update Automationsの利用方法を説明します。
ImageRepository、ImagePolicy、ImageUpdateAutomationの3つマニフェストを作成したうえで、検証用のDeploymentにタグを更新するコメントを記載して、イメージのタグが自動的に更新されることを確認します。
最初にImageRepositoryを作成しイメージのリポジトリの設定を行います。マニフェストを自動生成した上でGitリポジトリにプッシュすることで、イメージのリポジトリと疎通ができていることを確認します。
なお、今回はパブリックなイメージのリポジトリを利用していますが、プライベートなイメージのリポジトリを利用する場合は、Docker config形式のSecretをImageRepositoryとおなじnamespace(今回の場合 flux-system)に作成した上で、ImageRepositoryの spec.secretRef.name にて指定します。
# fluxのコマンドでImageRepositoryのマニフェストを自動生成
$ flux create image repository podinfo \
--image=ghcr.io/stefanprodan/podinfo \
--interval=1m \
--export > ${GITHUB_PATH}/image-repository.yaml
# マニフェストをpush
$ git add -A
$ git commit -m "add image repository"
$ git push origin main
# Fluxに変更を即時に反映するようにコマンド実行
$ flux reconcile kustomization flux-system --with-source
# ImageRepository CRが構築されていて、リポジトリとの疎通ができていることを確認
$ kubectl get imagerepository -n flux-system
NAME LAST SCAN TAGS
podinfo 2023-12-08T23:13:15Z 86
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageRepository
metadata:
name: podinfo
namespace: flux-system
spec:
image: ghcr.io/stefanprodan/podinfo
interval: 1m0s
次にImagePolicyを作成し、イメージのバージョンをどのポリシーで最新化するかを定義します。
spec.policy にイメージのバージョンのポリシーを設定します。今回はsemver形式で指定を行い、パッチバージョンの最新バージョンを取得するポリシーを設定しています。なお、ポリシーについては、semver以外にアルファベット順などの指定も可能です。
# fluxのコマンドでImagePolicyのマニフェストを自動生成
$ flux create image policy podinfo \
--image-ref=podinfo \
--select-semver=5.0.x \
--export > ${GITHUB_PATH}/image-policy.yaml
# マニフェストをpush
$ git add -A
$ git commit -m "add image policy"
$ git push origin main
# Fluxに変更を即時に反映するようにコマンド実行
$ flux reconcile kustomization flux-system --with-source
# ImagePolicy CRが構築されていて、タグが設定したポリシー通り取得できていることを確認
$ kubectl get imagepolicy -n flux-system
NAME LATESTIMAGE
podinfo ghcr.io/stefanprodan/podinfo:5.0.3
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: podinfo
namespace: flux-system
spec:
imageRepositoryRef:
name: podinfo
policy:
semver:
range: 5.0.x
次にImageUpdateAutomationを作成し、Gitリポジトリに対してどのようなポリシーでコミットを作成するか設定します。
なお、--checkout-branch と --push-branch に別のブランチを指定することで、更新結果を一度検証用ブランチにコミットさせたあとで、手動で本番用のブランチにマージさせるといった運用も可能です。
# fluxのコマンドでImageUpdateAutomationのマニフェストを自動生成
$ flux create image update flux-system \
--git-repo-ref=flux-system \
--git-repo-path=${GITHUB_PATH} \
--checkout-branch=${GITHUB_BRANCH} \
--push-branch=${GITHUB_BRANCH} \
--author-name=fluxcdbot \
--author-email=fluxcdbot@users.noreply.github.com \
--commit-template="{{range .Updated.Images}}{{println .}}{{end}}" \
--export > ${GITHUB_PATH}/image-update-automation.yaml
# マニフェストをpush
$ git add -A
$ git commit -m "add image update automation"
$ git push origin main
# Fluxに変更を即時に反映するようにコマンド実行
$ flux reconcile kustomization flux-system --with-source
# ImageUpdateAutomationによる更新が実施されていることを確認
$ kubectl get imageupdateautomation -A
NAMESPACE NAME LAST RUN
flux-system flux-system 2023-12-09T11:22:21Z
---
apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
name: flux-system
namespace: flux-system
spec:
git:
checkout:
ref:
branch: 指定したブランチ
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
messageTemplate: '{{range .Updated.Images}}{{println .}}{{end}}'
push:
branch: 指定したブランチ
interval: 1m0s
sourceRef:
kind: GitRepository
name: flux-system
update:
path: Fluxの管理対象にするディレクトリパスを指定
strategy: Setters
最後に検証用のDeploymentのマニフェストにタグ更新用のコメントを記載し、イメージのタグが自動的に更新されることを確認します。コメント内ではImagePolicyの情報を指定します。設定をpushするとDeploymentのタグを更新するGitへのコミットがImage Update Automationsのコンポーネントによって自動的に作成され、イメージのタグが更新されます。
spec:
containers:
- name: podinfo
image: ghcr.io/stefanprodan/podinfo:5.0.0 # {"$imagepolicy": "flux-system:podinfo"}
# fluxのコマンドでImageUpdateAutomationのマニフェストを自動生成
# マニフェストをpush
$ git add -A
$ git commit -m "update podinfo image"
$ git push origin main
# Fluxに変更を即時に反映するようにコマンド実行
$ flux reconcile kustomization flux-system --with-source
# しばらく待つとDeploymentのイメージのタグが設定したポリシー通り更新されている
$ kubectl get deployment/podinfo -oyaml | grep 'image:'
image: ghcr.io/stefanprodan/podinfo:5.0.3
# Gitのログにコミット履歴があることを確認
$ git log
commit d2e122d1a26220df6702754175637600aec584bd (HEAD -> main, origin/main, origin/HEAD)
Author: fluxcdbot
Date: Fri Dec 9 08:40:46 2023 +0000
ghcr.io/stefanprodan/podinfo:5.0.3
今回はFluxのImage Update Automationsについて紹介しました。
Image Update Automationsを利用することで、コンテナイメージの更新についてもGitOpsを利用して細かい制御を行うことが可能になります。
以上、最後までお読みいただきありがとうございました。
条件に該当するページがございません