V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
huage
V2EX  ›  Kubernetes

在 k8s 中如何实现 NGINX 的高可用?

  •  
  •   huage · 2023-08-28 11:50:59 +08:00 · 2908 次点击
    这是一个创建于 462 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我对 ingress nginx 不太懂,我需要服务高可用的话,使用 ingress nginx 就不需要 VIP 了吗?那么对外暴露的地址是什么?

    例如 k8s 下 NGINX 高可用的话,对外暴露的地址是什么?

    例如 k8s 下 MySQL 高可用的话,对外暴露的地址是什么?
    第 1 条附言  ·  2023-08-28 14:41:55 +08:00
    我上面的描述可能不太准确,我想表达的是 k8s 部署的服务是高可用的话,可以怎么实现?对外暴露的地址是什么?

    例如之前:多个虚拟机+keepalived+vip 来实现,VIP 就是对外暴露的地址,也就是基于 IP 的网络通讯,不管在局域网还是互联网都可以实现。

    那么在 k8s 管理的部署服务里,上面这样的场景是如何实现的?或者是不是有更好的实现?

    例如在局域网环境下,是没有云厂商提供 LB 的,需要自己解决负载均衡的问题,这时候就要考虑通讯层面的事情。

    举例来说 k8s 里面部署 NGINX ,需要实现高可用,是什么用的方案?
    21 条回复    2023-09-19 16:56:29 +08:00
    seers
        1
    seers  
       2023-08-28 12:12:26 +08:00 via Android
    service
    StoneHuLu
        2
    StoneHuLu  
       2023-08-28 12:22:15 +08:00   ❤️ 11
    首先你具体的服务是容器,容器在 pod 里,pod 的 ip 是会变的,所以引入 service ,service 的 ip 是集群内固定的 ip ,然后你的每个 pod 是一个 endpoint ,service 管理多个 endpoint ,根据一定规则把每次请求分发到不同的 endpoint ,也就是 pod ,然后 service 可以通过 nodePort 或者 LoadBalance 把集群内服务暴露给外部访问,但这是基于 ip+端口号的,而 ingress 就是在 service 的基础上,提供根据域名、路由、正则等你所有能想得到的基于域名解析的路由分配请求的方式,比如 a.b.com 分配到 service1 ,b.b.com 分配给 service2 ,*.b.com 分配给 service3 。
    简单理解的话,集群外部流量是按这个顺序来的:ingress->service->pod->container
    然后 ingress 有各种不同的实现,Nginx 只是其中一种,更强大的还有 ingress-traefik 、ingress-apisix ,说白了 ingress 就是个 interface ,Nginx apisix traefik 只是实现了这个 interface 的具体功能而已,基于这个理解,你可以认为,ingress 实际上就是一个集群专用的反向代理。
    而 ingress 可以使用 deployment 、daemonset 等方式进行部署,部署后本身也是 pod ,那么它实际上也符合上述的条件,ingress 也有 service ,一般来说会使用 LoadBalance 模式的 service 暴露出一个 ip ,这样的话你应该能理解了,ingress 有多个 pod ,所以本身是高可用,然后通过 LoadBalance 的 service 做了一个负载均衡+暴露服务,接下来你只需要到 dns 提供商那里把你的域名解析到这个 ip 上就可以了,用户通过访问域名,就会把流量打到你的 ingress 的 pod 上,然后 ingress 根据域名规则,把请求路由到具体服务的 service 上,service 本身又有负载均衡,会路由到不同的 pod 上,基于此实现整个集群的 ha
    coala
        3
    coala  
       2023-08-28 12:23:37 +08:00
    我也算踩了这个坑吧, 一开始用的 Nginx ,

    你可以试试 ingress + Traefik 代替 Nginx 。
    panisertoller
        4
    panisertoller  
       2023-08-28 12:37:36 +08:00
    我之前也是 nginx ,后来改用了 以 DaemonSet 模式部署 Traefik ,感兴趣可以看看 https://www.rehiy.com/post/462/
    anubu
        5
    anubu  
       2023-08-28 12:45:07 +08:00
    还是需要 VIP 的。高可用场景是逃离不了 VIP 这个东西的,因为底层是基于 IP 通信的。在 k8s 场景里,VIP 这个东西往往放到 loadbalance 来一起做,导致对高可用、负载均衡、VIP 这些概念理解起来比较混乱。事实上,也可以指定 externalIP 为 VIP 来绑定 NGINX 服务。
    eudore
        6
    eudore  
       2023-08-28 12:56:03 +08:00
    在 k8s 环境下应该放弃使用 nginx 作为 http 入口,改使用 ingress 模式进行 http 反向代理,一些不常见配置 nginx 需求应该直接转移实现位置,nginx 和 Traefik 都是 ingress 的实现方式之一。

    暴露 svc 地址就可以暴露 ip ,使用 loadbalance 或 nodeport ;另外一种是 daemonset+hostnetwrok 直接暴露 pod 端口 不推荐。
    dzdh
        7
    dzdh  
       2023-08-28 12:58:17 +08:00
    对外服务节点搞 vip 或者在机房路由做 4 层 lb
    dzdh
        8
    dzdh  
       2023-08-28 12:59:13 +08:00
    k8s 只是一种服务部署的概念,下面还是网络层那一套 vip 跑不了
    BeautifulSoap
        9
    BeautifulSoap  
       2023-08-28 13:26:32 +08:00 via Android   ❤️ 2
    @coala 从 traefik ingress 回到 nginx ingress 的在这。teaefik 会随机把流量导向任意一个节点中的 service 而不是优先导向本地的 service 而且没法更改,会导致很多问题。
    比如我用 k8s 在每个节点搭了 xray 梯子,traefik 这个问题会导致你访问东京节点,然后 traefik 把请求给随机导向集群内任意一个节点的 xray pod 处理(比如美国,欧洲),这样流量的路径实际上是 你的电脑 → 东京节点 → 美国节点 ,延迟会非常高且 ip 跳来跳去。
    再比如我为了测试每个节点的连接速度,我在每个节点跑了个 nginx 并且生成了 1g 的 bin 文件。trraefik 这个问题会导致我想测连东京节点的下载速度,结果测的是我到东京又绕美国的下载速度
    dayeye2006199
        10
    dayeye2006199  
       2023-08-28 13:30:37 +08:00
    ingress controller 会部署多个备份保证 ingress 服务本身的高可用的。

    ingress 对外暴露的 LB 一般直接用云厂商提供的 LB ,这个是由云厂商保证高可用
    tairan2006
        11
    tairan2006  
       2023-08-28 13:36:23 +08:00
    在云环境下,ing 一般通过云服务商提供的 LoadBalancer 暴露到外面;

    自建机房的话,可以考虑 MetalLB+Keepalived ;有域名的话也可以不用 Keepalived 直接用域名;
    tudou1514
        12
    tudou1514  
       2023-08-28 15:14:33 +08:00
    service 简称 svc 。ingress 解析的地址实际是这个 svc 地址,而 svc 在 k8s 里面在 pod 前面实际上是个小型负载均衡,负载到一个或者 N 个 pod (同一个业务的 pod )
    vhwwls
        13
    vhwwls  
       2023-08-28 15:33:54 +08:00
    ingress-nginx 自己可以跑多个 Pod ,自身就是高可用的,在公有云环境下的设计是怎么回事上面已经有同行说过了,在私有云环境下,可以用 metalb 这种东西,如果你觉得心智成本太大,可以很干脆的把 ingress-nginx pod 全部运行为 hostNetwork: true 模式,然后再在前面加一对 nginx ,这一对 nginx 负责把流量转发到 ingerss-nginx pod 上,包括 https 卸载也可以在这对 nginx 上来做,同时这一对 nginx 上也用 Keepalived 部署一个 VIP ,让网工配置入口防火墙把流量打到这个 VIP 上,基本上就可以完成高可用了,再往外的话还得考虑互联网专线也要两条,不然就一条断了的话还是 GG 。
    liuhan907
        14
    liuhan907  
       2023-08-28 15:38:17 +08:00
    你是否在寻找: calico BGP mode
    huage
        15
    huage  
    OP
       2023-08-28 17:30:39 +08:00
    @liuhan907 愿闻其翔
    liuhan907
        16
    liuhan907  
       2023-08-29 12:11:50 +08:00
    @huage
    看 calico 的文档吧。metallb + calico BGP 可以实现你想要的功能。配置略微复杂且在云上配置比较麻烦,一般本地部署用,云上就还是老实的用云提供的 LB 。
    lf978
        17
    lf978  
       2023-09-06 15:44:37 +08:00
    @panisertoller 那这个如果对外提供服务, 是直接路由器配置指向到 ns 上吗?
    kennylam777
        18
    kennylam777  
       2023-09-07 00:21:45 +08:00
    先說一下, Cloud natives 的 Load balancer 走的是 nodePorts, 每一台 node 沒有 node excluded label 的都是 node ports 的提供者, 例如 nodePort 35000 就是 kube-proxy 在所有 nodes 打開 port 35000, 進來的連線都是用 iptables/ipvs 指導到 pod IP 上。

    你所提及的 VIP 方案, 用 MetalLB 的 ARP 模式就可以實現, 反正都是 failover 的單點方案。

    上面提及的 MetalLB 及 Calico BGP 有點遠了, 應該是本人沒試過的才會這樣答, MetalLB BGP 根本不看 CNI 的, 那怕 CNI 是 Flannel 也可以使用 MetalLB BGP 啊。
    kennylam777
        19
    kennylam777  
       2023-09-07 00:34:30 +08:00
    MetalLB Layer-2 ARP 模式跟 Keepalived 是相似的, 但配置簡單太多了。

    這種模式的問題是, 只有一個 node 在提供服務

    1. failover 需要的時間比較長
    2. 流量集中在 elected leader 的一個 node 上

    MetalLB BGP 就是解決流量集中的問題而生的, 利用 BGP 做出 ECMP 路由, 在內網製造 Anycast 的效果, 但首要條件是你內網路由器要有 BGP

    Anycast 也不能在同一個 subnet 下運作, 例如 client 在 192.168.0.20/24, 而你的 Anycast IP 在 192.168.0.100/24, 這種配置是毫無意義的。
    panisertoller
        20
    panisertoller  
       2023-09-15 16:38:36 +08:00
    @lf978 默认就是对外的
    lf978
        21
    lf978  
       2023-09-19 16:56:29 +08:00
    @panisertoller 端口怎么处理的 是开的 nodeport 模式吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6043 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 02:36 · PVG 10:36 · LAX 18:36 · JFK 21:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.