【问题标题】:How do Kubernetes NodePort services with Service.spec.externalTrafficPolicy=Local route traffic?Kubernetes NodePort 服务如何使用 Service.spec.externalTrafficPolicy=Local 路由流量?
【发布时间】:2020-05-20 20:37:47
【问题描述】:

对于 NodePort 服务如何路由流量,似乎有两种相互矛盾的解释。服务可以将流量路由到两者之一,而不是两者:

  1. 节点(通过 kube-proxy) 根据 kubectl explain Service.spec.externalTrafficPolicythis article 添加更多详细信息,传入带有 Service.spec.externalTrafficPolicy=Local 设置的 NodePort 服务的数据包被路由到 kube-proxy,然后路由将数据包发送到其运行的相应 pod。
  2. Pods:服务从 endpoints 更新其 IPtables,其中包含它们可以路由到的 pods 的 IP 地址。此外,如果您删除服务的标签选择器和 edit endpoints,您可以更改流量路由到的位置。

如果其中一个是正确的,那么我一定是误会了。

  • 如果服务路由到节点,那么为什么我可以编辑endpoints 而不会破坏IPtables?
  • 如果服务路由到pods,那么为什么设置Service.spec.externalTrafficPolicy时服务会遇到路由到节点的麻烦?

【问题讨论】:

    标签: kubernetes kubernetes-service


    【解决方案1】:

    Service 是由kube-proxy 管理的虚拟地址/端口。服务将流量转发到其关联的端点,这些端点通常是 pod,但正如您所提到的,可以将其设置为任何目标 IP/端口。

    NodePort Service 不会改变服务的端点端,NodePort 允许外部流量通过节点上的端口进入服务。

    服务分解

    kube-proxy可以使用3 methods来实现一个服务从Node到目的地的转发。

    • 用户代理
    • iptables
    • ipvs

    大多数集群都使用 iptables,如下所述。我使用术语“转发”而不是“路由”,因为服务使用Network Address Translation(或代理)来“转发”流量而不是标准网络路由。

    服务ClusterIP 是一个由kube-proxy 管理的虚拟实体。此地址/端口组合在集群中的每个节点上都可用,并将任何本地(pod)服务流量转发到端点 IP 和端口。

                                             / Pod (remote node)
    Pod -- ClusterIP/Port -- KUBE-SVC-NAT  --  Pod
                                             \ Pod (remote node)
    

    NodePort 的服务与上述相同,只是增加了一种通过 Node.js 将外部流量转发到集群的方法。 kube-proxy 管理一个额外的规则来监视外部流量并将其转发到相同的服务规则中。

    Ext --     NodePort   \                / Pod (remote node)
                            KUBE-SVC-NAT --  Pod
    Pod -- ClusterIP/Port /                \ Pod (remote node)
    

    externalTrafficPolicy=Local 设置使 NodePort 服务使用本地 Pod 来服务传入流量。这避免了网络跳跃,从而消除了重写数据包源的需要(通过 NAT)。这会导致真正的网络 IP 到达为连接提供服务的 pod,而不是集群节点之一是源 IP。

    Ext --     NodePort   \                  Pod (remote node)
                            KUBE-SVC-NAT --  Pod (local)
    Pod -- ClusterIP/Port /                  Pod (remote node)
    

    iptables

    我建议尝试跟踪主机上服务或节点端口从源到目标的连接。它需要一些 iptables 知识,但我认为这是值得的

    列出所有将被转发的服务ip/端口:

    iptables -vnL -t nat KUBE-SERVICES

    列出所有将被转发的节点端口:

    iptables -vnL -t nat KUBE-NODEPORTS

    一旦你有了规则,你就可以在完整输出中跳过KUBE-SVC-XXX“目标”规则。

    iptables -vnL -t nat | less

    【讨论】:

    • 那么如何将externalTrafficPolicy 应用于负载平衡流量?负载均衡器是否知道哪些节点正在运行相应的 pod?
    • 对于带有NodePort 服务的手动 lb,lb 健康检查将在未运行 pod 的节点上失败。您可以在部署中使用节点选择器来限制您在 lb 配置上匹配的节点。
    • 对于type: LoadBalancer,只有所需的节点应该被推送到lb(至少在AWS上是这样。我想它可能会因cloud-provider而异)
    【解决方案2】:

    externalTrafficPolicy:ClusterIP 上不会使用集群,尝试删除并应用它,它会起作用

    【讨论】:

      猜你喜欢
      • 2021-05-04
      • 1970-01-01
      • 2021-12-03
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      • 2018-02-03
      • 1970-01-01
      • 2021-05-02
      相关资源
      最近更新 更多