知识卡片

用Docker Daemon Label解耦元数据与调度,但暴露出"改元数据必须重启"的硬伤

普通读书笔记卡

内容

调度算法要根据每台实例的具体情况(属于哪个云服务商、IP是什么、归属哪个业务、扮演什么角色)来筛选资源,微博团队选择用Docker Daemon的Label机制来记录这些元数据(比如--label IDC=$provider记录云服务提供商、--label srv=$srv记录所属业务),而不是把这些信息硬编码进调度系统本身。这个设计的好处是让”资源信息”和”调度逻辑”实现了解耦——调度系统只需要读取Daemon暴露出来的Label,不需要关心这些元数据具体是怎么维护和更新的,两者可以独立演进。但这个方案随着规模化使用,暴露出Docker Daemon本身一个明显的架构短板:任何元数据的改变都需要重启整个Daemon才能生效,这在生产环境是相当高的代价——一个实例的归属信息、角色标签只是发生了变化,却要为此重启整个容器运行时,影响面被不成比例地放大了。团队针对这个短板采取的应对是:一方面计划把元数据管理从Daemon本身挪到自己的系统里去维护(不再依赖Daemon Label作为元数据的最终来源),另一方面也向Docker社区反馈这个问题、尝试推动动态修改Label的能力,但社区对是否要支持这种动态修改API的态度比较纠结,相关PR被拒绝。这个案例提示了一条评估基础设施组件设计的经验:一个组件某个字段”支持配置”,不等于它”支持动态修改配置”,这两者在实际运维场景下的代价可能天差地别——选择依赖某个组件的元数据机制之前,需要具体确认这个元数据一旦需要变更,代价是轻量的热更新,还是像这里一样要付出重启整个运行时的重量级代价,这个差异会直接决定它是否真的适合被用作频繁变化的动态信息的载体。

参考来源

- 位置:《高可用架构(第1卷)》第4章《容器与云计算》"4.1 微博基于Docker容器的混合云迁移实战"节,"4.1.2 跨云的资源管理与调度"(源文件:_epub-src/OEBPS/Text/Chapter4_1_3.xhtml) - 结论依据:原文说明"这部分信息目前是通过 Docker Daemon的Label实现的,这样做的好处是资源和调度可以Docker Daemon解耦……目前Docker Daemon最大的硬伤是任何元数据的改变都需要重启。所以我们计划把元数据从移到我们的系统中,同时尝试向社区反馈这个问题……PR被拒",直接支撑本卡片结论。 - 原始内容:这部分信息目前是通过 Docker Daemon的Label实现的,这样做的好处是资源和调度可以Docker Daemon解耦……目前Docker Daemon最大的硬伤是任何元数据的改变都需要重启。所以我们计划把元数据从移到我们的系统中,同时尝试向社区反馈这个问题,比如动态修改 Docker Daemon Label的接口(PR被拒)。