web-dev-qa-db-ja.com

すべてのビルドステップでレジストリからのキャッシュを使用するようにDockerを設定する方法

Dockerを備えた2台のサーバーと、プライベートレジストリを備えた1台のサーバーがあります。

最初のマシンでDockerfileをビルドしました。次に、イメージをレジストリにプッシュしました。

レジストリのキャッシュを使用して、2台目のマシンでDockerfileをすぐに構築できますか?いいえの場合、独自のキャッシュを作成せずに「ほぼ」同じDockerfileの構築を高速化する方法はありますか?

セットアップしようとしました--registry-mirrorしかし、それは役に立ちませんでした。

17
SerCe

docker> 1.10の場合、この問題について何かを見つけました: https://github.com/docker/docker/issues/20316#issuecomment-221289631

このDockerfileを考えると

_FROM busybox
RUN mkdir this-is-a-test
RUN echo "hello world"
_

_docker build -t caching-test ._を実行します

次に、_docker history caching-test_で画像を構成するレイヤーを確認できます

_3e4a484f0e67        About an hour ago   /bin/sh -c echo "Hello world!"                  0 B                 
6258cdec0c4b        About an hour ago   /bin/sh -c mkdir this-is-a-test                 0 B                 
47bcc53f74dc        9 weeks ago         /bin/sh -c #(nop) CMD ["sh"]                    0 B                 
<missing>           9 weeks ago         /bin/sh -c #(nop) ADD file:47ca6e777c36a4cfff   1.113 MB  
_

1.11での保存/読み込みの変更により、親レイヤーと子レイヤーの関係が保持されますが、Dockerを使用して一緒に保存された場合に限ります。 _docker inspect test | grep Parent._を実行すると、最終テストイメージの親を確認できます

_$ docker inspect caching-test | grep Parent
"Parent": "sha256:6258cdec0c4bef5e5627f301b541555883e6c4b385d0798a7763cb191168ce09", 
_

これは、Docker履歴出力の2番目から2番目のレイヤーです。

保存と読み込みを使用してキャッシュを再作成するには、親として参照されているすべての画像とレイヤーを保存する必要があります。実際には、これは通常、同じコマンドで各レイヤーとFROMイメージを保存する必要があることを意味します。

_docker save caching-test 6258cdec0c4b busybox > caching-test.tar_- saveコマンドにIDの代わりにレイヤー名を付けることもできることに注意してください。

すべてを削除してから、tarファイルからイメージをリロードします。 docker rmi $(docker images -q)。画像が存在しないことを確認してください。

次に_docker load -i caching-test.tar_を実行します。画像を見ると、busyboxが表示され、次にcache-testが表示されます。 _docker history caching-test_を実行すると、イメージが最初に作成されたときとまったく同じ出力が表示されます。これは、親子関係が保存と読み込みによって保持されていたためです。 _docker inspect caching-test | grep Parent_を実行して、親レイヤーとして指定されたものとまったく同じIDを確認することもできます。

また、同じDockerfileの再構築を実行すると、キャッシュが使用されていることがわかります。

_Sending build context to Docker daemon 5.391 MB
Step 1 : FROM busybox
 ---> 47bcc53f74dc
Step 2 : RUN mkdir this-is-a-test
 ---> Using cache
 ---> 6258cdec0c4b
Step 3 : RUN echo "hello world"
 ---> Using cache
 ---> 3e4a484f0e67
Successfully built 3e4a484f0e67
_

編集:これの下でのみ機能しますdocker 1.10より前

2番目のマシンでは、新しいマシンを構築する前に_docker pull theimagefromthefirstdockerfileontheregistry_できます。

そうすれば、すべてのレイヤーが2番目のマシンに存在することを確認できます。

Docker-engineは、レイヤーが構築されるたびにレジストリにクエリを実行しません(それを認識していません)。速度が遅すぎたり重すぎたりするため、別の方法があるとは思いません。

12
michael_bitard

注: issue 20316( "Pulling build cache") は、 PR 26839( "Implement build cache based on history array") がマージされたため、クローズされました。

たとえば、以前のCIビルドのイメージを--cache-fromで指定できます。

ビルド時にキャッシュソースとして使用されるイメージを指定する機能を追加します。これらのイメージは、ローカルの親チェーンを持つ必要はなく、他のレジストリから取得できます。ユーザーは、信頼できる画像のみをソースとして使用するようにする必要があります。

使用法:

docker pull myimage:v1.0
docker build --cache-from myimage:v1.0 -t myimage:v1.1 .

docker 1.13(January 2017) については merge commit 794448 を参照してください。

コメントどおり by javipolo

私のように誰かがレイヤーを再利用することに夢中になっている場合、「トリック」は、再構築している(そしてすでにプルされている)イメージを--cache-fromに渡し、またFROMのベースとして使用する画像。

例:
Dockerfile for image custom-gource:0.1

FROM base_image:2.2.1
RUN apt-get update && apt-get install gource
COPY myscript.sh /myscript.sh

apt-getを再度実行せずに他のホストで再構築するには、次のことを行う必要があります。

docker pull custom-gource:0.1
docker build --cache-from=base_image:2.2.1,custom-gource:0.1 . -t custom-gource:0.2

当たり前のように思えるかもしれませんが、ベースイメージも含める必要があることがわかるまで、私はこれに長い間苦労してきました。

27
VonC

Dockerバージョン> = 19.03の場合、新しいBuildKit機能を使用して、ビルドする前にリモートイメージをプルする必要をなくすことができます。 DOCKER_BUILDKIT環境変数を設定してBuildKitをアクティブにし、インラインキャッシュをオンにして、次のようにBUILDKIT_INLINE_CACHEビルド引数を使用してビルドキャッシュをイメージとともにレジストリに保存します。

export DOCKER_BUILDKIT=1
docker build -t registry/imagename:tag --cache-from registry/imagename:tag --build-arg BUILDKIT_INLINE_CACHE=1 .
docker Push registry/imagename:tag

このソリューションを提供してくれた Nicholas Dille に感謝します。

4
Jeff