udp服务 k8s方案(细化)

方案思路

需求

保留客户端地址,k8s服务对外一个地址和53端口,负载均衡。

可能的方案

  • hostnetwork 针对pod级别(负载均衡可以放到外面做,我们不考虑。k8s的开发目标本身就是服务编排没必要自造轮子)

  • hostport也是,针对pod(原因如上)

  • kube port-forward命令
    k8s服务对外端口转发。不仅支持pod,现在支持service了。但目前不支持udp。社区有人开发出了,但没有approve。

  • ddns service type=cluster ip方式,默认保留客户端ip;只能集群内部访问。

  • ddns service type=cluster ip方式,对clusterip 设置static route,从外网访问,方案不好。

  • ddns service type=nodeport方式
    默认不保留。但service.spec.externalTrafficPolicy=local就可以了;
    nodeport端口默认30000以上,除非修改k8s源码修改到支持53端口,也有可能冲突等。
    前面加个负载均衡器nginx类似的可以做到对外一个ip地址。k8s社区采用以下的方案。

  • ddns service type=nodeport + keepalive-vip
    可以做到多个node的failover,高可用,但没有node的负载均衡。

  • ddns service type=loadbalancer方式
    默认不保留客户端IP地址。
    云厂商如google/aws支持保留客户端,
    对于开源的metallb(onpremis)

    • metallb:

      1. lay2 arp
        目前不支持保留客户端ip。保留客户端的方式 正在社区在开发中,时间不可估。
        metallb本身暂时不支持proxy protocol协议,我们ddns也暂时不支持proxy protocol协议。所以proxy protocol方式也不可以。
        注意:proxy protocol作用是在proxy与后端或者proxy间传递客户端ip地址信息的协议,一种保留客户单ip的方法。
        暂时本身只是支持failover不能负载均衡(why)。与keeplive-vip类似。
      2. BGP 方式
        支持保留客户端ip,真正的负载均衡
        咱们部署的时候需要BGP路由器,以便metalb的extra ip从internet可以路由到k8s集群。
        BGP本身复杂。
  • ingress nginx,nginx service type=nodeport,ddns service type clusterip方式
    保证了多个node的负载均衡,但是为了端口不是53,前面可能需要有个proxy或者keepalive等。
    nginx upd代理下保留客户端ip的方法有:

    1. proxy protocol:不支持udp,尽支持tcp。需要开发nginx和ddns的proxy protocol。
    2. proxy bind ip透明方式 container/pod后端和nginx端需要设置路由等
    3. dsr直接服务区返回,基于2.
      需要先熟悉基本的ingress nginx 然后探索方便的方法进行container端的网络设置(采用2/3)
      咨询了开发者,目前2/3暂时不能工作,需要摸索实现。
  • ingress nginx,nginx service type=loadbalancer, ddns service type clusterip方式
    前面加上metalb,如果上面proxy_bind or dsr 走通,就可以做到node本身负载均衡和保留客户端ip。

  • 其他ingress方式如haproxy,envoy,traefik 目前都不支持upd负载均衡。

  • 一种基于ecmp的方法
    https://github.com/Mirantis/k8s-externalipcontroller/blob/master/doc/ecmp-load-balancing.md
    有必要探索

一些tradeoff

  • 只一台机器

    • 不需要考虑node的failover和loadbalance,只考虑k8s内部的负载均衡。但要考虑到将来k8s扩容的需要和k8s本身的设计目标:服务编排,隐藏分布式系统的实现细节。

    • 建一个service,采用clusterip方式。kube port forward命令的方式,upd不支持。

    • 建一个service,采用nodeport方式,机器使用端口转发把53端口的流量转发到nodeport端口。

      • 可以采用,但将来要是再添加一个单机k8s集群,我们需要管理多个k8s集群,只利用了单机的功能,不能利用master的高可用,不能利用一个worker节点坏了自动调度其上得pod到其他节点上等功能,也不能利用多个worker节点的负载均衡功能等。而所有k8s已经考虑的问题需要我们在集群外考虑。)
      • 如果不是添加一个单机k8s集群,而是扩容的方式,这样就到了k8s多台机器的方式了。我们考虑多节点k8s的解决方案。
    • 建多个service,采用nodeport的方式,就是多个nodeport出现,需要引入外部负载均衡或者ingress nginx等对外才可能是一个53端口,也类似与多节点k8s的方案。

  • 多台机器

    • failover,没有多个节点的负载均衡

      • keepalive-vip + dns service(nodeport)
      • metallb layer2 (暂时不考虑)
    • lb

      • ingress nginx(udp的探索)
        需要考虑那个对外端口53

        1. 前面加一个负载均衡比如metalb,简单实用但bgp配置复杂可能还需要bgp路由成本。
        2. 如果加上个nginx反向代理也得考虑保留客户ip问题。
        3. 如果只用portforward,只能考虑单个机器。
        4. ingress nginx前部署keepalive-vip的方法,可以保证了服务的高可用,同时端口也能做到53。
      • metallb( BGP)

结论

  • 如果优先考虑多节点负载均衡的话,重点ingress nginx +keepalive-vip方案。如果BGP方案已有设备,也可以探索metallb的方案。
  • 如果优先考虑多节点failover,采用keepalive + dns service(nodeport)。
  • 如果只考虑多节点不考虑扩展性等,采用建一个service nodeport方式,机器使用端口转发把53端口的流量转发到nodeport端口。
Webmentions

Loading...

When you post a tweet with a link to this post it will automatically show up here! (refreshed every 30 minutes) 💯

A small favor

Was anything I wrote confusing, outdated, or incorrect? Please let me know! Just write a few words below and I'll be sure to amend this post with your suggestions.

Follow along

If you want to know about new posts, add your email below. Alternatively, you can subscribe with RSS.

More from 格物治用

实践、探索、思考.

View all posts