Azure 系列文(15) - Key Vault 保護你的安全資訊 - (Kubernetes 篇)
昨天提到可以使用Key Vault去儲存一些安全性的資料,然後應用程式透過Azure的認證、指派的裝置...等等方式可以取得資料,但最近也越來越多人使用Kubernetes了,不知道在Kubernetes上取得Key Vault需要如何實現呢,讓我們繼續看下去
準備
建立服務主體,可以透過服務主體去管理秘密
az ad sp create-for-rbac --name myServicePrincipal --skip-assignment
然後可以看到畫面上回傳的值,把appId和password複製下來
[appid]
這邊假設你已經有安裝好Kubernetes,並且取得AKS的憑證了,接下來先確認Kubernetes版本是不是1.16.0以上的版本
kubectl version
如果不是的話,透過Azure CLI的指令升級
az aks upgrade --kubernetes-version 1.16.9 --name {AKS-name} --resource-group {resource-group-name}
然後取得Kubernetes的資訊,記住principalId、clientId、subscriptionId、nodeResourceGroup
az aks show --name {AKS-name} --resource-group {resource-group-name}
確定helm為v3以上的版本
helm version
安裝csi驅動程式
helm repo add csi-secrets-store-provider-azure https://raw.githubusercontent.com/Azure/secrets-store-csi-driver-provider-azure/master/charts
helm install csi-secrets-store-provider-azure/csi-secrets-store-provider-azure --generate-name
使用Azure提供的範本[https://github.com/Azure/secrets-store-csi-driver-provider-azure/blob/master/test/bats/tests/azure_v1alpha1_secretproviderclass.yaml]
必填的參數:
secretProvider.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
name: azure-kvname
spec:
provider: azure
parameters:
usePodIdentity: "false" # [REQUIRED] Set to "true" if using managed identities
useVMManagedIdentity: "false" # [OPTIONAL] if not provided, will default to "false"
userAssignedIdentityID: "servicePrincipalClientID" # [REQUIRED] If you're using a service principal, use the client id to specify which user-assigned managed identity to use. If you're using a user-assigned identity as the VM's managed identity, specify the identity's client id. If the value is empty, it defaults to use the system-assigned identity on the VM
# az ad sp show --id http://contosoServicePrincipal --query appId -o tsv
# the preceding command will return the client ID of your service principal
keyvaultName: "contosoKeyVault5" # [REQUIRED] the name of the key vault
# az keyvault show --name contosoKeyVault5
# the preceding command will display the key vault metadata, which includes the subscription ID, resource group name, key vault
cloudName: "" # [OPTIONAL for Azure] if not provided, Azure environment will default to AzurePublicCloud
objects: |
array:
- |
objectName: secret1 # [REQUIRED] object name
# az keyvault secret list --vault-name "contosoKeyVault5"
# the above command will display a list of secret names from your key vault
objectType: secret # [REQUIRED] object types: secret, key, or cert
objectVersion: "" # [OPTIONAL] object versions, default to latest if empty
- |
objectName: secret2
objectType: secret
objectVersion: ""
resourceGroup: "contosoResourceGroup" # [REQUIRED] the resource group name of the key vault
subscriptionId: "subscriptionID" # [REQUIRED] the subscription ID of the key vault
tenantId: "tenantID" # [REQUIRED] the tenant ID of the key vault
將服務主體指派給Key Vault,需要填以下資訊
az role assignment create --role Reader --assignee $AZURE_CLIENT_ID --scope /subscriptions/$SUBID/resourcegroups/$KEYVAULT_RESOURCE_GROUP/providers/Microsoft.KeyVault/vaults/$KEYVAULT_NAME
接下來將權限授權給服務主體,填入AZURE_CLIENT_ID
az keyvault set-policy -n $KEYVAULT_NAME --secret-permissions get --spn $AZURE_CLIENT_ID
認證服務主體,透過CSI驅動取得秘密,填入AZURE_CLIENT_ID、AZURE_CLIENT_SECRET,AZURE_CLIENT_SECRET是建立服務主體的時候的密碼
kubectl create secret generic secrets-store-creds --from-literal clientid=$AZURE_CLIENT_ID --from-literal clientsecret=$AZURE_CLIENT_SECRET
如果忘記服務主體的密碼,可以用下面指令重新設定
az ad sp credential reset --name myServicePrincipal --credential-description "APClientSecret" --query password -o tsv
把secretProvider.yaml部署到AKS
kubectl apply -f secretProvider.yaml
接下來把podIdentityAndBinding也加進來
podIdentityAndBinding.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-secrets-store-inline
labels:
aadpodidbinding: azure-pod-identity-binding-selector
spec:
containers:
- name: nginx
image: nginx
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
部署Pod
kubectl apply -f podBindingDeployment.yaml
顯示Pod,可以看到有nginx-secrets-store-inline
kubectl get pods
檢查Pod狀態是不是有成功
kubectl describe pod/nginx-secrets-store-inline
顯示所有的秘密
kubectl exec -it nginx-secrets-store-inline -- ls /mnt/secrets-store/
以上的步驟就可以完成把秘密放在AKS了,不過上面是使用服務主體的方式,官方也有提供使用受控識別的方式,那下一篇的部分也會跟大家一起做受控識別的部分,可以依照實際的需求去選擇要用哪一種認證方式!