はじめに
AzureのK8sサービスであるAKSでは拡張機能としてCDツールのFluxが導入できます。さらにFluxはイメージ自動更新までできますが、Azure公式のドキュメントではそこまでの手順を解説してくれていませんでした。そのため、Flux導入からイメージ自動更新まで設定する流れをまとめました。
環境
クラウド
リソースグループにAKSおよびACRが作成されている状態から開始します。GitHubのリポジトリも予め用意しておきます。
AKS拡張機能でインストールするとns:flux-systemにfluxconfig-controller等のFluxコントローラ一式がデプロイされます。ns:flux-testにFluxで管理する対象リソースをデプロイします。
ディレクトリ構造
GitHubのリポジトリは以下のディレクトリ構造です。
flux
ディレクトリ配下はAKS拡張機能のFluxをインストールするTerraformコード群です。
flux-test
はテスト用のNamespaceです。test-app
配下にテスト用アプリケーションのファイル群を配置します。k8s
はテスト用アプリケーションのk8sマニフェスト群です。terraform
はfluxconfigをAzureで設定するterraformファイルです。
.
├── flux
│ ├── base.tf
│ └── container.tf
└── flux-test
├── ns.yaml
└── test-app
├── k8s
│ ├── flux-configs.yaml
│ ├── kustomization.yaml
│ └── pod.yaml
└── terraform
└── container.tf
手順
Fluxのインストール
AKS拡張機能でFluxをAKSにインストールします。
リソースプロバイダ
Fluxをインストールする前に以下のリソースプロバイダーを有効にします。チュートリアル: GitOps with Flux v2 を使ってアプリケーションをデプロイする
- Microsoft.ContainerService(既定で有効)
- Microsoft.Kubernetes
- Microsoft.KubernetesConfiguration
Microsoft.ContainerService
は既定で有効なためそれ以外の2つを有効化します。
resource "azurerm_resource_provider_registration" "k8s" {
name = "Microsoft.Kubernetes"
}
resource "azurerm_resource_provider_registration" "k8sconfiguration" {
name = "Microsoft.KubernetesConfiguration"
}
Fluxのインストール
AKS拡張機能のFluxをインストールします。イメージ自動更新をする場合は明示的にオプションを指定します。Flux クラスター拡張機能を使用してデプロイするコントローラーを制御する
resource "azurerm_kubernetes_cluster_extension" "flux" {
name = "Flux"
cluster_id = AKS_CLUSTER_ID
extension_type = "microsoft.flux"
configuration_settings = {
"image-automation-controller.enabled" = true # 自動イメージ更新機能を有効化
"image-reflector-controller.enabled" = true # 自動イメージ更新機能を有効化
}
depends_on = [azurerm_resource_provider_registration.k8s, azurerm_resource_provider_registration.k8sconfiguration]
}
GitOpsの設定
FluxのGitOps設定をします。
Namespace作成
Fluxでデプロイするリソース群を配置するNamespaceを作成します。
apiVersion: v1
kind: Namespace
metadata:
name: flux-test
GitHub認証情報の作成
GitOps設定をする前にGitHubへアクセスするための認証情報を作成します。GitHubにアクセスする認証情報(ユーザー名、パーソナルアクセストークン)を使って以下のようにSecretを作成します。ソースでの認証のためのローカル シークレット
kubectl create secret generic -n flux-test github-auth --from-literal=username=<GitHubユーザー名> --from-literal=password=<GitHubパーソナルアクセストークン>
認証情報をファイルに残したくなかったためコマンドでSecretを作成しています。
fluxconfigの設定
AKS拡張機能でFluxをインストールするとfluxconfigをAzureで設定できます。git_repository.local_auth_reference
は先ほど作成したGitHub認証情報のSecretを指定します。kustomizations.path
はkustomization.yamlを配置しているディレクトリのパスを指定します。このfluxconfigのリソース名はAKSクラスタ内で一意でないといけません。
resource "azurerm_kubernetes_flux_configuration" "test_app" {
name = "flux-test-test-app"
cluster_id = AKS_CLUSTER_ID
namespace = "flux-test"
git_repository {
url = "https://github.com/ORG/REPONAME"
reference_type = "branch"
reference_value = "main"
sync_interval_in_seconds = 60
timeout_in_seconds = 60
local_auth_reference = "github-auth" # GitHub認証のSecret名
}
kustomizations {
depends_on = []
garbage_collection_enabled = false
name = "kustomization"
path = "flux-test/test-app/k8s"
recreating_enabled = false
retry_interval_in_seconds = 60
sync_interval_in_seconds = 60
timeout_in_seconds = 60
}
}
動作確認
fluxconfigをデプロイするとGitHubに格納している以下マニフェストをFluxが自動でデプロイしてくれているはずです。
apiVersion: v1
kind: Pod
metadata:
labels:
flux: v1
name: test-app
spec:
containers:
- image: REGISTRYNAME.azurecr.io/test-app:20240814-1210
name: test-app
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: flux-test
metadata:
name: test-app
resources:
- pod.yaml
以下コマンドで現在のPodラベルを確認します。
$ kubectl get pod -n flux-test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
test-app 1/1 Running 0 9m56s flux=v1,kustomize.toolkit.fluxcd.io/name=test-app-kustomization,kustomize.toolkit.fluxcd.io/namespace=flux-test
pod.yamlのラベルflux: v1
をflux: v2
に変更してGitHubにpushします。しばらくするとPodのラベルが更新されているはずです。
$ kubectl get pod -n flux-test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
test-app 1/1 Running 0 13m flux=v2,kustomize.toolkit.fluxcd.io/name=test-app-kustomization,kustomize.toolkit.fluxcd.io/namespace=flux-test
Cluster Scopeのリソースがある場合
Namespaceに納まらないリソースが含まれるとkustomize-controller
のPodログにcluster scopeのリソースに関するエラーが出力されデプロイできない。
{"level":"error","ts":"2024-08-14T09:00:23.222Z","msg":"Reconciliation failed after 111.770573ms, next try in 1m0s","controller":"kustomization","controllerGroup":"kustomize.toolkit.fluxcd.io","controllerKind":"Kustomization","Kustomization":{"name":"flux-test-test-app-kustomization","namespace":"flux-test"},"namespace":"flux-test","name":"flux-test-test-app-kustomization","reconcileID":"99f2ef4a-584c-467f-bebe-247776bd6c07","revision":"main@sha1:9449402cada8205e86d087b48a8cac7c29da85aa","error":"ClusterRoleBinding/testtest dry-run failed (Forbidden): clusterrolebindings.rbac.authorization.k8s.io \"testtest\" is forbidden: User \"system:serviceaccount:flux-test:flux-applier\" cannot patch resource \"clusterrolebindings\" in API group \"rbac.authorization.k8s.io\" at the cluster scope\n"}
fluxconfigのScopeをClusterに変えるかNamespace内のsa:flux-applierにcluster-adminを付ければデプロイできるようになる。
$ kubectl create clusterrolebinding --serviceaccount="flux-test:flux-applier" --clusterrole="cluster-admin" my-flux-applier-crb
イメージ自動更新の設定
Fluxのイメージ自動更新を設定します。
ACR認証情報の作成
イメージ自動更新の設定をする前にFluxがACRを参照できるようにします。以下コマンドでFlux専用のサービスプリンシパルを作成します。サービス プリンシパルの作成
$ az ad sp create-for-rbac --name acr-pull-for-flux --role acrpull --scopes /subscriptions/SUBSCRIPTIONID/resourceGroups/RESOUCEGROUPNAME/providers/Microsoft.ContainerRegistry/registries/REGISTRYNAME
上記コマンドを実行すると以下のような出力が得られます。
{
"appId": "your-app-id",
"displayName": "acr-pull-for-flux",
"password": "YOURPASSWORD",
"tenant": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
上記の出力結果を使ってdocker-registryタイプのSecretを作成します。Secretはこの後作るImageRepositoryと同じNamesapceに作ります。イメージのプル シークレットを作成する
$ kubectl create secret docker-registry acr-pull-for-flux \
--namespace flux-test \
--docker-server=REGISTRYNAME.azurecr.io \
--docker-username=your-app-id \
--docker-password=YOURPASSWORD
認証情報をファイルに残したくなかったためコマンドでSecretを作成しています。
イメージ自動更新の設定
ImageRepository
、ImagePolicy
、ImageUpdateAutomation
の3つのリソースを作成します。ImageRepository
では先ほど作成したdocker-registryタイプのSecret名を指定します。ImagePolicy
ではYYYYMMDD-hhmm
の形式でタグ付けされるイメージの最新をalphabetical
のasc
(昇順)で指定します。ImageUpdateAutomation
のソースはAzureで作成したfluxconfigの名前を指定します。
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageRepository
metadata:
name: test-app
namespace: flux-test
spec:
image: REGISTRYNAME.azurecr.io/test-app
interval: 1m
secretRef:
name: acr-pull-for-flux # 予め作成したACR pull用のSecret
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: test-app
namespace: flux-test
spec:
imageRepositoryRef:
name: test-app
policy:
alphabetical:
order: asc # 昇順で最後のイメージを選択
---
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImageUpdateAutomation
metadata:
name: test-app
namespace: flux-test
spec:
interval: 1m
sourceRef:
kind: GitRepository
name: flux-test-test-app # Azureで作成したfluxconfigの名前
git:
commit:
author:
email: fluxcdbot@users.noreply.github.com
name: fluxcdbot
push:
branch: main
update:
strategy: "Setters"
path: ./
マニフェストのマーカー
マニフェストのイメージ更新したい箇所にコメントでマーカーを設定します。Configure image update for custom resources
...
spec:
containers:
- image: REGISTRYNAME.azurecr.io/test-app:20240813-1823 # {"$imagepolicy": "flux-test:test-app"}
name: test-app
...
動作確認
現在のPodイメージを確認します。
$ kubectl describe pod -n flux-test test-app | grep Image:
Image: REGISTRYNAME.azurecr.io/test-app:20240813-1823
コンテナイメージを適当に更新しACRに最新のイメージを格納します。しばらくした後にPodイメージを確認すると以下のように更新されているはずです。
$ kubectl describe pod -n test test-app | grep Image:
Image: REGISTRYNAME.azurecr.io/test-app:20240814-1210
Fluxによりリモートリポジトリが更新されているため最後にリポジトリをpullしておく。
まとめ
拡張機能なので自分たちでツールを管理するよりは楽になるはず。ArgoCDとは違いGUIはありませんが、最低限使う分には支障ないでしょう。