Troubleshooting | 通过Load Balancer IP访问服务时好时坏

参考文档

externalTrafficPolicy - Technotes (adelerhof.eu)
Configure kubenet networking in Azure Kubernetes Service (AKS) - Azure Kubernetes Service | Microsoft Learn

环境背景及问题现象

  • AKS集群使用kubenetes网络插件
  • 服务通过Internal LB暴露
  • 通过clusterIP访问服务正常,但通过Internal LB IP访问时出现大概率失败小概率成功的情况

排查分析

  • 首先检查ILB的探测情况,探测存在部分失败的情况。

  • 检查健康探测配置规则,由于AKS的LB为AKS托管,规则都是自动配置的;查看LB探测规则为以TCP方式探测NodePort的高位端口;以此推测s集群中service使用的是externalTrafficPolicy: Cluster的流量分发模式。

  • 在此模式下,探测流量被Node接收后会跟进iptables规则平均分发给不同节点上的实际业务pod进行响应。Node在做转发时,会进行SNAT。如果node到pod的通信有问题,则会导致仅有分发到同一节点上的Pod的探测成功,跨节点的探测不成功。

    alt text
    图片来源

  • 进一步检查集群NSG配置,发现Node与Pod之间的流量未放通。

    Configure kubenet networking in Azure Kubernetes Service (AKS) - Azure Kubernetes Service | Microsoft Learn
    alt text

解决方案

调整放通node与pod之间的流量后访问正常。

知识点延申

  1. 当service的externalTrafficPolicy的配置不同时,LB的探测有如下不同的行为:

    • 当externalTrafficPolicy设置为cluster时(default),LB使用的TCP探测模式,且请求会由后端实际的业务pod响应。此模式下,集群中所有的节点都会接收流量,当该节点没有部署对应的service pod时,请求将由该节点转发给部署了service pod的节点上,同时源IP地址被替换为节点的IP地址。

    • 当externalTrafficPolicy设置为local时, LB对后端应用(探测方式为http/https,探测路径为/healthz)的探测流量由节点上对应kube proxy的node port端口处理,不再由后端的应用来处理。当服务的Pod没有分布在所有节点上时,探测请求到达没有pod的节点上,会拿到503的返回,此时metrics可能会显示部分不健康,属于预期现象。
      alt text

  2. 如果同时设置了externalTrafficPolicy: local以及以下annotation,externalTrafficPolicy配置的优先级更高,LB的探测方式依然会是HTTP(s)。

    1
    2
    3
    annotation:
    service.beta.kubernetes.io/port_443_health-probe_protocol: "tcp"
    service.beta.kubernetes.io/port_80_health-probe_protocol: "tcp"