この記事について
Kubernetesと連携して使うAzureのリソースを、Azure Service Operator (ASO) を使ってデプロイしてみた。
背景
- KubernetesはManifest、AzureリソースはBicepでIaC書いてたが、統一したい
- Bicepはデプロイするためのワークフローが必要だが、ワークフローを管理したくない
前提条件
- azure cli, kubectl, helmがインストール済み
環境
- Kunbernetes
- Kubernetes Version: 1.28.5
- Azure CLI
- version: 2.59.0
AKSのデプロイ
AKSをデプロイする
export AKS_CLUSTER_NAME="myAKSCluster"
export AKS_RG_NAME="myResourceGroup"
export LOCATION="japaneast"
az group create -n ${AKS_RG_NAME} -l ${LOCATION}
az aks create -n ${AKS_CLUSTER_NAME} -g ${AKS_RG_NAME} -l ${LOCATION} \
--enable-oidc-issuer \
--enable-workload-identity \
--network-plugin azure \
--node-vm-size Standard_B2ms \
--node-count 1
kubeconfigを取得する
az aks get-credentials --resource-group ${AKS_RG_NAME} --name ${AKS_CLUSTER_NAME} \
--overwrite-existing
Azure Service Operatorのインストール
ほとんど公式の手順そのまま
cert-managerのインストール
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.14.1/cert-manager.yaml
federated credentialのセットアップ
ASOがAzureのサービスをデプロイできるように権限を付与する必要がある。
まずはUser Assigned Identityをデプロイする。
権限はサブスクリプションのOwnerにする(つよいので注意)。
export USER_ASSIGNED_ID_NAME="myIdentity"
export USER_ASSIGNED_ID_RG="myResourceGroup"
export SUBSCRIPTION_ID="$(az account show --query id --output tsv)"
az identity create --name "${USER_ASSIGNED_ID_NAME}" \
--resource-group "${USER_ASSIGNED_ID_RG}" \
--location "${LOCATION}" \
--subscription "${SUBSCRIPTION_ID}"
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${USER_ASSIGNED_ID_RG}" --name "${USER_ASSIGNED_ID_NAME}" --query 'clientId' -otsv)"
export IDENTITY_TENANT=$(az aks show --name ${AKS_CLUSTER_NAME} --resource-group ${AKS_RG_NAME} --query identity.tenantId -o tsv)
az role assignment create --assignee ${USER_ASSIGNED_CLIENT_ID} \
--role Contributor --scope /subscriptions/${SUBSCRIPTION_ID}
クラスタのOIDC issuerのアドレスを取得する。
export AKS_OIDC_ISSUER="$(az aks show -n "${AKS_CLUSTER_NAME}" -g "${AKS_RG_NAME}" --query "oidcIssuerProfile.issuerUrl" -otsv)"
federated credentialを作成する。
az identity federated-credential create --name aso-federated-credential \
--identity-name ${USER_ASSIGNED_ID_NAME} --resource-group ${USER_ASSIGNED_ID_RG} \
--issuer ${AKS_OIDC_ISSUER} \
--subject "system:serviceaccount:azureserviceoperator-system:azureserviceoperator-default" \
--audiences "api://AzureADTokenExchange"
ASOのインストール
helmのリポジトリを追加する。
helm repo add aso2 https://raw.githubusercontent.com/Azure/azure-service-operator/main/v2/charts
helm repo update
helmのvalues.yamlを作成する。
認証はWorkload Identityで行うようにする。
cat - << EOF > values.yaml
azureSubscriptionID: "${SUBSCRIPTION_ID}"
azureTenantID: "${IDENTITY_TENANT}"
azureClientID: "${USER_ASSIGNED_CLIENT_ID}"
useWorkloadIdentityAuth: true
crdPattern: 'resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*'
EOF
Azure Service Operatorをインストールする。
デフォルトのnamespace名が、長い…。
helm upgrade --install aso2 aso2/azure-service-operator \
--create-namespace \
--namespace=azureserviceoperator-system \
-f values.yaml
そのうちPodが立ち上がる。
$ kubectl get pods -n azureserviceoperator-system
NAME READY STATUS RESTARTS AGE
azureserviceoperator-controller-manager-5df476889c-x2crc 1/1 Running 1 (6m28s ago) 6m44s
リソースをデプロイしてみる
サポートされているリソースの一覧は、以下から確認できる。
Resource Group
デプロイ先のnamespaceを作成する
kubectl create ns aso-sample
リソースグループのCustomResourceを作成する。
cat <<EOF | kubectl apply -f -
apiVersion: resources.azure.com/v1api20200601
kind: ResourceGroup
metadata:
name: aso-sample-rg
namespace: aso-sample
spec:
location: japaneast
EOF
kubectlでresourcegroupsを取得すると、READY=Trueと表示される。
$ kubectl get resourcegroups.resources.azure.com -n aso-sample
NAME READY SEVERITY REASON MESSAGE
aso-sample-rg True Succeeded
同様にaz cliでリソースグループが正しく作成できていることが確認できる。
$ az group list -o table --query "[?name=='aso-sample-rg']"
Name Location
------------- ----------
aso-sample-rg japaneast
User Assigned Identity
Manifestが簡単そうなので、User Assigned Identityをデプロイしてみる。
サンプルをほぼそのままコピペ。
cat <<EOF | kubectl apply -f -
apiVersion: managedidentity.azure.com/v1api20230131
kind: UserAssignedIdentity
metadata:
name: sampleuserassignedidentity
namespace: aso-sample
spec:
location: japaneast
owner:
name: aso-sample-rg
operatorSpec:
configMaps:
clientId:
name: umi-cm
key: clientId
principalId:
name: umi-cm
key: principalId
tenantId:
name: umi-cm
key: tenantId
secrets:
clientId:
name: umi-secret
key: clientId
principalId:
name: umi-secret
key: principalId
tenantId:
name: umi-secret
key: tenantId
EOF
同様に、az cliからもデプロイされていることを確認。
$ az identity list -g aso-sample-rg \
-o table --query "[?name=='sampleuserassignedidentity']"
Name Location TenantId PrincipalId ClientId ResourceGroup
-------------------------- ---------- ------------------------------------ ------------------------------------ ------------------------------------ ---------------
sampleuserassignedidentity japaneast 454dfabb-ba50-4830-be47-c8530d997f69 30e89404-8cc4-4231-9661-67ea882a8fbe b4833b6d-5498-4a32-acf5-f5f6aedfd90f aso-sample-rg
リソースを消してみる
リソースグループを消す(時間が、ちょっとかかる)。
$ kubectl delete resourcegroups.resources.azure.com -n aso-sample aso-sample-rg
resourcegroup.resources.azure.com "aso-sample-rg" deleted
リソースグループに入っていたUser Assigned Identityのカスタムリソースも、ちゃんと消えてる!
素晴らしい!
$ kubectl get userassignedidentities.managedidentity.azure.com -n aso-sample
No resources found in aso-sample namespace.
まとめ
Azure Service OperatorをAKSにインストールし、簡単なAzureリソースを作成、削除してみた。
期待していた通り、Kubernetesのリソースを扱うが如く、Azureリソースを作成できた。
ただし、サンプルを軽く覗いた感じ、VMやDB等、よく使うリソースは設定も複雑っぽいので、個別に検証していきたい。