重要
AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
Istio 服务网格加载项支持 Istio 自己的入口流量管理 API 和用于入口流量管理的 Kubernetes 网关 API。 可以使用 Istio 网关 API 自动部署模型 或 手动部署模型。 本文介绍如何使用 Kubernetes 网关 API 和 自动化部署模型为 Istio 服务网格加载项配置入口流量管理。
限制和注意事项
- Istio 服务网格加载项和 应用程序路由网关 API 实现 不能同时启用。 必须先禁用一个,并在单独的操作中启用另一个。
- 仅支持在手动部署模型中使用 Kubernetes 网关 API 进行出口流量管理与 Istio 加载项。
- 资源的 ConfigMap 自定义
Gateway必须符合 资源自定义允许列表。 未在允许列表中的字段将被禁止,并通过加载项管理的 Webhook 阻止。 有关 、allowed和blocked功能的详细信息,请参阅supported。 - 目前不支持通过
TLSRoute资源配置 HTTPS 服务的 HTTPS 入口访问,即服务器名称指示 (SNI) 透传。
先决条件
- 在 AKS 群集上启用 托管网关 API 。
- 安装 Istio 服务网格插件修订版
asm-1-26或更高版本。 如果尚未安装 Istio 服务网格加载项,请遵循 安装指南 ;如果使用的是较低次要修订,请遵循 升级指南 。
设置环境变量。
设置以下环境变量,以便在整个文章中使用:
| Variable | Description |
|---|---|
RESOURCE_GROUP |
包含 AKS 群集的资源组的名称。 |
CLUSTER_NAME |
AKS 群集的名称。 |
LOCATION |
部署 AKS 群集的Azure区域。 |
KEY_VAULT_NAME |
要为存储 TLS 机密而创建的Azure Key Vault资源的名称。 如果有现有资源,请使用该名称。 |
部署示例应用程序
首先,使用
httpbin命令在default命名空间中部署示例kubectl apply应用程序。export ISTIO_RELEASE="release-1.27" kubectl apply -f https://raw.githubusercontent.com/istio/istio/$ISTIO_RELEASE/samples/httpbin/httpbin.yaml
创建 Kubernetes 网关和 HTTPRoute
示例清单创建可从群集外部访问的外部入口负载均衡器服务。 可以添加 批注 以创建内部负载均衡器并自定义其他负载均衡器设置。
在
default命名空间中部署一个网关 API 配置,将gatewayClassName设置为istio,并使用HTTPRoute将流量路由到httpbin服务,使用以下清单:kubectl apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway spec: gatewayClassName: istio listeners: - name: http port: 80 protocol: HTTP allowedRoutes: namespaces: from: Same --- 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: /get backendRefs: - name: httpbin port: 8000 EOF注释
默认情况下,Istio 控制平面会将
GatewayClass的名称追加到它为istio预配的资源名称中。 可以使用Gateway批注你的资源gateway.istio.io/name-override,以覆盖预配资源的名称。 资源名称必须小于63字符,并且必须是有效的 DNS 名称。注释
如果要执行小版本升级,并且在群集上同时安装了两个 Istio 服务网格加载项修订,则小版本中较高版本的控制平面会默认接管
Gateways的管理权限。 可以将istio.io/rev标签添加到Gateway,以控制哪个控制平面修订版本拥有它。 如果添加修订版标签,请确保在回滚或完成升级作业之前,将其相应更新为适当的控制平面修订版。
验证资源创建
验证
Deployment、Service、HorizontalPodAutoscaler和PodDisruptionBudget资源是否已使用以下kubectl get命令创建:kubectl get deployment httpbin-gateway-istio kubectl get service httpbin-gateway-istio kubectl get hpa httpbin-gateway-istio kubectl get pdb httpbin-gateway-istio示例输出:
# Deployment resource NAME READY UP-TO-DATE AVAILABLE AGE httpbin-gateway-istio 2/2 2 2 31m # Service resource NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpbin-gateway-istio LoadBalancer 10.0.65.45 <external-ip> 15021:32053/TCP,80:31587/TCP 33m # HPA resource NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE httpbin-gateway-istio Deployment/httpbin-gateway-istio cpu: 3%/80% 2 5 3 34m # PDB resource NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE httpbin-gateway-istio 1 N/A 2 36m
将请求发送到示例应用程序
尝试向
curlhttpbin应用程序发送请求。 首先,设置INGRESS_HOST环境变量:kubectl wait --for=condition=programmed gateways.gateway.networking.k8s.io httpbin-gateway export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -ojsonpath='{.status.addresses[0].value}')尝试向
httpbin发送 HTTP 请求。curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"在输出中,应会看到响应
HTTP 200。
使用 Kubernetes 网关 API 保护 Istio 入口流量
Istio 服务网格加载项支持从 Azure Key Vault 同步密钥,以传输层安全(TLS)终止保护基于网关 API 的入口流量。 在以下部分中,您将使用 Azure 密钥保管库提供程序的机密存储容器存储接口 (CSI) 驱动程序加载项,将机密从 Azure Key Vault 同步到 AKS 群集,并在入口网关处终止 TLS。
创建客户端/服务器证书和密钥
创建根证书和私钥用于为示例服务的证书签名:
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
设置Azure Key Vault并创建机密
使用
az keyvault create命令创建Azure Key Vault实例,向 Istio 服务网格加载项提供证书和密钥输入。 如果已有Azure Key Vault实例,则可以跳过此步骤。az keyvault create --name $KEY_VAULT_NAME --resource-group $RESOURCE_GROUP --location $LOCATION使用 命令在群集上为机密存储(CSI)驱动程序加载项启用
az aks enable-addons。az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME如果您的 Key Vault 使用 Azure 基于角色的访问控制(RBAC)作为权限模型,请按照 提供 Azure Key Vault 密钥、证书和机密的 Azure 基于角色的访问控制 中的说明,为加载项的用户分配的托管标识分配 Azure 角色 Key Vault Secrets User。 或者,如果密钥保管库使用保管库访问策略权限模型,请使用
az keyvault set-policy命令授权加载项的用户分配的托管标识访问Azure Key Vault资源。OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r') CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId') TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $KEY_VAULT_NAME --query 'properties.tenantId') az keyvault set-policy --name $KEY_VAULT_NAME --object-id $OBJECT_ID --secret-permissions get list使用以下
az keyvault secret set命令,使用证书和密钥在 Azure Key Vault 中创建机密:az keyvault secret set --vault-name $KEY_VAULT_NAME --name test-httpbin-key --file httpbin_certs/httpbin.example.com.key az keyvault secret set --vault-name $KEY_VAULT_NAME --name test-httpbin-crt --file httpbin_certs/httpbin.example.com.crt
部署 SecretProviderClass 和示例 Pod
部署 SecretProviderClass,以便使用以下清单向 CSI 驱动程序提供Azure Key Vault特定参数。 在此示例中,
test-httpbin-key和test-httpbin-crt是Azure Key Vault中机密对象的名称。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: $KEY_VAULT_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引用证书对象类型,请使用以下清单部署 SecretProviderClass。 在此示例中,
test-httpbin-cert-pfx是Azure Key Vault中的证书对象的名称。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: $KEY_VAULT_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使用以下清单部署示例 Pod。 Azure 密钥保管库提供程序是 Secrets Store CSI 驱动程序的加载项,要求 Pod 引用 SecretProviderClass 资源,以确保机密能够从 Azure 密钥保管库同步到群集。
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
验证 TLS 密钥创建
验证
httpbin-credential是否在default命名空间中按照 SecretProviderClass 资源的定义创建了一个kubectl describe secret机密,使用kubectl describe secret命令进行。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 网关
使用以下清单创建一个在 TLS 配置下引用
httpbin-credential密钥的 Kubernetes 网关:cat <<EOF | kubectl apply -f - apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: httpbin-gateway spec: gatewayClassName: 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注释
在网关定义中,
tls.certificateRefs.name必须与 SecretProviderClass 资源匹配secretName。创建一个相应的
HTTPRoute,使用以下清单通过 HTTPS 路由入口流量到httpbin服务: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使用以下命令获取入口网关的外部 IP 地址和安全端口:
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 我是茶壶 代码。注释
若要配置对 HTTPS 服务的 HTTPS 入口访问,请将网关定义中的 TLS 模式更新为
Passthrough。 此配置指示网关 按原样传递入口流量,而不会终止 TLS。
自定义批注设置
可以在spec.infrastructure.annotations下添加注释以配置负载均衡器设置,用于Gateway。 例如,若要创建附加到特定子网 的内部负载均衡器 ,可以使用以下注释创建一个 Gateway :
spec:
# ... existing spec content ...
infrastructure:
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
service.beta.kubernetes.io/azure-load-balancer-internal-subnet: "my-subnet"
ConfigMap 自定义设置
Istio 服务网格附加组件支持对为 生成的 Gateways 进行自定义,其中包括:
- 服务
- 部署
- 水平 Pod 自动缩放器 (HPA)
- Pod 故障预算 (PDB)
这些资源的默认设置是在istio-gateway-class-defaults命名空间中的 ConfigMap 中进行配置的,当启用了托管网关 API CRD 和 Istio 插件时,AKS 会预配置这些资源。 此ConfigMap必须将标签设置为gateway.istio.io/defaults-for-classistio,以便自定义项对所有Gatewaysspec.gatewayClassName: istio的项生效。 启用GatewayClass后,aks-istio-system 命名空间中默认会安装 级别的 ConfigMap。 安装托管网关 API CRD 后,ConfigMap 的部署可能最多需要五分钟 istio-gateway-class-defaults。
注释
当托管网关API CRD和Istio加载项一起启用时,AKS会预配并协调istio-gateway-class-defaults ConfigMap。 如果您以前在istio-gateway-class-defaults命名空间中自行创建了aks-istio-system ConfigMap,则必须在启用托管网关 API CRD 之前删除该自管理的 ConfigMap 实例,以避免与 AKS 托管的 ConfigMap 在对帐时产生冲突。
kubectl get configmap istio-gateway-class-defaults -n aks-istio-system -o yaml
...
data:
horizontalPodAutoscaler: |
spec:
minReplicas: 2
maxReplicas: 5
podDisruptionBudget: |
spec:
minAvailable: 1
...
可以通过更新 Gateways ConfigMap 来修改所有 Istio GatewayClassistio-gateway-class-defaults 的这些设置,也可以为单个Gateway资源设置这些设置。 必须在给定资源中为 GatewayClass 级别和 Gateway 级别的 ConfigMaps 添加字段至允许列表。 如果同时对 GatewayClass 和单个 Gateway 进行了自定义,那么 Gateway 级别的配置将优先。
允许列表字段的部署自定义
| 字段路径 | Description |
|---|---|
metadata.labels |
部署标签 |
metadata.annotations |
部署注释 |
spec.replicas |
部署副本计数 |
spec.template.metadata.labels |
Pod 标签 |
spec.template.metadata.annotations |
Pod 批注 |
spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms |
节点相关性 |
spec.template.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution |
节点相关性 |
spec.template.spec.affinity.podAffinity.requiredDuringSchedulingIgnoredDuringExecution |
Pod 相关性 |
spec.template.spec.affinity.podAffinity.preferredDuringSchedulingIgnoredDuringExecution |
Pod 相关性 |
spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution |
Pod 反相关性 |
spec.template.spec.affinity.podAntiAffinity.preferredDuringSchedulingIgnoredDuringExecution |
Pod 反相关性 |
spec.template.spec.containers.resizePolicy |
容器资源利用率 |
spec.template.spec.containers.resources.limits |
容器资源利用率 |
spec.template.spec.containers.resources.requests |
容器资源利用率 |
spec.template.spec.containers.stdin |
容器调试 |
spec.template.spec.containers.stdinOnce |
容器调试 |
spec.template.spec.nodeSelector |
Pod 调度 |
spec.template.spec.nodeName |
Pod 调度 |
spec.template.spec.tolerations |
Pod 调度 |
spec.template.spec.topologySpreadConstraints |
Pod 调度 |
服务自定义允许列表字段
| 字段路径 | Description |
|---|---|
metadata.labels |
服务标签 |
metadata.annotations |
服务注释 |
spec.type |
服务类型 |
spec.loadBalancerSourceRanges |
服务负载均衡器设置 |
spec.loadBalancerClass |
服务负载均衡器设置 |
spec.externalTrafficPolicy |
服务流量策略 |
spec.internalTrafficPolicy |
服务流量策略 |
HorizontalPodAutoscaler(HPA)自定义允许列表字段
| 字段路径 | Description |
|---|---|
metadata.labels |
HPA 标签 |
metadata.annotations |
HPA 批注 |
spec.behavior.scaleUp.stabilizationWindowSeconds |
HPA 纵向扩展行为 |
spec.behavior.scaleUp.selectPolicy |
HPA 纵向扩展行为 |
spec.behavior.scaleUp.policies |
HPA 纵向扩展行为 |
spec.behavior.scaleDown.stabilizationWindowSeconds |
HPA 缩减行为 |
spec.behavior.scaleDown.selectPolicy |
HPA 缩减行为 |
spec.behavior.scaleDown.policies |
HPA 缩减行为 |
spec.metrics |
HPA 缩放资源指标 |
spec.minReplicas |
HPA 最小副本计数。 不得低于 2。 |
spec.maxReplicas |
HPA 最大副本计数 |
PodDisruptionBudget (PDB) 自定义允许列表字段
| 字段路径 | Description |
|---|---|
metadata.labels |
PDB 标签 |
metadata.annotations |
PDB 注释 |
spec.minAvailable |
PDB 最低可用性 |
spec.unhealthyPodEvictionPolicy |
PDB 逐出策略 |
注释
PDB修改最小可用性和逐出策略可能会导致集群/节点升级和删除操作期间出现潜在错误。 按照 PDB 故障排除指南 解决因 而导致的 PDB 错误。
配置 GatewayClass 级设置
使用
GatewayClass命令在aks-istio-system命名空间中更新kubectl edit configmap级别的ConfigMap。kubectl edit cm istio-gateway-class-defaults -n aks-istio-system根据需要编辑
data部分中的资源设置。 例如,若要更新 HPA 最小/最大副本数并向Deployment添加标签,请按如下方式修改 ConfigMap:... data: deployment: | metadata: labels: test.azureservicemesh.io/deployment-config: "updated" horizontalPodAutoscaler: | spec: minReplicas: 3 maxReplicas: 6 podDisruptionBudget: | spec: minAvailable: 1 ...注释
每个
GatewayClass只允许一个ConfigMap。现在,你应该会看到你之前创建的
HPA中的httpbin-gateway,已经更新为新的最小值/最大值。HPA使用kubectl get hpa命令验证设置。kubectl get hpa httpbin-gateway-istio示例输出:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE httpbin-gateway-istio Deployment/httpbin-gateway-istio cpu: 3%/80% 3 6 3 36m使用
Deployment命令验证kubectl get deployment是否已更新为新标签。kubectl get deployment httpbin-gateway-istio -ojsonpath='{.metadata.labels.test\.azureservicemesh\.io\/deployment-config}'示例输出:
updated
配置特定网关的参数
使用以下清单为网关创建具有资源自定义的
httpbinConfigMap:kubectl apply -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: gw-options data: horizontalPodAutoscaler: | spec: minReplicas: 2 maxReplicas: 4 deployment: | metadata: labels: test.azureservicemesh.io/deployment-config: "updated-per-gateway" EOF请更新
httpbinGateway以引用ConfigMap。spec: # ... existing spec content ... infrastructure: parametersRef: group: "" kind: ConfigMap name: gw-options使用
kubectl apply命令应用更新。kubectl apply -f httpbin-gateway-updated.yaml请使用
HPA命令验证kubectl get hpa是否已更新为新的最小值/最大值。 如果你还配置了GatewayClass级别的ConfigMap,Gateway级别的设置应优先。kubectl get hpa httpbin-gateway-istio示例输出:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE httpbin-gateway-istio Deployment/httpbin-gateway-istio cpu: 3%/80% 2 4 2 4h14m检查
Deployment标签,确保test.azureservicemesh.io/deployment-config已使用kubectl get deployment命令更新为新值。kubectl get deployment httpbin-gateway-istio -ojsonpath='{.metadata.labels.test\.azureservicemesh\.io\/deployment-config}'示例输出:
updated-per-gateway
清理资源
如果不再需要本文中创建的资源,可以将其删除,以避免产生任何费用。
使用以下命令
kubectl delete删除网关和 HTTPRoute 资源:kubectl delete gateways.gateway.networking.k8s.io httpbin-gateway kubectl delete httproute httpbin如果创建了用于自定义网关资源的 ConfigMap,请使用
kubectl delete configmap命令将其删除。kubectl delete configmap gw-options如果创建了用于 TLS 终止的 SecretProviderClass 和机密,
kubectl delete请使用以下命令删除资源:kubectl delete secret httpbin-credential kubectl delete pod secrets-store-sync-httpbin kubectl delete secretproviderclass httpbin-credential-spc