目前业务遇到了比较蛋疼的问题,虽然要上 k8s 但是应用本身不支持 replica,不然会出重复数据 看了一圈发现好像 k8s 不管是 replicaset 还是 hpa 好像都只支持多个 pod 同时 active 然后随机接受流量,请问有什么方法能同时跑多个 pod 但是只让其中一个接受流量,剩下的只是运行状态?类似 DB 的 primary 和 secondary,只有 primary 接受流量,剩下的只要在 primary 挂掉时能及时接上就好。
数据是统一写入数据库的,所以不存在数据差异问题
1 kaikai5601 2020-07-30 20:37:59 +08:00 via iPhone 你就起一个 pod 不就好了 |
![]() | 2 wxsm 2020-07-30 20:39:32 +08:00 via iPhone 就起 1 个,挂掉了会自动重启 |
![]() | 3 UnknownR OP @kaikai5601 但是挂掉时就没法快速切换另一个上。。启动再快也需要时间 |
![]() | 4 wetist 2020-07-30 20:42:11 +08:00 让开发试试分布式锁? |
![]() | 6 wxsm 2020-07-30 20:46:44 +08:00 via iPhone ![]() 提供一个思路:利用 readinessProbe 从节点定时检测主节点是否存活,存活的话该检测提供失败返回,就不会被 k8s 分配流量,同时也不会被杀死。 |
![]() | 8 Reficul 2020-07-30 20:49:40 +08:00 ![]() 用 APIServer 里的资源对象来实现分布式锁,锁释放下一个顶上 |
![]() | 10 jmperdev 2020-07-30 21:00:24 +08:00 可以在负载均衡层考虑 |
![]() | 11 derek80 2020-07-30 23:59:18 +08:00 via iPhone 上 istio |
![]() | 12 derek80 2020-07-31 00:00:29 +08:00 via iPhone 或者在自定义的 ingress controller 层面控制。有已有的实现 |
14 gleymonkey 2020-07-31 01:05:06 +08:00 单节点就是个坑 |
![]() | 15 yisaYisa 2020-07-31 01:18:48 +08:00 ![]() 这个需求其实非常简单也非常普遍。 比如 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 |
![]() | 16 wd 2020-07-31 04:10:15 +08:00 via iPhone 又不要重复数据,也不要当机时间,数据库搞了那么多年你看他们实现了没?你可以掂量掂量自己可以做到什么程度。 |
![]() | 17 zliea 2020-07-31 05:02:16 +08:00 lb+有状态服务? |
18 yuaner 2020-07-31 07:31:21 +08:00 用 istio |
19 haidii 2020-07-31 07:58:03 +08:00 多个 replica 下,可以通过 给 pod 添加标签的方式,根据标签值,让流量只流向其中一个 pod 。 |
20 sampeng 2020-07-31 08:34:25 +08:00 via iPhone 所以一个无服务状态是多么得重要。 |
21 sampeng 2020-07-31 08:36:04 +08:00 via iPhone 那你们上 k8s 的意义是什么?硬上么?不支持多节点就改称支持。哪里有状态就用 redis,数据库等稳定的服务分离状态。硬上 k8s 没收益还带来复杂度 |
  22 sampeng 2020-07-31 08:37:06 +08:00 via iPhone 我们刚上 k8s 的时候也是这样,尤其是定时任务。我一个一个盯着全改成 xxl-job,可以支持了就切 |
![]() | 23 xuanbg 2020-07-31 08:47:24 +08:00 楼主你这个需求叫“热备”,主备热切换,非常古老的可用性方案了。现在流行的可用性方案是无状态的分布式,核心就是不管谁挂,反正流量都是活着的分摊,费效比比热备不知道高哪里去了…… 所以 k8s 在设计的时候根本就没有考虑热备这种古老的需求,这就比较僵硬。不过,办法还是有的。楼主你在 k8s 外面再做一套热备就是了。 |
24 yushiwho 2020-07-31 08:47:37 +08:00 via Android controller 都是这种机制 参考 kuberbuilder |
![]() | 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 再控制流量。 |
![]() | 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 代码里加竞争机制,只有一个可以提供服务。 |
27 Illusionary 2020-07-31 10:07:34 +08:00 单节点要求高可用? 你们的开发水平配不上在运维层面使用 k8s,建议用回单 docker 部署,或者 tomcat 也行嗷 |
28 rushssss 2020-07-31 10:08:11 +08:00 @yisaYisa 这个方案除了不满足 “应该让应用对 k8s 无感知" 这条最佳实践外,几乎是最好的方案,当然就算你不用 k8s 的 api, 也必须要有其他的分布式的,强一致的组件来做协调 |
29 lostsquirrelX 2020-07-31 14:30:58 +08:00 nginx 支持主备,但要注意解析缓存, 可以考虑 nginx + (service + pod x 1) x n |
![]() | 30 UnknownR OP @sampeng 没错。。。就是硬伤,我们是软件提供商,客户需要 linux 加容器,本来是 windows 软件,现在硬上 k8s,后续开发这边只能开任务做分布式或者无状态 |
31 v2Geeker 2020-07-31 19:45:21 +08:00 statefulset 搞定,用 headless service 指定就行了呀~ |
32 dreamusername 2020-08-07 00:36:06 +08:00 最好的方式肯定是用通用的方式,不要去使用那些不常用的功能。 流量层面考虑,你可以考虑使用 istio,借助 envoy 可以对流量进行精准的控制,缺点就是对运维的要求很高。 |
33 kiddingU 2020-10-09 15:43:51 +08:00 上层挂一个 lb,指定节点跑流量 |