Concourse CI:利用docker图像缓存

Max*_*sky 21 docker concourse

我完全理解Concourse是无国籍的,但是有没有办法重新使用已经拉过的docker图像?在我的例子中,我构建了~10个具有相同基本图像的docker图像,但每次构建都被触发Concourse将基本图像拉10次.

是否可以使用标准docker资源将该图像拉一次并在以后重新使用它(至少在同一版本的范围内)?

是的,应该可以使用自定义图像并在sh脚本中编写它,但我不喜欢邀请自行车.

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

--cache-from 没有用,因为CI花费大部分时间来拉动图像,而不是构建新图层.

mat*_*ner 38

理论

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

人们经常谈论Concourse有"缓存",但误解了这意味着什么.每个广播工作者在磁盘上都有一组卷,这些卷留在周围,形成卷缓存.本卷缓存包含已填充的资源量get和put和任务outputs.

人们也经常误解如何docker-image-resource使用Docker.没有全局docker服务器与Concourse安装一起运行,实际上Concourse容器不是Docker容器,它们是runC容器.每一个docker-image-resource过程(check,get,put)是其自身runC容器内运行,这里面有一个本地泊坞窗服务器上运行.这意味着没有全局docker服务器正在拉动docker镜像并缓存这些层以供进一步使用.

这意味着当我们讨论使用docker-image-resource进行缓存时,这意味着将图像加载或预先拉入本地docker服务器.


实践

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

load_base

背景

将load_base您的PARAM docker-image-resource put告诉资源,以第一docker load图像(通过检索get)到本地服务器泊坞窗,前建设通过您指定的图像putPARAMS.

当您需要将图像预先填充到"docker cache"中时,这非常有用.在您的情况下,您需要预加载FROM指令中使用的图像.这样更有效,因为它使用Concourse自己的卷缓存只拉一次"base",使其在执行FROM命令期间可供docker服务器使用.

用法

您可以使用load_base如下:

假设您要构建一个自定义python映像,并且您有一个带有文件的git存储库,ci/Dockerfile如下所示:

FROM ubuntu

RUN apt-get update
RUN apt-get install -y python python-pip
Run Code Online (Sandbox Code Playgroud)

如果您想在利用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
Run Code Online (Sandbox Code Playgroud)

cache & cache_tag

背景

在构建通过put参数指定的图像之前,您的资源中的cache和cache_tagparams docker-image-resource put告诉资源首先从远程源中提取特定图像+标记.

这比从头开始构建图像更容易下拉图像更有用,例如,你有一个很长的构建过程,比如昂贵的编译

这不会利用Concourse的音量缓存,--cache-from并且docker pull在每次使用时都会利用Docker的功能(这需要首先执行a的风险)put.

用法

你可以使用cache和cache_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
Run Code Online (Sandbox Code Playgroud)

如果您想在利用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
Run Code Online (Sandbox Code Playgroud)

建议

如果你想提高建造码头图像的效率,我个人认为load_base应该在大多数情况下使用.因为它使用资源get,所以它利用了Concourse卷缓存,并且避免了需要额外的docker pulls.

  • 这很容易是我在使用concourse构建docker映像时遇到的最有用的信息。谢谢! (2认同)