你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
重要
AKS 预览功能可在自助服务和自愿选择的基础上启用。 预览版按“现状”和“视供应情况”提供,它们不包括在服务级别协议和有限保证范围内。 AKS 预览功能是由客户支持尽最大努力部分覆盖。 因此,这些功能并不适合用于生产。 有关详细信息,请参阅以下支持文章:
除了 Istio 自己的入口流量管理 API,Istio 服务网格加载项还支持 Kubernetes 网关 API 进行入口流量管理。 若要使用 Istio 加载项从 Azure 接收对基于网关 API 的部署的支持,必须在群集上启用 托管网关 API 安装 。 可以使用 Istio 网关 API 自动部署模型 或 手动部署模型 进行入口流量管理。 ConfigMap 自定义必须属于 资源自定义允许列表。
局限性
- 对于手动部署模型,仅支持通过 Istio 加载项使用 Kubernetes 网关 API 进行出口流量管理。
- 针对
Gateway资源的ConfigMap自定义必须属于资源自定义允许列表。 允许列表中未包含的字段不被允许,且通过加载项管理的 webhook 进行阻止。 若要详细了解 、allowed和blocked功能,请参阅supported。
先决条件
- 启用 托管网关 API 安装。
- 安装 Istio 加载项版本号
asm-1-26或更高版本。 如果尚未安装 Istio 加载项,请遵循 安装指南 ;如果使用的是较低次要修订,请遵循 升级指南 。
使用 Kubernetes 网关配置入口
部署示例应用程序
首先,在httpbin命名空间中部署default示例应用。
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.26/samples/httpbin/httpbin.yaml
创建 Kubernetes 网关和 HTTPRoute
接下来,在 default 命名空间中部署网关 API 配置,并将其 gatewayClassName 设置为 istio.
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 和 httpbin-gateway。
kubectl get deployment httpbin-gateway-istio
NAME READY UP-TO-DATE AVAILABLE AGE
httpbin-gateway-istio 2/2 2 2 31m
kubectl get service httpbin-gateway-istio
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
kubectl get hpa httpbin-gateway-istio
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
httpbin-gateway-istio Deployment/httpbin-gateway-istio cpu: 3%/80% 2 5 3 34m
kubectl get pdb httpbin-gateway-istio
NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
httpbin-gateway-istio 1 N/A 2 36m
可以通过修改 默认值 ConfigMap 或通过将 ConfigMap 附加到特定的 GatewayClass 上来Gateway。
将请求发送到示例应用程序
最后,尝试向 curl 应用程序发送 httpbin 请求。 首先,设置 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}')
然后,尝试将 HTTP 请求发送到 httpbin:
curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
应会看到响应 HTTP 200 。
使用 Kubernetes 网关 API 保护 Istio 入口流量
Istio 加载项支持从 Azure Key Vault (AKV) 同步机密,以使用 传输层安全性(TLS)终止 或 服务器名称指示(SNI)传递来保护基于网关 API 的入口流量。 可以按照以下说明使用 AKV 机密存储容器存储接口(CSI)驱动程序加载项 将 AKV 中的机密同步到 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
配置 TLS 入口网关
设置 Azure 密钥保管库并将机密同步到群集
创建 Azure Key Vault
需要 [Azure Key Vault 资源][akv-quickstart] 才能向 Istio 加载项提供证书和密钥输入。
export AKV_NAME=<azure-key-vault-resource-name> az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION在群集上启用 [适用于机密存储 CSI 驱动程序的 Azure 密钥保管库提供程序][akv-addon] 加载项。
az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER如果您的 Key Vault 使用 Azure RBAC 作为权限模型,请按照 此处 的说明,将 Azure 角色 "Key Vault 机密用户" 分配给加载项的用户分配的托管标识。 或者,如果密钥保管库使用的是保管库访问策略权限模型,请授权用户分配的加载项托管标识使用访问策略访问 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使用证书和密钥在 Azure 密钥保管库中创建机密。
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使用以下清单部署 SecretProviderClass,为 CSI 驱动程序提供 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: $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 引用证书对象类型,请使用以下清单部署 SecretProviderClass。 在此示例中,
test-httpbin-cert-pxf是 Azure Key Vault 中证书对象的名称。 有关详细信息,请参阅[获取证书和密钥][akv-csi-driver-obtain-cert-and-keys] 部分。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使用以下清单部署示例 Pod。 机密存储 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.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机密是否在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: 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来配置网关的入口流量路由。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 "我是一个茶壶" 代码。
注释
若要配置对 HTTPS 服务的 HTTPS 入口访问(即,将入口网关配置为对传入请求执行 SNI 直通而不是 TLS 终止),请将网关定义中的 tls 模式更新为
Passthrough。 这会指示网关“按原样”传递入口流量,而不会终止 TLS。
资源自定义
自定义批注设置
可以在 spec.infrastructure.annotations 下添加注释来为 Gateway。 例如,若要创建附加到特定子网的内部负载均衡器,可以使用以下注释创建一个 Gateway :
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
infrastructure:
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: "true"
service.beta.kubernetes.io/azure-load-balancer-internal-subnet: "my-subnet"
EOF
ConfigMap 自定义设置
- 服务
- 部署
- 水平 Pod 自动缩放程序 (HPA)
- Pod 中断预算 (PDB)
这些资源的默认设置是在 istio-gateway-class-defaults 命名空间中的 aks-istio-system ConfigMap 中设定的。 为使自定义对带有 gateway.istio.io/defaults-for-class 的所有 istio 生效,此 ConfigMap 必须将 Gateways 标签设置为 spec.gatewayClassName: istio。 启用GatewayClass后,aks-istio-system 命名空间中默认会安装 级别的 ConfigMap。 安装托管网关 API CRD 后,可能最多需要约 5 分钟才能完成 istio-gateway-class-defaults 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 在 GatewayClass 级别修改所有 Istio istio-gateway-class-defaults 的这些设置,也可为单个 Gateway 资源设定这些设置。 对于 GatewayClass 级别和 Gateway 级别的 ConfigMaps,字段必须添加到给定资源的允许列表中。 如果同时对 GatewayClass 和单个 Gateway 进行了自定义,那么 Gateway 级别的配置将优先。
资源自定义允许列表
资源允许列表中未包含的字段不被允许,且通过加载项管理的 webhook 进行阻止。 若要详细了解 、allowed 和 blocked 功能,请参阅 supported。
部署字段
| 字段路径 | 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 逐出失败而导致的 UpgradeFailed 错误。
配置 GatewayClass 级设置
在GatewayClass命名空间中更新aks-istio-system级别的ConfigMap。
kubectl edit cm istio-gateway-class-defaults -n aks-istio-system
编辑资源设置:
...
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 已更新:
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 httpbin-gateway-istio -ojsonpath='{.metadata.labels.test\.azureservicemesh\.io\/deployment-config}'
updated
配置特定网关的参数
为 httpbinGateway 创建带有资源自定义的 ConfigMap:
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。
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: httpbin-gateway
spec:
gatewayClassName: istio
infrastructure:
parametersRef:
group: ""
kind: ConfigMap
name: gw-options
listeners:
- name: http
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: Same
EOF
验证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 httpbin-gateway-istio -ojsonpath='{.metadata.labels.test\.azureservicemesh\.io\/deployment-config}'
updated-per-gateway
清理资源
运行以下命令以删除 Gateway 和 HttpRoute:
kubectl delete gateways.gateway.networking.k8s.io httpbin-gateway
kubectl delete httproute httpbin
如果您创建了用于定制Gateway的ConfigMap,请运行以下命令删除该ConfigMap:
kubectl delete configmap gw-options
如果创建了用于 TLS 终止的 SecretProviderClass 和机密,请删除以下资源:
kubectl delete secret httpbin-credential
kubectl delete pod secrets-store-sync-httpbin
kubectl delete secretproviderclass httpbin-credential-spc