この記事について
前回の記事でAKSにGrafana Lokiをデプロイした。今回はGrafana LokiのストレージをAzure Blob Storageに変更してみたのでその作業記録をメモする。Azure Blob Storageへの認証には、セキュアなworkload identityを使用した。
前提条件
- AKSはデプロイ済み
- AKS上にGrafana Lokiをデプロイ済み
- azure cliをインストール済み
環境
- Azure Kubernetes Service
- Kubernetes Version: 1.26.6
- Agentpoolのノードサイズと数: Standard_B2ms x 1
- Grafana Loki
- chart version: 5.15.0
- app versaion: 2.8.4
- Promtail
- chart version: 6.15.0
- app versaion: 2.8.3
- Grafana
- chart version: 6.59.0
- app versaion: 10.1.0
- azure cli version: 2.52.0
手順
workload identityを有効する
公式ドキュメントの手順に従えばOK。Key Vaultは今回は使わないのでデプロイしない。
環境変数を設定する。service account namespaceはgrafanaにしておく。あとはデフォルトのまま。
export RESOURCE_GROUP="myResourceGroup"
export LOCATION="japaneast"
export SERVICE_ACCOUNT_NAMESPACE="grafana"
export SERVICE_ACCOUNT_NAME="workload-identity-grafana-loki"
export SUBSCRIPTION="$(az account show --query id --output tsv)"
export USER_ASSIGNED_IDENTITY_NAME="myIdentity"
export FEDERATED_IDENTITY_CREDENTIAL_NAME="myFedIdentity"
export AKS_CLUSTER_NAME="myakscluster"
workload identityが使えるようにAKSの設定を更新する。
az aks update -g "${RESOURCE_GROUP}" -n ${AKS_CLUSTER_NAME} \
--enable-oidc-issuer --enable-workload-identity
OIDC issuerのURLを取得する。
export AKS_OIDC_ISSUER="$(az aks show -n ${AKS_CLUSTER_NAME} \
-g "${RESOURCE_GROUP}" --query "oidcIssuerProfile.issuerUrl" -otsv)"
Managed IDを作成し、クライアントIDを取得する。
az identity create --name "${USER_ASSIGNED_IDENTITY_NAME}" --resource-group "${RESOURCE_GROUP}" --location "${LOCATION}" --subscription "${SUBSCRIPTION}"
export USER_ASSIGNED_CLIENT_ID="$(az identity show --resource-group "${RESOURCE_GROUP}" --name "${USER_ASSIGNED_IDENTITY_NAME}" --query 'clientId' -otsv)"
公式ドキュメントではここでサービスアカウントを作成するが、今回はGrafana LokiのHELMから作成させたいので、スキップする。
Azure Blob Storageのデプロイ
設定はここを参考に。
ストレージアカウントを作成する。
export STORAGE_ACCOUNT_NAME="NAME OF YOUR STORAGE ACCOUT"
az storage account create --name ${STORAGE_ACCOUNT_NAME} \
--resource-group ${RESOURCE_GROUP} \
--location japaneast \
--sku Standard_LRS
デフォルトではstorage accountに対するpublic accessが有効なので、これを無効にすべきである。が、今回は設定後に動作確認をしやすくするために、あえてデフォルトのままにしている。
コンテナを作成する。Lokiはデフォルトで chunks
, ruler
, admin
という名前の3つのコンテナを使用する。コンテナがない場合は、自動作成などはしてくれないので必ず事前に作成すること。
az storage container create --name chunks --account-name ${STORAGE_ACCOUNT_NAME} -g ${RESOURCE_GROUP}
az storage container create --name ruler --account-name ${STORAGE_ACCOUNT_NAME} -g ${RESOURCE_GROUP}
az storage container create --name admin --account-name ${STORAGE_ACCOUNT_NAME} -g ${RESOURCE_GROUP}
Managed IDがStorage Accoutに書き込みできるように、Storage Blob Data Contributor ロールを付与する。
export STORAGE_ACCOUNT_SCOPE=$(az storage account show -n $STORAGE_ACCOUNT_NAME --query id -o tsv)
az role assignment create --role "Storage Blob Data Contributor" \
--assignee ${USER_ASSIGNED_CLIENT_ID} --scope ${STORAGE_ACCOUNT_SCOPE}
Lokiの更新
lokiのストレージをAzure Blob Storageに切り替えるための設定を行う。設定はloki-customvalues.yamlファイルに記述。ポイントは以下の4つ。
- ストレージタイプをazureに設定し、minioはfalseに。
- ストレージとの認証に
useFederatedToken
を設定(useManagedIdentity
を使いたくなるが、そうではないので注意。 - Service Accountのannotationにworkload identityのIDを追加する。
- Podに
azure.workload.identity/use: "true"
のラベルをつける。
cat <<EOF > loki-customvalues.yaml
loki:
auth_enabled: false
podLabels:
azure.workload.identity/use: "true"
commonConfig:
replication_factor: 1
storage:
type: azure
azure:
accountName: ${STORAGE_ACCOUNT_NAME}
useManagedIdentity: false
useFederatedToken: true
userAssignedId: null
requestTimeout: null
endpointSuffix: null
serviceAccount:
create: true
name: ${SERVICE_ACCOUNT_NAME}
annotations:
azure.workload.identity/client-id: "${USER_ASSIGNED_CLIENT_ID}"
minio:
enabled: false
write:
replicas: 1
read:
replicas: 1
backend:
replicas: 1
EOF
helm upgradeで新しいvalueを適用する。
helm upgrade --install loki -n grafana grafana/loki -f loki-customvalues.yaml
マネージドID、サービス アカウント発行者、サブジェクトの間にフェデレーションID資格情報を作成する。
az identity federated-credential create \
--name ${FEDERATED_IDENTITY_CREDENTIAL_NAME} \
--identity-name "${USER_ASSIGNED_IDENTITY_NAME}" \
--resource-group "${RESOURCE_GROUP}" \
--issuer "${AKS_OIDC_ISSUER}" \
--subject system:serviceaccount:"${SERVICE_ACCOUNT_NAMESPACE}":"${SERVICE_ACCOUNT_NAME}" \
--audience api://AzureADTokenExchange
動作確認
Azure Blob Storageのchunksコンテナにログらしき保存されていることを確認(設定してから反映されるまでに、しばらく時間がかかる)。
adminコンテナとrulerコンテナには何も保存されていなかった…。
お片付け
前回の記事でストレージとしてminioを利用したため、minioがつくっtPersistent Volumeがゴミとして残るので、削除する。Persistent Volume Claimを消せばOK。
kubectl delete pvc -n grafana \
$(kubectl get pvc -n grafana -o custom-columns=NAME:.metadata.name | grep loki-minio)
まとめ
Lokiの収集したデータをAzure Blob Storageに保存することができた。
workload identityの設定は情報が少なかったが、最終的にはPodに対するService Account設定+ラベル付けという基本的な設定のみで完了することがわかった。workload identityはシークレットを持つ必要がない、権限付与の範囲もPodに絞れる等、非常にセキュアな印象。Podから見るとKubernetesのService Accountを設定しているだけにみえるので、非常にスマート。