【问题标题】:How does k8s service route the traffic to mulitiple endpointsk8s 服务如何将流量路由到多个端点
【发布时间】:2019-02-26 00:49:28
【问题描述】:

在 Kubernetes 中,我们将 ClusterIp/Nodeport/LoadBalancer 作为 服务 来公开 pod。 当有多个端点绑定到一个服务(如部署)时,Kubernetes 将流量路由到其中一个端点的策略是什么?它会始终尝试尊重load balancing 策略,还是随机选择?

【问题讨论】:

    标签: kubernetes load-balancing


    【解决方案1】:

    Kubernetes 使用 iptables 在一组 pod 之间分配流量,正式名称为 explained by kubernetes.io。基本上,当您创建kind: service 对象时,K8s 会创建一个虚拟 ClusterIP 并指示 kube-proxy 守护进程更新每个节点上的 iptables,以便匹配该虚拟 IP 的请求将在一组 pod IP 之间实现负载平衡。这里的“虚拟”一词是指 ClusterIP 与 pod IP 不同,它不是由网络接口​​分配的真实 IP 地址,只是用作“过滤器”来匹配流量并将它们转发到正确的目的地。

    Kubernetes 文档说默认的负载平衡方法是轮询,但这并不完全准确。如果您查看任何工作节点上的 iptables,您会发现对于给定服务 foo,ClusterIP 为 172.20.86.5 和 3 个 pod,[过度简化] iptables 规则如下所示:

    $ kubectl get service foo
    
    NAME      TYPE       CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGE
    foo       ClusterIP  172.20.86.5   <none>        443:30937/TCP   12m
    
    Chain KUBE-SERVICES (2 references)
    target     prot opt source               destination         
    KUBE-SVC-4NIQ26WEGJLLPEYD  tcp  --  anywhere             172.20.86.5          /* default/foo:https cluster IP */ tcp dpt:https
    

    KUBE-SERVICES 链规则查找destination 为172.20.86.5 的所有流量,并应用在另一个名为KUBE-SVC-4NIQ26WEGJLLPEYD 的链中定义的规则:

    Chain KUBE-SVC-4NIQ26WEGJLLPEYD (2 references)
    target     prot opt source               destination         
    KUBE-SEP-4GQBH7D5EV5ANHLR  all  --  anywhere             anywhere             /* default/foo:https */ statistic mode random probability 0.33332999982
    KUBE-SEP-XMNJYETXA5COSMOZ  all  --  anywhere             anywhere             /* default/foo:https */ statistic mode random probability 0.50000000000
    KUBE-SEP-YGQ22DTWGVO4D4MM  all  --  anywhere             anywhere             /* default/foo:https */
    

    这个链使用statistic mode random probability 随机发送流量到定义的三个链之一(因为我有三个 pod,我在这里有三个链,每个链都有 33.3% 的机会被选择接收流量)。这些链中的每一个都是将流量发送到后端 pod IP 的最终规则。例如看第一个:

    Chain KUBE-SEP-4GQBH7D5EV5ANHLR (1 references)
    target     prot opt source               destination         
    DNAT       tcp  --  anywhere             anywhere             /* default/foo:https */ tcp to:10.100.1.164:12345
    

    DNAT 指令将数据包转发到 IP 地址 10.100.1.164(真实 pod IP)和端口 12345(foo 监听的端口)。其他两个链(KUBE-SEP-XMNJYETXA5COSMOZKUBE-SEP-YGQ22DTWGVO4D4MM)是相似的,只是每个链都有不同的 IP 地址。

    同样,如果您的服务类型是NodePort,Kubernetes 会在节点上分配一个随机端口(默认为 30000-32767)。有趣的是,工作节点上没有进程主动侦听此端口 - 相反,这是另一个 iptables 规则来匹配流量并将其发送到正确的 Pod 集:

    Chain KUBE-NODEPORTS (1 references)
    target     prot opt source               destination         
    KUBE-SVC-4NIQ26WEGJLLPEYD  tcp  --  anywhere             anywhere             /* default/foo:https */ tcp dpt:30937
    

    此规则匹配到端口 30937 (tcp dpt:30937) 的入站流量,并将其转发到链 KUBE-SVC-4NIQ26WEGJLLPEYD。但你猜怎么着:KUBE-SVC-4NIQ26WEGJLLPEYD 与集群 ip 172.20.86.5 匹配并将流量发送到的完全相同的链,如上所示。

    【讨论】:

    • 非常感谢您的详细说明! :)
    【解决方案2】:

    kubernetes 服务使用循环策略将调用分发到多个 pod

    【讨论】:

      【解决方案3】:

      这可能会有所帮助 https://kubernetes.io/docs/concepts/services-networking/#proxy-mode-ipvs

      总之,如果您想管理不同的负载均衡方法,您必须将您的 k8s 代理置于 ipvs 模式并选择以下方法之一: rr: 循环法

      lc:最少连接

      dh:目标哈希

      sh:源散列

      sed:最短的预期延迟

      nq:从不排队

      【讨论】:

        猜你喜欢
        • 2023-01-02
        • 2015-06-30
        • 2020-12-18
        • 1970-01-01
        • 2021-04-28
        • 2017-05-16
        • 1970-01-01
        • 2021-12-03
        • 2018-02-27
        相关资源
        最近更新 更多