知识卡片

动静分离的镜像分层设计:用shell脚本简化Dockerfile,把配置按"何时执行"拆开

普通读书笔记卡

内容

雪球在设计自己的Docker镜像体系时,从Base这一层就贯彻了一条”动静分离”的原则:把配置逻辑明确区分成静态部分(static.sh及相关配置文件)和动态部分(runtime.sh),静态部分在构建base镜像的过程中就被执行完毕、结果固化进镜像本身;动态部分则推迟到project镜像真正启动运行的那一刻才执行,处理那些必须依赖运行时环境信息(比如分配到的IP、Hostname)才能确定的配置。这个拆分背后还有一个具体的工程选择:静态部分的配置逻辑更推荐用灵活的shell脚本来完成,而不是把所有配置逻辑一股脑写进冗长的Dockerfile里——用一个真实对比来说明差异,标准写法把大量RUN指令堆在Dockerfile里会显得笨重难维护,而用shell脚本封装这些配置步骤、Dockerfile里只需要调用这些脚本,可读性和可维护性明显更好。这个设计思路的核心价值在于把镜像构建这个过程,按”什么时候能确定”这个维度拆成了两个独立阶段:能在构建时就确定的配置(不依赖具体运行环境),就应该在构建阶段一次性做完、固化进镜像,减少每次启动都要重复执行的逻辑;必须依赖运行时才能确定的配置,则明确隔离到一个专门的运行时脚本里去处理,不要和构建时逻辑混在一起。这条原则对任何”配置管理”场景都有参考价值:面对一堆配置项,先问清楚每一项”这个值什么时候能确定下来”,能提前确定的尽量提前做、并且固化下来避免重复劳动,只有真正依赖运行时上下文的部分才留到运行时处理。

参考来源

- 位置:《高可用架构(第1卷)》第4章《容器与云计算》"4.2 互联网金融创业公司Docker实践"节,"4.2.3 应用迁移"(源文件:_epub-src/OEBPS/Text/Chapter4_2_4.xhtml) - 结论依据:原文说明"这里做了动静分离,静态的部分(static.sh和对应的件)和动态的部分(runtime.sh)都会被添加进base镜像,静态部分会在构建base镜像过程中被执行,而动态部分会在启动project镜像的过程中被执行……静态部分我们更推荐灵活地使用shell脚本来完成多个基础配置,而不是写冗长的Dockerfile",直接支撑本卡片结论。 - 原始内容:这里做了动静分离,静态的部分(static.sh和对应的件)和动态的部分(runtime.sh)都会被添加进base镜像,静态部分会在构建base镜像过程中被执行,而动态部分会在启动project镜像的过程中被执行……静态部分我们更推荐灵活地使用shell脚本来完成多个基础配置,而不是写冗长的Dockerfile。