【问题标题】:Concourse CI: leverage docker image cacheConcourse CI:利用 docker 图像缓存
【发布时间】:2017-06-10 15:41:57
【问题描述】:

我完全理解 Concourse 是无状态的,但是有没有办法重用已经拉取的 docker 镜像? 就我而言,我构建了大约 10 个具有相同基础镜像的 docker 镜像,但每次触发构建时,Concourse 都会拉取基础镜像 10 次。

是否可以使用标准 docker 资源提取该图像一次并在以后重新使用它(至少在同一构建范围内)?

是的,应该可以使用自定义图像并在 sh 脚本中对其进行编码,但我不喜欢邀请自行车。

如果标准 docker 资源不允许这样做,是否可以以某种方式扩展它以启用此类行为?

--cache-from 没有帮助,因为 CI 大部分时间都在提取图像,而不是构建新层。

【问题讨论】:

  • 嗨,我对问题所在感到有点困惑......如果您将该基本图像存储为资源,那么大厅应该缓存它并使用缓存的图像来构建您的新图像。
  • @JoshZarrabi 我不将其存储为资源,因为它仅在 Dockerfile's FROM 声明中引用

标签: docker concourse


【解决方案1】:

理论

首先,一些 Concourse 理论(至少从 v3.3.1 开始):

人们经常谈论 Concourse 有一个“缓存”,但误解了它的含义。每个大厅工作人员在磁盘上都有一组卷,这些卷留在周围,形成一个卷缓存。此卷缓存包含已由资源 getput 以及任务 outputs 填充的卷。

人们也经常误解docker-image-resource 是如何使用 Docker 的。您的 Concourse 安装没有运行全局 docker 服务器,实际上 Concourse 容器不是 Docker 容器,它们是 runC 容器。每个docker-image-resource 进程(checkgetput)都在自己的 runC 容器内运行,其中运行着一个本地 docker 服务器。这意味着没有全局 docker 服务器正在拉取 docker 图像并缓存层以供进一步使用。

这意味着当我们谈论使用 docker-image-resource 进行缓存时,它意味着将图像加载或预拉到本地 docker 服务器中。


练习

现在是优化构建时间的选项:

load_base

背景

load_base 中的 load_base 参数告诉资源首先将 docker load 图像(通过 get 检索)到其本地 docker 服务器,在构建之前通过您的 put 参数指定的图像。

当您需要将图像预填充到“docker 缓存”中时,这很有用。在您的情况下,您可能希望预加载 FROM 指令中使用的图像。这更有效,因为它使用 Concourse 自己的卷缓存仅拉取“基础”一次,使其在执行 FROM 命令期间可供 docker 服务器使用。

用法

您可以按如下方式使用load_base

假设你想构建一个自定义的 python 镜像,并且你有一个 git 存储库,其中包含一个文件 ci/Dockerfile,如下所示:

FROM ubuntu

RUN apt-get update
RUN apt-get install -y python python-pip

如果您想在利用 Concourse 卷缓存 以及 Docker 映像层缓存 的同时自动构建/推送此映像:

resources:
- name: ubuntu
  type: docker-image
  source:
    repository: ubuntu

- name: python-image
  type: docker-image
  source:
    repository: mydocker/python

- name: repo
  type: git
  source:
    uri: ...

jobs:
- name: build-image-from-base
  plan:
  - get: repo
  - get: ubuntu
    params: {save: true}
  - put: python-image
    params:
      load_base: ubuntu
      dockerfile: repo/ci/Dockerfile

cache & cache_tag

背景

docker-image-resourceput 中的 cachecache_tag 参数告诉资源首先从远程源特定图像+标签,之前 构建通过你的 put 参数指定的图像。

当下拉图像比从头构建图像更容易时,这很有用,例如您的构建过程非常漫长,例如昂贵的编译

利用 Concourse 的卷缓存,并在每个 put 期间利用 Docker 的 --cache-from 功能(存在需要首先执行 docker pull 的风险)。

用法

您可以使用cachecache_tag,如下所示:

假设你想构建一个自定义的 ruby​​ 镜像,从源代码编译 ruby​​,并且你有一个 git 存储库,其中包含一个文件 ci/Dockerfile,如下所示:

FROM ubuntu

# Install Ruby
RUN mkdir /tmp/ruby;\
  cd /tmp/ruby;\
  curl ftp://ftp.ruby-lang.org/pub/ruby/2.0/ruby-2.0.0-p247.tar.gz | tar xz;\
  cd ruby-2.0.0-p247;\
  chmod +x configure;\
  ./configure --disable-install-rdoc;\
  make;\
  make install;\
  gem install bundler --no-ri --no-rdoc

RUN gem install nokogiri

如果您想自动构建/推送此映像,同时仅利用 Docker 映像层缓存

resources: 
- name: compiled-ruby-image
  type: docker-image
  source:
    repository: mydocker/ruby
    tag: 2.0.0-compiled

- name: repo
  type: git
  source:
    uri: ...

jobs:
- name: build-image-from-cache
  plan:
  - get: repo
  - put: compiled-ruby-image
    params:
      dockerfile: repo/ci/Dockerfile
      cache: mydocker/ruby
      cache_tag: 2.0.0-compiled

推荐

如果你想提高构建 docker 镜像的效率,我个人认为大部分情况下应该使用load_base。因为它使用资源get,所以它利用了Concourse 卷缓存,并且避免了需要做额外的docker pulls。

【讨论】:

  • 感谢您的详细回答,很遗憾,我将无法在接下来的几周内查看它。
  • 经过测试,效果很好。如果工作人员上不存在图像,则在使用 skip_download 时避免使用 file not found error。要求在输入 Docker 映像资源的 get 上设置 params: {save:true}
  • 我编辑添加save: true,否则管道失败,open ubuntu/image: no such file or directory
  • 此大厅资源陈旧、混乱且粗鲁。注意当前重写/重新设计的工作:github.com/concourse/docker-image-resource/issues/190
  • 这是我在使用 concourse 构建 docker 镜像时遇到的最有用的信息。谢谢!
猜你喜欢
  • 1970-01-01
  • 2022-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 1970-01-01
相关资源
最近更新 更多