Gemfile包含了需要安装的gem,同时Gemfile.lock用来管理依赖关系链。通过把这些文件缓存在/tmp目录,只有当Gemfile发生变更时,bundle install命令才会被执行。如果Gemfile没有发生变更,它会使用缓存里的文件。这个缓存很有用,因为安装gem是一个很耗时的任务,还会占用很多带宽。
run命令跨了很多行,只有一个层会被添加到镜像里,这个层包含了apk和gem包。构建包是作为虚拟包被添加进去的,在安装完毕之后它们可以很容易被移除。
更新:编译过的二进制仍然可能是不安全的
移除构建依赖会为我们带来一些好处,不过为了gem的扩展,镜像里仍然会存留一个二进制包。这个二进制包很难被扫描器发现,所以它或许仍然是一个会暴露薄弱点的地方。
所以,对这个二进制包进行安全检查是必要的。对于Nokogiri来说,我们使用了1.6.8版本,这个版本包含了最新的libxml和libxslt安全补丁。不过这些包的CVE元数据可能存在一个问题,我已经向Docker安全扫描团队反馈过这个问题。
自动构建
关于容器安全很关键的一点是,当镜像或基础镜像有安全方面的更新时,需要对镜像进行重新构建。镜像被关联到Git仓库,所以自动构建会让整个过程变得很容易。当仓库分支上有新的提交时,如果我们对其进行了跟踪,那么一个构建就会被触发。在之前的例子里我们已经看到,当基础镜像发生变更时也会自动触发构建。
我们的Ruby镜像自动构建会简单一些,因为自动构建可以直接使用本地的Dockerfile。不过我们的Go镜像就麻烦一些,因为在把二进制包加入镜像之前需要先通过编译,我们通过使用本地的makefile来完成编译。
我们可以使用钩子来进行自动构建,并使用Docker容器来编译二进制包。来自CenturyLinkLabs和Prometheus的Go语言构建器镜像都是很不错的选择。
可以通过钩子来调用这些构建器镜像。我们也可以使用钩子往镜像里添加动态的元数据,就像我最近在里所说的那样。
我无法覆盖视频里所提到的所有主题,所以如果有可能,大家可以自己去看视频。最后我想说的是,我们在MicroBadger里添加了对私有仓库的支持,所以你们可以为Docker Hub上的私有仓库使用通知。
查看英文原文: