Docker のベストプラクティス: タグとラベルを使用して Docker イメージの無秩序な増加を管理する

多くの組織がコンテナベースのワークフローに移行する中、イメージのさまざまなバージョンを追跡することが問題になる可能性があります。 小規模な組織でも、1 回限りの開発テストから、問題を修正するための緊急バリアント、コア プロダクション イメージに至るまで、何百ものコンテナ イメージを持つことができます。 これは、画像の無秩序な増加をどのように抑えながら、画像を急速に反復できるかという問題につながります。

よくある誤解は、「latest」タグを使用することで、画像の「latest バージョンをプルしていることが保証されているというものです。 残念ながら、この仮定は間違っています — 最新の手段はすべて「このレジストリにプッシュされた最後のイメージ」です。

Dockerを使用する際にこの落とし穴を回避する方法と、 Dockerイメージを管理する方法について詳しく知るために読んでください。

Docker のベスト プラクティス: タグとラベルを使用して Docker イメージの無秩序な増加を管理する

タグの使用

この問題に対処する方法の 1 つは、画像の作成時にタグを使用することです。 画像に 1 つ以上のタグを追加すると、その画像の目的を思い出しやすくなり、他のユーザーにも役立ちます。 1 つの方法は、常にイメージにセマンティック バージョニング (semver) でタグを付けることで、デプロイしているバージョンがわかります。 これは素晴らしいアプローチのように聞こえますし、ある程度はそうですが、しわ寄せがあります。

レジストリを不変タグ用に構成していない限り、タグは変更できます。 たとえば、as v1.0.0 にタグmy-great-appを付けて、イメージをレジストリにプッシュできます。ただし、同僚が更新されたバージョンのアプリをタグ v1.0.0 でプッシュするのを止めるものは何もありません。 今、そのタグはあなたのものではなく、彼らのイメージを指しています。 便利なタグ latestを追加すると、物事は少し曖昧になります。

例を見てみましょう。

FROM busybox:stable-glibc

# Create a script that outputs the version
RUN echo -e "#!/bin/sh\n" > /test.sh && \
    echo "echo \"This is version 1.0.0\"" >> /test.sh && \
    chmod +x /test.sh

# Set the entrypoint to run the script
ENTRYPOINT ["/bin/sh", "/test.sh"]

上記を次のように構築します docker build -t tagexample:1.0.0 . そしてそれを実行します。

$ docker run --rm tagexample:1.0.0
This is version 1.0.0

タグを指定せずに実行するとどうなりますか?

$ docker run --rm tagexample
Unable to find image 'tagexample:latest' locally
docker: Error response from daemon: pull access denied for tagexample, repository does not exist or may require 'docker login'.
See 'docker run --help'.

今、私たちはで構築します docker build . タグを指定せずに実行します。

$ docker run --rm tagexample
This is version 1.0.0

タグは latest 、タグが指定されていない最新のプッシュに常に適用されます。 そのため、最初のテストでは、リポジトリに 1 つのイメージがあり、タグ 1.0.0は です。 しかし、タグのないプッシュがなかったため、タグは latest 画像を指していませんでした。 ただし、タグなしで画像をプッシュすると、 latest タグは自動的に適用されます。

常にタグを latest 引っ張りたくなりますが、それが良い考えであることはめったにありません。 論理的な仮定 - これが画像の最新バージョンを指しているという - には欠陥があります。 たとえば、別の開発者がアプリケーションをバージョン 1に更新できます。0。1、 タグ 1.0.1を使用してビルドし、プッシュします。 この結果、次のようになります。

$ docker run --rm tagexample:1.0.1
This is version 1.0.1

$ docker run --rm tagexample:latest
This is version 1.0.0

最も高いバージョンを指していると latest 仮定した場合、イメージの古いバージョンを実行していることになります。

もう1つの問題は、誰かが誤って間違ったタグで押すのを防ぐメカニズムがないことです。 たとえば、コードに別の更新を作成して、 1に上げることができます。0。2。 コードを更新し、イメージをビルドし、プッシュしますが、新しいバージョンを反映するためにタグを変更するのを忘れています。 これは小さな見落としですが、このアクションにより、次のような結果になります。

$ docker run --rm tagexample:1.0.1
This is version 1.0.2

残念ながら、これはあまりにも頻繁に発生します。

ラベルの使用

タグを信頼できないため、画像を識別できることをどのように確認すべきでしょうか? ここで、画像にメタデータを追加するという概念が重要になります。

メタデータを使用して画像を管理する最初の試みは、 MAINTAINER 命令でした。 この命令は、生成された画像の「作成者」フィールド(org.opencontainers.image.authors)を設定します。 ただし、この命令は非推奨となり、より強力な LABEL 命令が優先されました。 とは異なり MAINTAINER、この命令では LABEL 、任意のキーと値のペアを設定してから、他のツールで docker inspect 読み取ることができます。

タグとは異なり、ラベルは画像の一部となり、適切に実装されると、画像のバージョンを判断するためのはるかに優れた方法を提供できます。 上記の例に戻ると、ラベルの使用がどのように違いを生んだかを見てみましょう。

これを行うには、 LABEL 命令を Dockerfile に追加し、キー version と値 1.0.2

FROM busybox:stable-glibc

LABEL version="1.0.2"

# Create a script that outputs the version
RUN echo -e "#!/bin/sh\n" > /test.sh && \
    echo "echo \"This is version 1.0.2\"" >> /test.sh && \
    chmod +x /test.sh

# Set the entrypoint to run the script
ENTRYPOINT ["/bin/sh", "/test.sh"]

さて、上記と同じ間違いを犯した場合でも、誤って画像にバージョン 1としてタグを付けます。0。1、 コンテナを実行して使用しているバージョンを確認することなく確認する方法があります。

$ docker inspect --format='{{json .Config.Labels}}' tagexample:1.0.1
{"version":"1.0.2"}

おすすめの方法

任意のキー/値をとして使用できます LABELが、推奨事項があります。 OCIは、次の表に示すように、org.opencontainers.imageネームスペース内に推奨されるラベルのセットを提供します。

ラベルコンテンツ
org.opencontainers.image.createdイメージが構築された日時 (文字列、RFC 3339 日時)。
org.opencontainers.image.authors画像の責任者または組織の連絡先の詳細 (フリーフォーム文字列)。
org.opencontainers.image.url画像(文字列)の詳細を確認するためのURL。
org.opencontainers.image.documentation画像に関するドキュメントを取得するためのURL(文字列)。
org.opencontainers.image.source画像 (文字列) をビルドするためのソース コードへの URL。
org.opencontainers.image.versionパッケージ・ソフトウェアのバージョン (文字列)。
org.opencontainers.image.revisionイメージのソース管理リビジョン識別子 (文字列)。
org.opencontainers.image.vendor配布エンティティ、組織、または個人の名前 (文字列)。
org.opencontainers.image.licenses含まれているソフトウェアが配布されるライセンス (文字列、SPDX ライセンス リスト)。
org.opencontainers.image.ref.nameターゲットの参照の名前 (文字列)。
org.opencontainers.image.title人間が判読できる画像のタイトル (文字列)。
org.opencontainers.image.descriptionイメージにパッケージ化されたソフトウェアの人間が判読できる説明(文字列)。

任意のキー/値を取るため LABEL 、カスタムラベルを作成することもできます。 たとえば、社内のチームに固有のラベルでは、 com.myorg.myteam 名前空間を使用できます。 これらを特定の名前空間に分離すると、ラベルを作成したチームに簡単に関連付けることができます。

最終的な感想

イメージの無秩序な増加は組織にとって現実的な問題であり、対処しなければ、混乱、やり直し、潜在的な本番環境の問題につながる可能性があります。 タグとラベルを一貫した方法で使用することで、これらの問題を排除し、作業を容易にし、難しくしない、十分に文書化された画像のセットを提供することができます。

さらに詳しく