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.
重要
AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
Istio 服务网格加载项支持 Istio 自己的入口流量管理 API 和用于入口流量管理的 Kubernetes 网关 API。 可以使用 Istio 网关 API 自动部署模型 或 手动部署模型。 本文介绍如何使用 Kubernetes 网关 API 和 自动化部署模型为 Istio 服务网格加载项配置入口流量管理。
限制和注意事项
- 仅在手动部署模型中支持将 Kubernetes 网关 API 用于出口流量管理与 Istio 服务网格加载项。
- 资源的 ConfigMap 自定义
Gateway必须位于资源自定义允许列表中。 未在允许列表中的字段将被禁止,并通过加载项管理的 Webhook 阻止。 有关详细信息,请参阅 Istio 服务网格附加支持策略。
先决条件
- 在 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应用程序。kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.26/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: http namespace: default spec: parentRefs: - name: httpbin-gateway hostnames: ["httpbin.example.com"] rules: - matches: - path: type: PathPrefix value: /get backendRefs: - name: httpbin port: 8000 EOF注释
如果要执行小版本升级,并且在群集上同时安装了两个 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)终止 或 服务器名称指示(SNI)传递来保护基于网关 API 的入口流量。 在以下部分中,使用 适用于机密存储容器存储接口(CSI)驱动程序插件的 Azure Key Vault 提供程序,将机密从 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 并创建机密
创建一个 Azure Key Vault 实例,以使用
az keyvault create命令向 Istio 服务网格加载项提供证书和密钥输入。 如果已有 Azure Key Vault 实例,可以跳过此步骤。az keyvault create --name $KEY_VAULT_NAME --resource-group $RESOURCE_GROUP --location $LOCATION使用命令在群集上
az aks enable-addons。az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME如果密钥保管库使用 Azure 基于角色的访问控制(RBAC)作为权限模型,请按照 提供对 Azure Key Vault 密钥、证书和机密的访问权限中的说明,通过 Azure 基于角色的访问控制 为加载项的用户分配 Key Vault 机密用户的 Azure 角色。 或者,如果密钥保管库使用保管库访问策略权限模型,请使用命令授权加载项的用户分配的托管标识,以使用访问策略
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-keytest-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-pxf是 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 Key Vault 提供程序(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.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 命名空间中的 aks-istio-system ConfigMap 中设定的。 此ConfigMap必须将标签设置为gateway.istio.io/defaults-for-classistio,以便自定义项对所有Gatewaysspec.gatewayClassName: istio的项生效。 启用GatewayClass后,aks-istio-system 命名空间中默认会安装 级别的 ConfigMap。 安装托管网关 API CRD 后,ConfigMap 的部署可能最多需要五分钟 istio-gateway-class-defaults。
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