Dockerfile实践指南之依赖管理

使用Dockerfile进行构建镜像的构建自然而然地会碰到各种依赖,而Dockerfile的本质就是将所有这些依赖构成的版本基线的一个管理,如何更好的管理依赖,当依赖变化的时候,当镜像重构进构建的时候,是否存在多重的管理,这些都是Dockerfile在进行依赖管理时说需要考虑的内容。

基本原则

基本原则1: 稳定性

  • 所有依赖的部分尽可能地需要满足依赖源的稳定性。

基本原则2: 幂等性

  • 镜像构建应能够保持幂等性,多次执行结果结果不会发生变化。

基本原则3: 一致性

  • 避免同一个文件的多处存放导致的不一致性。

注意事项细节说明

注意事项1: 谨慎使用latest

latest是一个变化的tag,不同时间其对应的tag可能是不同的,在使用时要谨慎。FROM指令指定了镜像的来源,如果不是希望实时每次都希望镜像使用最新的基础镜像,则需要慎用latest。比如FROM nginx:latest 每次构建的时候都会使用当时最新版本的nginx基础镜像,所以上述基本原则的稳定性、幂等性和一致性都会得到破坏。
但并非说不能使用latest,这里所有的原则都是希望使用者意识到使用的时候会带来的影响,只要基于此影响进行足够的确认和测试就可以了。

注意事项2: 注意下载内容的源地址

Dockerfile在生成的时候,依赖的基础镜像通过FROM指定,其余部分尽可能的使用wget、curl等命令下载,从而完成,而下载的源则并不一定不会发生变化。很多软件提供的源的下载地址,在新版本推出之后,原本的内容可能会放到归档目录中,所以会导致下载地址的变化,所以会导致原本可以获取的依赖无法下载,从而导致镜像构建的失败。而且有时软件本身也会进行自身调整,比如Maven的如下下载目录,可以看到缺少了3.6.0,之前使用3.6.0的版本的依赖的情况下,此时则会出现问题。
Dockerfile实践指南之依赖管理
所以在使用wget或者curl下载的时候,需要意识到如上问题,尽可能选择不是仅仅显示最新相关版本的下载地址进行下载,从而保证一定时间之后再此构建不会受此问题的影响。

注意事项3: COPY与ADD的本地依赖管理

COPY和ADD命令可以将本地的文件作为镜像构建的内容添加进去,而所添加的内容如何满足基本原则3(一致性)的要求,则是使用者需要考虑的内容。同一个文件尽可能避免在两处或者两处以上进行管理,不然则非常容易发生一致性问题,数据需要同步,每次修改都需要在多个场所保存的内容保持一致性,所以关于COPY和ADD的源的内容进行版本的管理以及一致性的管理,则是本地依赖所需要考虑的内容。

注意事项4: 构建结果管理

虽然进行了各种控制,但是有时还是无法避免出现各种依赖性问题导致无法重新构建镜像。所以建议有条件的情况下还是结合镜像私库管理,保证运维阶段需要的镜像能够在私库中进行保存,此镜像作为Dockerfile所关联版本的实现而存在,在需要的时候至少可以在此镜像上进行进一步的修正和更改。所以每次重构是否需要进行tag的覆盖,则是在实际使用中需要考虑的问题。

总结

总体来说还是建议在Dockerfile中将所有的内容进行管理,基于依赖的复杂程度以及实际需要的时候需要使用不通的Dockerfile名称还是一个Dockerfile来进行管理,在条件允许的情况下,将所有依赖的所有版本都在内部的统一私库中进行管理,这样才能保证镜像在构建的时候不会碰到一致性的问题。