Background
In this post, I will discuss how to utilize Azure Key Vault (AKV) with Azure Red Hat OpenShift (ARO) cluster. I will explain the relevant terms and their definitions from the architectural standpoint and how the flow works at a glance, and I will give an example of how to deploy this in the ARO cluster. The objective of this article is to enable you to store and retrieve secrets stored in AKV from your ARO cluster.
Basic Architecture
Container Storage Interface (CSI) is a standardized interface allowing third-party storage providers to integrate their storage systems with Kubernetes. Secrets Store CSI Driver, on the other hand, allows the integration of secrets stores with Kubernetes via a CSI volume. It enables Kubernetes to allow multiple secrets, keys, and certs stored in enterprise-grade external secrets stores as a volume into their pods. Some examples of these external secret stores are Azure Key Vault, HashiCorp Vault, AWS Secrets Manager, and Google Cloud Secret Manager. This driver is installed in the cluster as a daemonset.
Azure Key Vault (AKV) is an Azure-managed centralized repository allowing you to store secrets such as API keys, auth tokens, TLS/SSL certificates, passwords and so forth. It integrates with Azure Active Directory (AD) for authentication and authorization. In addition, AKV provider for Secret Store CSI driver allows for the integration of AKV as a secrets store with a Kubernetes cluster by mounting them into the pods as a CSI volume. This cloud-specific driver is also installed in the cluster as a daemonset along with the Secret Store CSI Driver.
Figure 1. High-level flow
Let's discuss how all of these work at a high level, as shown in the figure above. When a pod is created through the Kubernetes API, it is scheduled onto a node, and the kubelet looks at the pod specification and sees if there is a volume mount request. If there is, it will issue a gRPC call to the Secret Store CSI Driver.
The CSI driver then mounts the volume as tmpfs to the pod and issues another gRPC request to the AKV Provider for Secrets Store CSI Driver. The provider will then reach out to AKV to fetch the secret and send it back to the driver as gRPC response. Lastly, the driver will write the secret into the file system and the pod then starts running.
Deployment
Now let's talk about how to deploy this in conjunction with your existing ARO cluster. Note that this is an example of the deployment and your implementation may vary. This guide is a minor adaptation of the mobb.ninja article.
Prerequisites
The following were set up and installed for the example deployment in this article:
- ARO cluster v4.11
- az CLI v2.49.0
- oc CLI v4.13.0
- helm CLI v3.12.0
Should any of the commands in the following steps not work at your end, you might want to update the version(s) to at least match the one(s) listed above.
Step 1 - Set the Environment Variables
In this scenario I will be using an ARO cluster with the resource group called dsari-rg and location West US, so kindly modify this based on your resource group’s name and location.
export KEYVAULT_RESOURCE_GROUP=${AZR_RESOURCE_GROUP:-"dsari-rg"}
export KEYVAULT_LOCATION=${AZR_RESOURCE_LOCATION:-"westus"}
export KEYVAULT_NAME=secret-store-$(cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1)
export AZ_TENANT_ID=$(az account show -o tsv --query tenantId)
Step 2 - Install the Secrets Store CSI Driver
- Make sure you are logged into Azure using az login command.
- Log into your cluster using oc login command.
- Create a new namespace. In this example, I will call it secrets-store-csi-project.
oc new-project secrets-store-csi-project
- Add privileged security context constraints (SCC) policy to the Secret Store CSI Driver.
oc adm policy add-scc-to-user privileged \
system:serviceaccount:secrets-store-csi-project:secrets-store-csi-driver - Add the driver to your helm repo and update it.
helm repo add secrets-store-csi-driver \
https://kubernetes-sigs.github.io/secrets-store-csi-driver/charts
helm repo update - Install the driver.
helm install -n secrets-store-csi-project csi-secrets-store \
secrets-store-csi-driver/secrets-store-csi-driver \
--version v1.3.2 \
--set "linux.providersDir=/var/run/secrets-store-csi-providers" - Finally, check if the pods were created and running.
oc --namespace=secrets-store-csi-project get pods -l "app=secrets-store-csi-driver"
Step 3 - Install the Azure Key Vault Provider for Secrets Store CSI Driver
- Add Azure Key Vault Provider for Secrets Store CSI Driver to the helm repo and update it.
helm repo add csi-secrets-store-provider-azure \
https://azure.github.io/secrets-store-csi-driver-provider-azure/charts
helm repo update - Install the provider.
helm install -n secrets-store-csi-project azure-csi-provider \
csi-secrets-store-provider-azure/csi-secrets-store-provider-azure \
--set linux.privileged=true --set secrets-store-csi-driver.install=false \
--set "linux.providersDir=/var/run/secrets-store-csi-providers" \
--version=v1.4.1 - Add privileged SCC policy to the provider.
oc adm policy add-scc-to-user privileged \
system:serviceaccount:secrets-store-csi-project:csi-secrets-store-provider-azure
Step 4 - Create Azure Key Vault Secret
- Create a new namespace. In this example, I will call it my-app.
oc new-project my-app
- Create Azure Key Vault in the resource group where your ARO cluster resides.
az keyvault create -n ${KEYVAULT_NAME} \
-g ${KEYVAULT_RESOURCE_GROUP} \
--location ${KEYVAULT_LOCATION} - Create the secret. In this example, the secret is called mysecret and the value is MyPa55w0rd in the type of string.
az keyvault secret set \
--vault-name ${KEYVAULT_NAME} \
--name mysecret --value "MyPa55w0rd" - Create the service principal for the secret and set the policy for it.
export SERVICE_PRINCIPAL_CLIENT_SECRET="$(az ad sp create-for-rbac \
--name http://$KEYVAULT_NAME --query 'password' -otsv)"
export SERVICE_PRINCIPAL_CLIENT_ID="$(az ad sp list \
--display-name http://$KEYVAULT_NAME --query '[0].appId' -otsv)"
az keyvault set-policy -n ${KEYVAULT_NAME} \
--secret-permissions get \
--spn ${SERVICE_PRINCIPAL_CLIENT_ID} - Create the Kubernetes secret (and label it) so it uses the secret from Azure Key Vault.
oc create secret generic secrets-store-creds \
-n my-app \
--from-literal clientid=${SERVICE_PRINCIPAL_CLIENT_ID} \
--from-literal clientsecret=${SERVICE_PRINCIPAL_CLIENT_SECRET}
oc -n my-app label secret \
secrets-store-creds secrets-store.csi.k8s.io/used=true - Create a SecretProviderClass object to specify this secret.
cat <<EOF | oc apply -f -
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: azure-kvname
namespace: my-app
spec:
provider: azure
parameters:
usePodIdentity: "false"
useVMManagedIdentity: "false"
userAssignedIdentityID: ""
keyvaultName: "${KEYVAULT_NAME}"
objects: |
array:
- |
objectName: mysecret
objectType: secret
objectVersion: ""
tenantId: "${AZ_TENANT_ID}"
EOF - Create a pod that uses the secret you created. In this example, I will create a BusyBox application.
cat <<EOF | oc apply -f -
kind: Pod
apiVersion: v1
metadata:
name: busybox-secrets-store-inline
namespace: my-app
spec:
containers:
- name: busybox
image: k8s.gcr.io/e2e-test-images/busybox:1.29
command:
- "/bin/sleep"
- "10000"
volumeMounts:
- name: secrets-store-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: "azure-kvname"
nodePublishSecretRef:
name: secrets-store-creds
EOF - Finally, check and print the secret to see if it is successfully mounted.
oc exec busybox-secrets-store-inline \
-- ls /mnt/secrets-store/
oc exec busybox-secrets-store-inline \
-- cat /mnt/secrets-store/mysecret
This last step should reveal the name of the secret (mysecret) and its value (MyPa55w0rd).
If these were displayed, congratulations! You have successfully created a secret in Azure Key Vault and used it for an application.
Step 5 - Cleanup
- Uninstall and delete the helm chart.
helm uninstall -n secrets-store-csi-project azure-csi-provider
helm delete -n secrets-store-csi-project csi-secrets-store - Delete the SCC policy and the app.
oc adm policy remove-scc-from-user privileged \
system:serviceaccount:secrets-store-csi-project:secrets-store-csi-driver
oc delete project my-app - Delete the secret.
az keyvault delete -n ${KEYVAULT_NAME} - Finally, delete the service principal.
az ad sp delete --id ${SERVICE_PRINCIPAL_CLIENT_ID}
Sources
- Secret Store CSI Driver - Concepts:https://secrets-store-csi-driver.sigs.k8s.io/concepts.html
- Azure Key Vault CSI on Azure Red Hat OpenShift: https://mobb.ninja/docs/misc/secrets-store-csi/azure-key-vault/
저자 소개
유사한 검색 결과
From incident responder to security steward: My journey to understanding Red Hat's open approach to vulnerability management
Key considerations for 2026 planning: Insights from IDC
What Is Product Security? | Compiler
Technically Speaking | Security for the AI supply chain
채널별 검색
오토메이션
기술, 팀, 인프라를 위한 IT 자동화 최신 동향
인공지능
고객이 어디서나 AI 워크로드를 실행할 수 있도록 지원하는 플랫폼 업데이트
오픈 하이브리드 클라우드
하이브리드 클라우드로 더욱 유연한 미래를 구축하는 방법을 알아보세요
보안
환경과 기술 전반에 걸쳐 리스크를 감소하는 방법에 대한 최신 정보
엣지 컴퓨팅
엣지에서의 운영을 단순화하는 플랫폼 업데이트
인프라
세계적으로 인정받은 기업용 Linux 플랫폼에 대한 최신 정보
애플리케이션
복잡한 애플리케이션에 대한 솔루션 더 보기
가상화
온프레미스와 클라우드 환경에서 워크로드를 유연하게 운영하기 위한 엔터프라이즈 가상화의 미래