-
背景A,B是两个CR,b是B的controller,d,e是两个独立的controller,绿色是controller,蓝色是CR 目的:最后e 正确print出B中存储的值,置0操作也能执行成功 流程: 预先情况:A=0,B=0 1、d给A+100,A=100 2、b要做两个事情,先读取出A的值100,再把A置0,根据A的值b计算出 3、e读取出B中的值,并且把B置0,e打印出5。 问题可能会产生问题的场景 预先情况:A=0,B=5 本质:在一个 controller 里面要给aCR-100,给bCR+100,在这期间还会有人更新aCR,更新bCR,在controller里无法做到幂等,CRD里面没有锁概念和事务,比较难搞。 解决办法1b在更新A和B两个CR的时候,使用retry,b 更新 A CR失败的时候重新get A再 更新,b 更新 B CR失败的时候重新get B再更新。 缺点:retry大概率成功,但是理论上有一定概率失败,然后就会发生上面的问题。 解决办法2原则:一个CR只有一个controller更新原则下方法1:创造一个Kind叫ResourceUsed的 CR,这个CR由d或者e生成,来告诉b要对A或者B有什么字段要更新优点:无需添加第三方组件,使用CRD原生方式解决 缺点:会产生大量的resourceUsed的CR,给etcd造成大量压力 原则下方法2:跟方法2一样,不一样的地方是b 处理完action的操作之后把resourceUsed删除掉优点:无需添加第三方组件,产生可接受数量的resourceUsed CR 缺点:无法做到幂等,如果creare 了一个resourceUsed 的CR,b处理完了,但是d create之后挂掉了,又重新reconcile create了一个resurceUsed CR,这时候b会再处理一遍,无法做到幂等。 原则下方法3:d和e通过消息队列告诉b要对A和B什么操作缺点:k8s中无消息队列,如果使用的话得引入第三方组件。 优点:不会给etcd产生大量压力,kafka有幂等 解决办法3通过分布式锁,修改CR前先去分布式锁组件看看有没有其他人在修改 优点:理解简单,代码不难写 缺点:得引入第三方组件,会增加复杂度,会因为等待锁释放而浪费大量时间,CRD reconcile好像也不怎么适合这种模式。 各个解决办法都有点缺点,可以讨论一下哪个方法适合解决在CRD里面的这种问题? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
https://zhuanlan.zhihu.com/p/402061389 主要是这个原因造成的,先了解原理~ |
Beta Was this translation helpful? Give feedback.
https://zhuanlan.zhihu.com/p/402061389 主要是这个原因造成的,先了解原理~