Kubernetes 设计模式笔记 —— Singleton Service

Singleton Service 模式会保证在某个特定的时间点,有且只有一个应用实例是活跃的。这个模式可以在应用内部实现,也可以完全交给 Kubernetes 去处理。

Kubernetes 最大的优势之一就是能够轻松、透明地扩展应用,只需要一条命令式的语句 kubectl scale 就能伸缩 Pod,或者通过声明式的方式修改 controller(比如 ReplicaSet)定义来实现,甚至基于应用负载动态地完成应用扩展。
在 Kubernetes 中,多实例指的就是 Pod 的多个副本,能够提升应用的吞吐量和可用性,Service 则负责分配请求。

但是在一些特殊的场景中,同一时间只允许唯一一个应用实例运行。比如某个周期性执行的定时任务,若存在该任务的多个实例同时运行,则其中每一个实例都会在规定的时间间隔后触发一次该任务,导致预期之外的重复执行。
另一个例子比如,某个应用服务需要轮询特定的系统资源(文件系统或数据库等),我们想要确保只有一个应用实例甚至只有一个线程在执行这类操作。
还比如,我们必须按照特定的顺序消费来自消息代理的消息时,这里的单线程消费者也是一种单例。

运行同一个 Pod 实例的多个副本并令它们同时处于活跃状态,属于 active-active 拓扑结构,单例模式需要的是 active-possive(或者叫做 master-slave)结构。即只有一个实例是活跃的,其他所有的实例都是被动的,等待需要的时候被唤醒。

Out-of-Application Locking

顾名思义,通过外部的管理程序确保应用只有唯一一个实例在运行,应用本身并不知晓自己是否是单例。
Out-of-application locking mechanism

Kubernetes 实现单例模式的方式是,启动一个副本唯一的 Pod,但这并不能确保 Pod 是高可用的。因此还必须通过控制器(比如 ReplicaSet)来管理单例,令其具备高可用的能力。
这种结构严格来说并不是 active-passive (没有配置 passive 实例)的,但是具有同样的效果。Kubernetes 会确保任何时候都会有一个 Pod 实例在运行,控制器会持续进行健康检查,修复失败的 Pod。

最需要额外注意的是副本数量,避免意外地被修改成大于 1 的值。事实上任何时候都只有唯一的应用实例在运行的说法不是完全准确的。Kubernetes 中的组件比如 ReplicaSet,会优先考虑可用性而非一致性。这意味着对于副本数量来说,ReplicaSet 会实行至少一个而不是最多一个的策略。在某些特殊的情况下,即便有 replicas: 1 的配置,也会出现多个实例同时在运行的情况。
最常见的情形比如当某个节点失效时,与整个 Kubernetes 集群的连接丢失,ReplicaSet 控制器就会在另一个健康的节点上创建一个新的 Pod 实例,并且不会提前确认断连的节点上的原 Pod 是否已经关闭。类似的情况也会在修改副本数量或者将 Pod 重新分配给另一个节点时出现。

单例模式可以具有弹性和恢复能力,但是从定义来看,并不具备高可用性。它通常更倾向于一致性而非可用性。同样更倾向于一致性的 Kubernetes 资源是 StatefulSet。如果需要严格意义上的单例模式,StatefulSet 是更好的选择,但是它同样会增加系统的复杂度。

In-Application Locking

在分布式环境中,控制服务实例数量的一种方式就是分布式锁。当实例中的服务组件被激活时,它会尝试获取一个锁,成功获取到锁则服务处于活跃状态。此时任何其他未获取到锁的服务实例则等待并不断地尝试获取锁,直到占用的锁被释放。


In-application locking mechanism

在面向对象的概念中,单例就是一个保存在类的静态变量中的对象实例。类本身知晓该实例是单例,并且在定义中不允许为同一个进程实例化多个实例。
在分布式系统中,就意味着容器化应用本身在设计上,就不允许同一时间下有多于一个的实例处于活跃状态,不管实际上启动了多少个 Pod。上述实现需要借助分布式锁,比如 ZooKeeper,Consul,Redis 或 Etcd 等。

结论

如果使用场景需要强 singleton 保证,就不能借助 ReplicaSet 实现的应用外部的锁机制。ReplicaSet 的设计目标在于保证 Pod 的可用性而不是满足 at-most-one 语义。会有很多错误场景,同一个 Pod 的两个副本短时间内并发地运行。
若上述情况是不可接受的,则可以使用 StatefulSet 或者引入应用内的锁机制。
在另外一些场景中,只有容器化应用的一部分是需要作为 singleton 运行的。比如一个容器化应用提供 HTTP 服务(能够安全地扩展),同时还包含必须是 singleton 的轮询组件。这时候使用应用外部的锁机制,会阻止整个应用被扩展。我们因此必须将 singleton 组件从原本的部署中分离出来。
或者借助应用内的锁机制,只对 singleton 组件加锁。此时就可以透明地扩展整个应用,多个 HTTP 服务副本提供访问,singleton 组件则以 active-passive 模式运行。

参考资料

Kubernetes Patterns

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容