本文介绍如何解决数据面Kubernetes集群中的Pod无法访问入口网关的SLB地址的问题。

问题现象

服务网格ASM已添加Kubernetes集群,并且使用Local类型的负载均衡SLB部署入口网关。当应用Pod访问入口网关暴露的SLB地址时,出现以下问题:
  • 部分节点上的Pod能访问入口网关暴露的SLB地址。
  • 部分节点上的Pod不能访问入口网关暴露的SLB地址。

问题原因

如果Kubernetes集群的服务配置了externalTrafficPolicy: Local,则只有部署了服务的后端Pod才能访问SLB地址。因为SLB地址是集群外使用,如果集群节点和Pod不能直接访问SLB地址,请求不会路由到负载均衡,而是被当作服务的扩展IP地址,被kube-proxy的iptables或IPVS转发。

如果集群节点或者Pod所在的节点上没有相应的后端服务Pod,就会发生网络不通的问题。而如果有相应的后端服务Pod,则可以正常访问SLB地址。更多信息,请参见iptables规则

解决方案

  • 您可以在Kubernetes集群内通过ClusterIP或者服务名访问SLB地址。其中入口网关的服务名为istio-ingressgateway.istio-system。
    说明 推荐使用该方法。
  • 如果您不需要源IP,您可以使用以下方法。
    将入口网关服务中的 externalTrafficPolicy修改为 Cluster,但是在应用中会丢失源IP。关于修改入口网关的更多信息,请参见 修改入口网关服务
    apiVersion: istio.alibabacloud.com/v1beta1
    kind: IstioGateway
    metadata:
      name: ingressgateway
      namespace: istio-system
      ....
    spec:
      externalTrafficPolicy: Cluster
    ....
  • 如果您使用的是Terway的ENI或者ENI多IP集群,您可以使用以下方法。该方法不会丢失源IP,也支持在集群内访问SLB地址。
    将入口网关服务中的 externalTrafficPolicy修改为 Cluster,并且添加ENI直通的Annotation,例如 serviceAnnotations: service.beta.kubernetes.io/backend-type:"eni"。关于修改入口网关的更多信息,请参见 修改入口网关服务
    apiVersion: istio.alibabacloud.com/v1beta1
    kind: IstioGateway
    metadata:
      name: ingressgateway
      namespace: istio-system
      ....
    spec:
      externalTrafficPolicy: Cluster
      maxReplicas: 5
      minReplicas: 2
      ports:
        - name: status-port
          port: 15020
          targetPort: 15020
        - name: http2
          port: 80
          targetPort: 80
        - name: https
          port: 443
          targetPort: 443
        - name: tls
          port: 15443
          targetPort: 15443
      replicaCount: 2
      resources:
        limits:
          cpu: '2'
          memory: 2G
        requests:
          cpu: 200m
          memory: 256Mi
      runAsRoot: false
      serviceAnnotations:
        service.beta.kubernetes.io/backend-type: eni
      serviceType: LoadBalancer