k8s 该怎么在多个 replica 的情况下只让其中一个接受流量 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
UnknownR
V2EX    Kubernetes

k8s 该怎么在多个 replica 的情况下只让其中一个接受流量

  •  
  •   UnknownR 2020-07-30 20:36:48 +08:00 5032 次点击
    这是一个创建于 1903 天前的主题,其中的信息可能已经有所发展或是发改变。

    目前业务遇到了比较蛋疼的问题,虽然要上 k8s 但是应用本身不支持 replica,不然会出重复数据 看了一圈发现好像 k8s 不管是 replicaset 还是 hpa 好像都只支持多个 pod 同时 active 然后随机接受流量,请问有什么方法能同时跑多个 pod 但是只让其中一个接受流量,剩下的只是运行状态?类似 DB 的 primary 和 secondary,只有 primary 接受流量,剩下的只要在 primary 挂掉时能及时接上就好。

    数据是统一写入数据库的,所以不存在数据差异问题

    33 条回复    2020-10-09 15:43:51 +08:00
    kaikai5601
        1
    kaikai5601  
       2020-07-30 20:37:59 +08:00 via iPhone
    你就起一个 pod 不就好了
    wxsm
        2
    wxsm  
       2020-07-30 20:39:32 +08:00 via iPhone
    就起 1 个,挂掉了会自动重启
    UnknownR
        3
    UnknownR  
    OP
       2020-07-30 20:40:03 +08:00
    @kaikai5601 但是挂掉时就没法快速切换另一个上。。启动再快也需要时间
    wetist
        4
    wetist  
       2020-07-30 20:42:11 +08:00
    让开发试试分布式锁?
    UnknownR
        5
    UnknownR  
    OP
       2020-07-30 20:42:33 +08:00
    @wxsm 想要达到的效果是能无缝切换,自动重启的话用户的体验可能就会差,重启能被感知
    wxsm
        6
    wxsm  
       2020-07-30 20:46:44 +08:00 via iPhone   5
    提供一个思路:利用 readinessProbe
    从节点定时检测主节点是否存活,存活的话该检测提供失败返回,就不会被 k8s 分配流量,同时也不会被杀死。
    UnknownR
        7
    UnknownR  
    OP
       2020-07-30 20:47:41 +08:00
    @wetist 哎这个需求时间紧迫,开发这边的方案已经提了好几个了
    Reficul
        8
    Reficul  
       2020-07-30 20:49:40 +08:00   1
    用 APIServer 里的资源对象来实现分布式锁,锁释放下一个顶上
    UnknownR
        9
    UnknownR  
    OP
       2020-07-30 20:49:52 +08:00
    @wxsm 非常感谢!我去试试,就是为了确保故障不被感知,检测频率可能要非常高。。。
    jmperdev
        10
    jmperdev  
       2020-07-30 21:00:24 +08:00
    可以在负载均衡层考虑
    derek80
        11
    derek80  
       2020-07-30 23:59:18 +08:00 via iPhone
    上 istio
    derek80
        12
    derek80  
       2020-07-31 00:00:29 +08:00 via iPhone
    或者在自定义的 ingress controller 层面控制。有已有的实现
    bwangel
        13
    bwangel  
       2020-07-31 00:07:40 +08:00
    @UnknownR readinessProbe 每 10 秒检测一次,这个故障恢复时间应该很快了。
    gleymonkey
        14
    gleymonkey  
       2020-07-31 01:05:06 +08:00
    单节点就是个坑
    yisaYisa
        15
    yisaYisa  
       2020-07-31 01:18:48 +08:00   2
    这个需求其实非常简单也非常普遍。 比如 kubernetes 的 controller-manager 是怎么做 HA 的?常用的 k8s 上的 operator 的 controller 组件是怎么做 HA 的? 其实上面已经有人给出答案了就是用分布式锁。当然这个分布式锁的轮子也不需要你重复造,kubernetes 早就帮你搞好了。k8s project 里 client-go 中就有 "leaderelection" 可以直接用。具体例子可以参考这个项目。

    https://github.com/pingcap/tidb-operator/blob/8a86f9a661aa30393ce8f087aa388d107e57e72b/cmd/controller-manager/main.go#L241-L253
    wd
        16
    wd  
       2020-07-31 04:10:15 +08:00 via iPhone
    又不要重复数据,也不要当机时间,数据库搞了那么多年你看他们实现了没?你可以掂量掂量自己可以做到什么程度。
    zliea
        17
    zliea  
       2020-07-31 05:02:16 +08:00
    lb+有状态服务?
    yuaner
        18
    yuaner  
       2020-07-31 07:31:21 +08:00
    用 istio
    haidii
        19
    haidii  
       2020-07-31 07:58:03 +08:00
    多个 replica 下,可以通过 给 pod 添加标签的方式,根据标签值,让流量只流向其中一个 pod 。
    sampeng
        20
    sampeng  
       2020-07-31 08:34:25 +08:00 via iPhone
    所以一个无服务状态是多么得重要。
    sampeng
        21
    sampeng  
       2020-07-31 08:36:04 +08:00 via iPhone
    那你们上 k8s 的意义是什么?硬上么?不支持多节点就改称支持。哪里有状态就用 redis,数据库等稳定的服务分离状态。硬上 k8s 没收益还带来复杂度
    sampeng
        22
    sampeng  
       2020-07-31 08:37:06 +08:00 via iPhone
    我们刚上 k8s 的时候也是这样,尤其是定时任务。我一个一个盯着全改成 xxl-job,可以支持了就切
    xuanbg
        23
    xuanbg  
       2020-07-31 08:47:24 +08:00
    楼主你这个需求叫“热备”,主备热切换,非常古老的可用性方案了。现在流行的可用性方案是无状态的分布式,核心就是不管谁挂,反正流量都是活着的分摊,费效比比热备不知道高哪里去了……

    所以 k8s 在设计的时候根本就没有考虑热备这种古老的需求,这就比较僵硬。不过,办法还是有的。楼主你在 k8s 外面再做一套热备就是了。
    yushiwho
        24
    yushiwho  
       2020-07-31 08:47:37 +08:00 via Android
    controller 都是这种机制 参考 kuberbuilder
    abowloflrf
        25
    abowloflrf  
       2020-07-31 09:00:40 +08:00 via iPhone
    deployment 下的所有 pod 都是无差别对待的也就是无状态的,楼主的需求感觉应用还是有状态。解决办法想到有一个就是楼上所说,用一个锁,若是 golang,client-go 自带 leaderelection 的包,用了 apiserver 里一个唯一的资源做 leader 选举,非 leader 的 pod 在探针里返回失败就行这样 endpoint 就不会加入到 service 里。另外一个想法就是部署两个副本数为 1 的 deployment 再控制流量。
    rrfeng
        26
    rrfeng  
       2020-07-31 09:57:49 +08:00
    你应该去看 service 的实现。

    这个需求不在 k8s 上加功能的前提下自己实现的思路有以下几种:
    1. 用 statefulset,这样每个 pod 有独立的 service name,然后 client 去搞切换
    2. 继续用 deployment ( replicaset ),然后 client 不直接调用 service,而是去拿 service 对应的 endpoint 对应的 pod,还是 client 去搞切换
    3. 继续用 deployment,然后自己搞个额外小程序跑起来,选主然后注册成一个 service
    4. 加个 proxy,proxy 帮你做切换
    5. server 代码里加竞争机制,只有一个可以提供服务。
    Illusionary
        27
    Illusionary  
       2020-07-31 10:07:34 +08:00
    单节点要求高可用? 你们的开发水平配不上在运维层面使用 k8s,建议用回单 docker 部署,或者 tomcat 也行嗷
    rushssss
        28
    rushssss  
       2020-07-31 10:08:11 +08:00
    @yisaYisa 这个方案除了不满足 “应该让应用对 k8s 无感知" 这条最佳实践外,几乎是最好的方案,当然就算你不用 k8s 的 api, 也必须要有其他的分布式的,强一致的组件来做协调
    lostsquirrelX
        29
    lostsquirrelX  
       2020-07-31 14:30:58 +08:00
    nginx 支持主备,但要注意解析缓存, 可以考虑 nginx + (service + pod x 1) x n
    UnknownR
        30
    UnknownR  
    OP
       2020-07-31 16:11:30 +08:00
    @sampeng 没错。。。就是硬伤,我们是软件提供商,客户需要 linux 加容器,本来是 windows 软件,现在硬上 k8s,后续开发这边只能开任务做分布式或者无状态
    v2Geeker
        31
    v2Geeker  
       2020-07-31 19:45:21 +08:00
    statefulset 搞定,用 headless service 指定就行了呀~
    dreamusername
        32
    dreamusername  
       2020-08-07 00:36:06 +08:00
    最好的方式肯定是用通用的方式,不要去使用那些不常用的功能。
    流量层面考虑,你可以考虑使用 istio,借助 envoy 可以对流量进行精准的控制,缺点就是对运维的要求很高。
    kiddingU
        33
    kiddingU  
       2020-10-09 15:43:51 +08:00
    上层挂一个 lb,指定节点跑流量
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5134 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 09:27 PVG 17:27 LAX 02:27 JFK 05:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86