如何解决Kubernetes集群中的Pod无法访问入口网关的CLB地址的问题?

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

问题现象

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

  • 部分节点上的Pod能访问入口网关暴露的CLB地址。

  • 部分节点上的Pod不能访问入口网关暴露的CLB地址。

问题原因

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

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

解决方案

  • 您可以在Kubernetes集群内通过ClusterIP或者服务名访问CLB地址。其中入口网关的服务名为istio-ingressgateway.istio-system。

    说明

    推荐使用该方法。

  • 如果您不需要源IP,您可以使用以下方法。

    将入口网关服务中的externalTrafficPolicy修改为Cluster,但是在应用中会丢失源IP。关于修改入口网关的更多信息,请参见ASM网关CRD说明

    apiVersion: istio.alibabacloud.com/v1beta1
    kind: IstioGateway
    metadata:
      name: ingressgateway
      namespace: istio-system
      ....
    spec:
      externalTrafficPolicy: Cluster
    ....
  • 如果您使用的是Terway的ENI或者ENI多IP集群,您可以使用以下方法。该方法不会丢失源IP,也支持在集群内访问CLB地址。

    将入口网关服务中的externalTrafficPolicy修改为Cluster,并且添加ENI直通的Annotation,例如serviceAnnotations: service.beta.kubernetes.io/backend-type: eni。关于修改入口网关的更多信息,请参见ASM网关CRD说明

    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