iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 17
0
Microsoft Azure

Azure 的奇幻之旅系列 第 17

Azure 系列文(17) - Key Vault 保護你的安全資訊 - (Kubernetes - 受控識別)

上一篇提到如何透過服務主體的方式授權給Kubernetes,然後取得秘密,那這一篇的部分會繼續把受控識別的段落做完,服務主體、受控識別主要是操控Azure Resource需要用到的服務,所以馬上就使用吧!

建立Azure Kubernetes Service使用受控識別

首先要建立一個有受控識別的AKS

az aks create -n my-k8s -g my-rg --kubernetes-version 1.16.9 --node-count 1 --enable-managed-identity

取得Azure Kubernetes Service 資料

再來跟上次一樣取得Kubernetes的資訊,但只需要記住subscriptionIdnodeResourceGroup

az aks show --name my-k8s --resource-group my-rg

透過helm安裝csi驅動程式

確定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

建立SecretProviderClass

使用Azure提供的範本[https://github.com/Azure/secrets-store-csi-driver-provider-azure/blob/master/test/bats/tests/azure_v1alpha1_secretproviderclass.yaml]

必填的參數:

  • usePodIdentity: 使用受控識別需要填成true
  • userAssignedIdentityID: 使用受控識別填""即可
  • keyvaultName: Key Vault的資源名稱
  • objects: 掛載的秘密
    • objectName: 秘密名稱
    • objectType: 秘密類型
  • resourceGroup: 資源群組名稱
  • subscriptionId: 訂用帳戶ID
  • tenantID: 租用戶識別碼

secretProvider.yaml

apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
  name: azure-kvname
spec:
  provider: azure
  parameters:
    usePodIdentity: "true"                   # [REQUIRED] Set to "true" if using managed identities
    useVMManagedIdentity: "false"             # [OPTIONAL] if not provided, will default to "false"
    userAssignedIdentityID: ""       # [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

指派Azure Kubernetes Service

接下來把AKS指派為受控識別操作員的角色,以下三個參數分別填入

  • cleintId: AKS的ClientId
  • SUBID: AKS的SubscriptionId
  • NODE_RESOURCE_GROUP: AKS的Resource Group
az role assignment create --role "Managed Identity Operator" --assignee $clientId --scope /subscriptions/$SUBID/resourcegroups/$NODE_RESOURCE_GROUP

az role assignment create --role "Virtual Machine Contributor" --assignee $clientId --scope /subscriptions/$SUBID/resourcegroups/$NODE_RESOURCE_GROUP

在AKS裡安裝Azure Active Diretory(AAD)身份識別

helm repo add aad-pod-identity https://raw.githubusercontent.com/Azure/aad-pod-identity/master/charts

helm install pod-identity aad-pod-identity/aad-pod-identity

建立身份識別,複製clientIdprincipalId

az identity create -g $resourceGroupName -n $identityName

賦予AKS權限

az role assignment create --role "Reader" --assignee $principalId --scope /subscriptions/$SUBID/resourceGroups/contosoResourceGroup/providers/Microsoft.KeyVault/vaults/contosoKeyVault5

az keyvault set-policy -n contosoKeyVault5 --secret-permissions get --spn $clientId

接下來將secretProvider.yaml部署上AKS

kubectl apply -f secretProviderClass.yaml

這邊如果是使用受控識別的話需要再加入podIdentityAndBinding.yaml
podIdentityAndBinding.yaml

apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentity
metadata:
    name: "azureIdentityName"               # The name of your Azure identity
spec:
    type: 0                                 # Set type: 0 for managed service identity
    resourceID: /subscriptions/<SUBID>/resourcegroups/<RESOURCEGROUP>/providers/Microsoft.ManagedIdentity/userAssignedIdentities/<AZUREIDENTITYNAME>
    clientID: "managedIdentityClientId"     # The clientId of the Azure AD identity that you created earlier
---
apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentityBinding
metadata:
    name: azure-pod-identity-binding
spec:
    azureIdentity: "azureIdentityName"      # The name of your Azure identity
    selector: azure-pod-identity-binding-selector

將podIdentityAndBinding.yaml部署上AKS

kubectl apply -f podIdentityAndBinding.yaml

再來部署podBindingDeployment.yaml
podBindingDeployment.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

部署podBindingDeployment.yaml上AKS

kubectl apply -f podBindingDeployment.yaml

提取秘密

接下來就可以從Pod提取秘密了,先檢查Pod狀態

kubectl get pods

kubectl describe pod/nginx-secrets-store-inline

確認部署成功之後,就可以提取秘密了!

kubectl exec -it nginx-secrets-store-inline -- ls /mnt/secrets-store/

昨天介紹了服務主體的方法,今天介紹了受控識別的方法,我使用起來覺得兩者的差距就在於服務主體需要自己建立服務主體指派至AKS,而受控識別則是AKS自動幫你建立一個服務主體,Key Vault幫你管理你的安全性資訊的方式,我覺得用起來還不賴,至少也不需要太麻煩的設定,只要透過AAD認證就可以使用了,下一篇會繼續介紹Pipeline的Key Vault如何使用!


上一篇
Azure 系列文(16) - Key Vault 保護你的安全資訊 - (Kubernetes - 服務主體)
下一篇
Azure 系列文(18) - Key Vault 保護你的安全資訊 - (Pipeline)
系列文
Azure 的奇幻之旅30

尚未有邦友留言

立即登入留言