Note
本文說明如何在 資源上Gateway設定 TLS 終止,方法是自行撰寫 SecretProviderClass、透過範例 Pod 掛載 Secrets Store CSI Driver 的 Azure Key Vault 提供者,並直接在 Gateway 接聽程式的 certificateRefs 中參考所產生的 Kubernetes Secret。 如果你需要完全掌控憑證同步工作流程,或偏好自行管理這些資源,這種方法很有用。
對於大多數使用者,建議路徑是由應用程式路由操作員提供支援的自動化 Azure DNS 和 Azure Key Vault 整合SecretProviderClass,該操作員會根據一組接聽程式 certificateRefs,為您佈建並協調 SecretProviderClass、已同步的 Kubernetes 秘密,以及接聽程式 tls.options。 要使用自動化工作流程,請參考「配置 Azure DNS 與 TLS 並搭配應用程式路由閘道 API 實作」。
應用程式路由增益集支援從 Azure Key Vault (AKV) 同步祕密,以透過 TLS 終止來保護 Gateway API 輸入流量。 請依照以下步驟建立憑證與金鑰,以在閘道器終止 TLS 流量。
先決條件
- 啟用 應用程式路由閘道 API 實作
- 啟用 託管閘道 API 安裝
- 設定環境變數:
export CLUSTER=<cluster-name> export RESOURCE_GROUP=<resource-group-name> export LOCATION=<location>
所需用戶端/伺服器憑證和金鑰
- 建立根憑證和私人金鑰,以簽署樣本服務的憑證:
mkdir httpbin_certs
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout httpbin_certs/example.com.key -out httpbin_certs/example.com.crt
- 產生
httpbin.example.com的憑證與私鑰。
openssl req -out httpbin_certs/httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout httpbin_certs/httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization"
openssl x509 -req -sha256 -days 365 -CA httpbin_certs/example.com.crt -CAkey httpbin_certs/example.com.key -set_serial 0 -in httpbin_certs/httpbin.example.com.csr -out httpbin_certs/httpbin.example.com.crt
設定 TLS 入口閘道
設定 Azure Key Vault 並將密碼同步至叢集
建立 Azure Key Vault
你需要一個 Azure Key Vault 資源 來提供應用程式路由外掛的憑證和金鑰輸入。
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION在叢集上啟用密碼存放 CSI 驅動程式的 Azure Key Vault 提供者附加元件。
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER如果你的 金鑰保存庫 使用 Azure RBAC 作為權限模型,請依 照此處的指示,將 Azure 角色 "金鑰保存庫 Secrets User" 分配給該附加元件的使用者指派管理身份。 或者,如果您的金鑰庫正在使用金庫存取原則權限模型,請授權該附加元件的使用者指派受控識別,以使用存取原則存取 Azure Key Vault 資源:
OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r') CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId') TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $AKV_NAME --query 'properties.tenantId') az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get list選擇如何提供 TLS 證書。
Azure Key Vault 支援不同的物件類型。 在本次逐步解說中,請從以下端對端選項中選擇 一個,然後繼續執行通用的驗證和 Gateway 步驟。
Option 當…時使用此選項 金鑰保存庫 商店 Kubernetes Secret 結果 選項一:將憑證和金鑰儲存為 金鑰保存庫 秘密 你有分開的 PEM 憑證( .crt)和私鑰(.key)檔案,就像本文前面產生的那些。兩個 金鑰保存庫 的秘密。 有一個同步的 Kubernetes TLS 秘密,名為 httpbin-credential。選項二:直接參考 金鑰保存庫 憑證物件 你的憑證已經以憑證物件形式儲存在 金鑰保存庫 中,例如匯入的 .pfx。一個 金鑰保存庫 憑證物件。 有一個同步的 Kubernetes TLS 秘密,名為 httpbin-credential。Important
不要同時採用兩種選項。 如果您使用選項 1,請將憑證和金鑰檔案上傳至 金鑰保存庫 並儲存為祕密,然後套用選項 1 的
SecretProviderClass資訊清單。 如果你使用選項 2,跳過 金鑰保存庫 秘密上傳步驟,直接套用選項 2SecretProviderClass的清單。
選項一:將憑證和金鑰儲存為 金鑰保存庫 秘密
當您有獨立的 PEM 憑證(.crt)和私鑰(.key)檔案時,請使用此選項,例如本文前述產生的檔案。
將憑證與金鑰檔案上傳為 金鑰保存庫 秘密:
az keyvault secret set --vault-name $AKV_NAME --name test-httpbin-key --file httpbin_certs/httpbin.example.com.key az keyvault secret set --vault-name $AKV_NAME --name test-httpbin-crt --file httpbin_certs/httpbin.example.com.crtNote
每次你輪換(更改)憑證或金鑰時,都重新執行這個步驟,將新版本上傳為秘密。 要將更新後的值自動同步到叢集,請在 Secrets Store CSI 驅動程式的 Azure Key Vault 提供者上啟用自動旋轉功能。 更多資訊請參閱 自動旋轉與秘密同步總覽。 如果你偏好讓 金鑰保存庫 管理憑證生命週期,建議改用選項 2。
建立參考你在 金鑰保存庫 中建立的兩個祕密的
SecretProviderClass:cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: httpbin-credential-spc spec: provider: azure secretObjects: - secretName: httpbin-credential type: kubernetes.io/tls data: - objectName: test-httpbin-key key: tls.key - objectName: test-httpbin-crt key: tls.crt parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $AKV_NAME cloudName: "" objects: | array: - | objectName: test-httpbin-key objectType: secret objectAlias: "test-httpbin-key" - | objectName: test-httpbin-crt objectType: secret objectAlias: "test-httpbin-crt" tenantId: $TENANT_ID EOF
選項二:直接參考 金鑰保存庫 憑證物件
當憑證已經以憑證物件儲存在 Azure Key Vault 時,請使用此選項。 你不需要將 .crt 和 .key 檔案作為個別的 金鑰保存庫 祕密上傳。
在此範例中, test-httpbin-cert-pfx 是 Azure 金鑰保存庫中憑證物件的名稱。 若要將現有憑證匯入 金鑰保存庫 作為憑證物件,請參見「將憑證匯入 金鑰保存庫」。 欲了解更多物件參數資訊,請參閱 取得憑證與金鑰。
建立參考 金鑰保存庫 憑證物件的
SecretProviderClass:cat <<EOF | kubectl apply -f - apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: httpbin-credential-spc spec: provider: azure secretObjects: - secretName: httpbin-credential type: kubernetes.io/tls data: - objectName: test-httpbin-key key: tls.key - objectName: test-httpbin-crt key: tls.crt parameters: useVMManagedIdentity: "true" userAssignedIdentityID: $CLIENT_ID keyvaultName: $AKV_NAME cloudName: "" objects: | array: - | objectName: test-httpbin-cert-pfx #certificate object name from keyvault objectType: secret objectAlias: "test-httpbin-key" - | objectName: test-httpbin-cert-pfx #certificate object name from keyvault objectType: cert objectAlias: "test-httpbin-crt" tenantId: $TENANT_ID EOF
將秘密同步到叢集
完成「選項 1」或「選項 2」後,部署一個範例 Pod,以將 Secret 同步至叢集。 Secrets Store CSI 驅動程式需要 Pod 參考 SecretProviderClass 資源,才能將 Azure Key Vault 中的祕密同步至叢集中。
請使用以下清單部署範例艙:
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-httpbin spec: containers: - name: busybox image: mcr.microsoft.com/oss/busybox/busybox:1.33.1 command: - "/bin/sleep" - "10" volumeMounts: - name: secrets-store01-inline mountPath: "/mnt/secrets-store" readOnly: true volumes: - name: secrets-store01-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "httpbin-credential-spc" EOF驗證在
httpbin-credential命名空間中建立的default密碼是否如 SecretProviderClass 資源中所定義。kubectl describe secret/httpbin-credential輸出範例:
Name: httpbin-credential Namespace: default Labels: secrets-store.csi.k8s.io/managed=true Annotations: <none> Type: kubernetes.io/tls Data ==== tls.crt: 1180 bytes tls.key: 1675 bytes
部署 TLS 閘道器
建立一個 Kubernetes Gateway,在 TLS 設定下引用該
httpbin-credential機密:cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway spec: gatewayClassName: approuting-istio listeners: - name: https hostname: "httpbin.example.com" port: 443 protocol: HTTPS tls: mode: Terminate certificateRefs: - name: httpbin-credential allowedRoutes: namespaces: from: Selector selector: matchLabels: kubernetes.io/metadata.name: default EOF接著,建立對應
HTTPRoute的介面來配置閘道的入口流量路由:cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: httpbin spec: parentRefs: - name: httpbin-gateway hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /status - path: type: PathPrefix value: /delay backendRefs: - name: httpbin port: 8000 EOF取得閘道位址和埠口:
kubectl wait --for=condition=programmed gateways.gateway.networking.k8s.io httpbin-gateway export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.status.addresses[0].value}') export SECURE_INGRESS_PORT=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.spec.listeners[?(@.name=="https")].port}')發送 HTTPS 請求以存取服務
httpbin:curl -v -HHost:httpbin.example.com --resolve "httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" \ --cacert httpbin_certs/example.com.crt "https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418"你應該會看到 httpbin 服務回傳 418 I’m a Teapot 狀態碼。