Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
注释
本文介绍如何在 资源上Gateway配置 TLS 终止,方法是自行编写 SecretProviderClass,通过示例 Pod 挂载适用于 Secrets Store CSI Driver 的 Azure 密钥保管库 提供程序,并在 Gateway 侦听器的 certificateRefs 中直接引用生成的 Kubernetes Secret。 如果需要完全控制证书同步工作流,或者希望自己管理这些资源,此方法非常有用。
对于大多数用户,推荐的方式是由 Application Routing Operator 提供支持的 Azure DNS 与 Azure 密钥保管库 的自动化集成,它会根据一对监听器SecretProviderClass,为你预配并调和certificateRefs、同步的 Kubernetes Secret 以及监听器tls.options。 若要使用自动化工作流,请参阅 使用应用程序路由的 Gateway API 实现配置 Azure DNS 和 TLS。
应用路由插件支持从 Azure 密钥保管库 (AKV) 同步密钥,以通过 TLS 终止来保护网关 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 密钥保管库并将机密同步到群集
创建Azure 密钥保管库
需要一个 Azure 密钥保管库 资源才能向应用程序路由加载项提供证书和密钥输入。
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION为群集启用 Secret Store CSI 驱动程序加载项的 Azure 密钥保管库 提供程序。
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER如果 密钥保管库 对权限模型使用 Azure RBAC,请按照 此处 的说明,为加载项的用户分配 密钥保管库 密钥用户的 Azure 角色。 或者,如果密钥保管库正在使用保管库访问策略权限模型,请使用访问策略授权为加载项的用户分配托管标识访问 Azure 密钥保管库 资源。
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 密钥保管库支持不同的对象类型。 对于本演练,请选择以下端到端选项 之一 ,然后继续执行常见验证和网关步骤。
选项 使用此选项时 密钥保管库存储 Kubernetes 机密结果 选项 1:将证书和密钥存储为密钥保管库机密 你有单独的 PEM 证书 ( .crt) 和私钥 (.key) 文件,如本文前面生成的文件。两个 密钥保管库 机密。 一个已同步的 Kubernetes TLS 机密命名 httpbin-credential。选项 2:直接引用密钥保管库证书对象 证书已作为证书对象(如导入 .pfx)存储在密钥保管库中。一个密钥保管库证书对象。 一个已同步的 Kubernetes TLS 机密命名 httpbin-credential。Important
不要遵循这两个选项。 如果使用选项 1,请将证书和密钥文件作为密钥保管库机密上传,然后应用选项 1
SecretProviderClass清单。 如果您使用选项 2,请跳过 密钥保管库 机密上传步骤,并应用选项 2 的SecretProviderClass清单。
选项 1:将证书和密钥存储为密钥保管库机密
如果具有单独的 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.crt注释
每次轮换(更改)证书或密钥时,请重新运行此步骤以将新版本作为机密上传。 若要自动将更新后的值同步到群集,请在用于 Secrets Store CSI Driver 的 Azure 密钥保管库 提供程序上启用自动轮换。 有关详细信息,请参阅 自动轮换和机密同步概述。 如果希望密钥保管库管理证书生命周期,请改用选项 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
选项 2:直接引用密钥保管库证书对象
当证书已作为证书对象存储在 Azure 密钥保管库 中时,请使用此选项。 无需将 .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 以将机密同步到群集。 机密存储 CSI 驱动程序需要 Pod 来引用SecretProviderClass资源,以便机密从Azure 密钥保管库同步到群集。
使用以下清单部署示例 Pod:
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: secrets-store-sync-httpbin spec: containers: - name: busybox image: mcr.azk8s.cn/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机密是否在defaultSecretProviderClass 资源中定义的命名空间中创建。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 网关,在 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 "我是一个茶壶" 代码。