web-dev-qa-db-ja.com

コンコースCI:Dockerイメージキャッシュを活用する

Concourseはステートレスであることを完全に理解していますが、それでも、すでにプルされたDockerイメージを再利用する方法はありますか?私の場合、同じベースイメージを持つ〜10個のDockerイメージをビルドしますが、ビルドがトリガーされるたびに、コンコースはベースイメージを10回プルします。

標準のDockerリソースを使用して、そのイメージを一度プルし、後で(少なくとも同じビルドの範囲内で)再利用することはできますか?

ええ、カスタムイメージを使用してそれを実行し、shスクリプトでコーディングすることは可能ですが、私は自転車を招待するのは好きではありません。

標準のDockerリソースがそれを許可しない場合、なんらかの方法で拡張してそのような動作を有効にすることは可能ですか?

--cache-fromは役に立ちません。CIはほとんどの時間を画像のプルに費やしており、新しいレイヤーを構築していないためです。

22
Max Romanovsky

理論

最初に、いくつかのコンコース理論(少なくともv3.3.1以降):

コンコースには「キャッシュ」があるとよく言われますが、その意味を誤解しています。すべてのコンコースワーカーは、ディスク上に残された一連のボリュームを持ち、ボリュームキャッシュを形成します。このボリュームキャッシュには、リソース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_baseputdocker-image-resourceパラメータは、リソースに、最初に画像(getを介して取得)をローカルDockerサーバーにdocker loadしてbeforeputパラメータで指定された画像を作成します。

これは、「docker cache」に画像を事前入力する必要がある場合に役立ちます。あなたの場合、FROMディレクティブで使用される画像をプリロードする必要があります。 Concourse独自のボリュームキャッシングを使用して「ベース」を一度だけプルし、FROMコマンドの実行中にDockerサーバーで使用できるようにするため、これはより効率的です。

使用法

次のようにload_baseを使用できます。

カスタムpythonイメージを構築する必要があり、次のようにci/Dockerfileファイルを含むgitリポジトリがあるとします。

FROM ubuntu

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

コンコースボリュームキャッシュおよび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

cachecache_tag

バックグラウンド

cache_tagcacheputおよびdocker-image-resource paramsは、リモートソースから特定の画像+タグを最初にpullするようリソースに指示します、beforeputパラメータで指定された画像を構築します。

これは、イメージを最初から作成するよりもプルダウンする方が簡単な場合に便利です。非常にlongビルドプロセス(高価なコンパイルなど)がある

これはしないでください Concourseのボリュームキャッシングを利用し、すべてのputでDockerの--cache-from機能(最初にdocker pullを実行する必要があるリスクを冒す)を利用します。

使用法

次のように、cacheおよびcache_tagを使用できます。

カスタムのRubyイメージをビルドし、ソースからRubyをコンパイルして、ファイルci/Dockerfileとしてgitリポジトリを持っているとします。続く:

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を実行する必要がなくなります。

39