使用 Kubernetes 网关 API 配置 Istio 入口

除了 Istio 自己的入口流量管理 API,Istio 服务网格加载项还支持 Kubernetes 网关 API 进行入口流量管理。 若要使用 Istio 加载项从 Azure 接收对基于网关 API 的部署的支持,必须在群集上启用 托管网关 API 安装 。 可以使用 Istio 网关 API 自动部署模型手动部署模型 进行入口流量管理。 ConfigMap 自定义必须属于 资源自定义允许列表

局限性

  • 仅支持在手动部署模型中使用 Kubernetes 网关 API 进行出口流量管理与 Istio 加载项。
  • 针对Gateway资源的ConfigMap自定义必须属于资源自定义允许列表。 不在允许列表上的字段是不允许的,并通过插件管理的 Webhook 进行阻止。 若要详细了解 allowedblocked 功能,请参阅 supported

先决条件

使用 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 创建了 ServiceHorizontalPodAutoscalerPodDisruptionBudgethttpbin-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 群集。

资源自定义

Istio 加载项还支持对为生成的资源进行自定义,即:

  • 服务
  • 部署
  • 水平 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 可能需要长达约 5 分钟才能部署 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 在 GatewayClass 级别修改所有 Istio istio-gateway-class-defaults 的这些设置,也可为单个 Gateway 资源设定这些设置。 对于 GatewayClass 级别和 Gateway 级别的 ConfigMaps,字段必须添加到给定资源的允许列表中。 如果同时对 GatewayClass 和单个 Gateway 进行了自定义,那么 Gateway 级别的配置将优先。

资源自定义允许列表

资源允许列表中未包含的字段不被允许,且通过加载项管理的 webhook 进行阻止。 若要详细了解 allowedblocked 功能,请参阅 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。

现在,你应该会看到你之前创建的 HPAhttpbin-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

配置特定网关的参数

创建带有资源自定义的 ConfigMap httpbinGateway:

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

后续步骤