DUICUO

この記事ではDockerイメージの分析について詳しく説明します

[[429016]]

著者: ジョック

WeChat公式アカウント:運営と開発のストーリー

ジーフー:チャオおじさん

皆さんこんにちは。私は最前線の運用と保守の実務者である Qiao Ke です。

YAML エンジニアにとって、イメージは馴染み深いものであり、彼らはイメージの作成、構築、デプロイという反復的でありながら興味深いプロセスを毎日行っています。

イメージをビルドするためのDockerfileを一度書いたら、アプリケーションが正常に動作する限り、それを再度見直すことはほとんどありません(少なくとも私はそうです)。それが想像通り合理的かどうか、あるいはさらに最適化できるかどうかなど、深く考えることはありません。

この記事では、以下の側面からミラーリングをより深く理解できるようにします。

ミラーリングの基本概念

何かを学ぶとき、最初に頭に浮かぶ疑問は「それって何?」です。Dockerイメージについて学ぶときも同じことが当てはまります。Dockerイメージとは何でしょうか?

Docker イメージについて説明する前に、Linux ファイル システムについて簡単に説明しましょう。

一般的な Linux ファイル システムは、bootfs と rootfs で構成されます。bootfs はカーネルがメモリにロードした後にアンマウントされるため、システムに入ると表示されるのは、/etc、/prod、/bin などの標準ディレクトリなどの rootfs です。

Dockerイメージはルートファイルシステム(FS)と考えることができます。これにより、Dockerイメージとは何かをより明確に理解できます。例えば、公式のubuntu:21.10イメージには、カーネルは含まれていませんが、ubuntu:21.10の最小システムの完全なルートファイルシステムが含まれています。

Dockerイメージは、コンテナの実行に必要なプログラム、ライブラリ、リソース、設定、ランタイムパラメータを提供する特別なファイルシステムです。その最終的な目的は、コンテナ内でコードを実行できるようにすることです。

上記はDockerイメージとは何かというマクロレベルの視点を示しています。では、ミクロレベルの視点からさらに深く掘り下げてみましょう。例えば、`ubuntu:21.10`イメージしかないとします。`nginx`イメージが必要な場合、このイメージに`nginx`をインストールするだけで、`nginx`イメージに変換できるでしょうか?

答えは「はい」です。ここでは階層構造の概念が関わっています。最下層ではUbuntuイメージを使用し、その上にNginxイメージが階層化されて、Nginxイメージの構築が完了します。この場合、UbuntuイメージをNginxの親イメージと呼びます。

最初は少しわかりにくいかもしれませんが、次のミラー保存方法の説明を読めば理解しやすくなります。

ミラー保存方式

ミラーの保存方法について説明する前に、UnionFS (Union File System) について簡単に紹介します。

UnionFSは、異なる物理的な場所にあるディレクトリを単一の仮想ファイルシステムに統合します。典型的な用途としては、CD/DVDとハードドライブ上のディレクトリを一緒にマウントし、ユーザーが読み取り専用のCD/DVDを変更できるようにすることが挙げられます。

DockerはUnionFSテクノロジーを最大限に活用して、階層化ストレージ用のイメージを設計します。現在使用されているファイルシステムはOverlayFSで、これはUnionFSの多くのファイルの一つです。

OverlayFS には、下位層と上位層の 2 つの層しかありません。名前の通り、上位層は最上位にあり、下位層はその下に位置し、上位層は下位層よりも優先度が高くなります。

mount を使用してオーバーレイ ファイル システムをマウントする場合は、次の規則に従ってください。

  • 下位ディレクトリと上位ディレクトリの両方に同じ名前のファイルが存在する場合、下位ディレクトリのファイルは非表示になり、ユーザーは上位ディレクトリのファイルのみを表示できます。
  • 同じディレクトリ内の同じ名前のファイルで優先度が低いものは非表示になります。
  • 同じ名前のディレクトリが存在する場合、下位ディレクトリと上位ディレクトリの内容が結合されます。
  • ユーザーが merge で upper からデータを変更すると、そのデータは upper の元のディレクトリに直接書き込まれます。ファイルが削除された場合も同様です。
  • ユーザーがマージ時に下位パーティションのデータを変更した場合、下位パーティションの内容は変更されません。下位パーティションは読み取り専用であるため、ユーザーが下位パーティションのデータを変更したい場合、overlayfs はまず下位パーティションから上位パーティションにファイルのコピーをコピーします。その後の変更または削除は上位パーティションのコピーに対して行われ、下位パーティションの元のファイルは非表示になります。
  • ディレクトリが `lower` のみから派生している場合、または `lower` と `upper` が結合されている場合、`rename` システムコールはデフォルトではサポートされません。ただし、`mv` を使用して名前を変更することは可能です。名前変更をサポートするには、`CONFIG_OVERLAY_FS_REDIRECT_DIR` が必要です。

OverlayFS を例に挙げて、このファイルシステムの効果を直接体験してみましょう。

システム: CentOS 7.9 カーネル: 3.10.0

(1)lower、upper、merge、workの2つのディレクトリを作成します。

  1. # # mkdir下位 アッパー 作業マージ

で:

  • 下位ディレクトリは下位層のファイルを保存するために使用されます。
  • 上位ディレクトリは上位層のファイルを保存するために使用されます。
  • 作業ディレクトリは、一時ファイルまたは間接ファイルを保存するために使用されます。
  • マージ ディレクトリはマウント ディレクトリです。

(2)以下のように、下位ディレクトリと上位ディレクトリの両方にファイルを配置します。

  1. # echo "下層から。" >下層/common-file
  2. # echo "上層から。" >上層/common-file
  3. # echo "lowerから。" > lower / lower -file
  4. # echo "上層から。" > upper / upper -file
  5. # 木
  6. ├── 
  7. │ ├── 共通ファイル
  8. │ └──ファイル
  9. ├── マージ
  10. ├── 
  11. │ ├── 共通ファイル
  12. │ └──ファイル
  13. └──仕事 

下位ディレクトリと上位ディレクトリに同じ名前 (common-file) のファイルがありますが、その内容は異なることがわかります。

(3)以下のコマンドを使用して、これら2つのディレクトリをマウントします。

  1. # mount -t overlay -o lowerdir=、upperdir=、workdir=作業オーバーレイ マージ

実装結果は以下の通りです。

  1. # 木
  2. ├── 
  3. │ ├── 共通ファイル
  4. │ └──ファイル
  5. ├── マージ
  6. │ ├── 共通ファイル
  7. │ ├──ファイル
  8. │ └──ファイル
  9. ├── 
  10. │ ├── 共通ファイル
  11. │ └──ファイル
  12. └──仕事 
  13. └──仕事 
  14. # cat マージ/共通ファイル
  15. から 上部

ご覧のとおり、common-dir ディレクトリの内容がマージされ、重複したファイル common-file は uppderdir 内の common-file になっています。

(4)マージディレクトリにファイルを作成し、結果を確認します。

  1. # echo "マージからファイルを追加" > merge/merge-file
  2. # 木
  3. ├── 
  4. │ ├── 共通ファイル
  5. │ └──ファイル
  6. ├── マージ
  7. │ ├── 共通ファイル
  8. │ ├──ファイル
  9. │ ├── マージファイル
  10. │ └──ファイル
  11. ├── 
  12. │ ├── 共通ファイル
  13. │ ├── マージファイル
  14. │ └──ファイル
  15. └──仕事 
  16. └──仕事 

ご覧のとおり、下の層は変更されずに、新しく追加されたファイルが上の層に追加されます。

(5)マージレイヤーの下位ファイルを以下のように修正します。

  1. # echo "マージから下位ファイルを更新する" > merge/ lower -file
  2. # 木
  3. ├── 
  4. │ ├── 共通ファイル
  5. │ └──ファイル
  6. ├── マージ
  7. │ ├── 共通ファイル
  8. │ ├──ファイル
  9. │ ├── マージファイル
  10. │ └──ファイル
  11. ├── 
  12. │ ├── 共通ファイル
  13. │ ├──ファイル
  14. │ ├── マージファイル
  15. │ └──ファイル
  16. └──仕事 
  17. └──仕事 
  18.  
  19. # cat上位/下位ファイル
  20. アップデート マージからの下位ファイル
  21. # cat lower / lower -file
  22. から より低い

ご覧のとおり、下層は変更されず、すべての変更は上層で行われます。

上記の実験は、興味深い点を明らかにしています。それは、上層がどのように変化しても、下層は同じままであるということです。

Dockerイメージはユニオンファイルシステムを採用しています。イメージをビルドする際、レイヤーは互いに積み重ねられます。各レイヤーは一度ビルドされると、変更されません。後続のレイヤーへの変更は、そのレイヤーのみに影響し、前のレイヤーには影響しません。

下の画像のように、例を使ってこれを説明しましょう。

具体的には次のようになります。

  • 基本 L1 レイヤーには、file1 と file2 の 2 つのファイルがあり、両方のファイルに特定のコンテンツが含まれています。
  • L2レベルに到達すると、file2の内容を変更し、file3を追加する必要があります。file2を変更する際、システムはまずL1レベルにファイルが存在するかどうかを確認します。上図に示すように、file2はL1レベルに存在します。この時点で、file2はL2レベルにコピーされ、その後、L2レベルのfile2が変更されます。これは、ユニオンファイルシステムのコピーオンライトメカニズムの使用です。新しいファイルを追加する場合も同様です。
  • L3 レベルで file3 を変更する場合、コピーオンライト メカニズムを使用して、file3 を L2 レベルから L3 レベルにコピーしてから変更します。
  • すると、ビュー レイヤーに表示される file1、file2、file3 はすべて最新のファイルになります。

上記のイメージレイヤーは静的です。コンテナを実行すると、Dockerデーモンはコンテナ内のファイルを変更するための読み書きレイヤーも動的に生成します(下図参照)。

例えば、file2 を変更したい場合、コピーオンライト機構を使って file2 を読み書きレイヤーにコピーし、その後変更を加えます。同様に、コンテナの実行中はビューが存在します。コンテナを停止するとビューレイヤーは消えますが、読み書きレイヤーは保持されます。コンテナを再起動すると、以前の変更内容を確認できます。

ファイルを削除しても、実際には削除されるわけではなく、削除済みとしてマークされて非表示になるだけなので、ご注意ください。ファイルは見えなくなりますが、画像上には引き続き表示されます。

これで、階層化イメージストレージの基本を理解できました。この階層化ストレージは、記事の冒頭で紹介したUbuntuをベースにカスタマイズされたnginxイメージのように、イメージの再利用とカスタマイズを容易にします。

Dockerfileとイメージの関係

アプリケーションコードにDockerfileを記述してイメージを作成することがよくありますが、Dockerfileとイメージの関係は一体何でしょうか?Dockerfileがなくてもイメージを作成することはできるのでしょうか?

まず、単純な Dockerfile がどのようなものかを見てみましょう。

  1. ubuntu:latestから
  2. 追加run.sh /
  3. ボリューム/データ
  4. コマンド [ "./run.sh" ]

これらのコマンドを使用して新しいイメージを作成できますか?

はい、これらのコマンドをファイルにまとめることで、Dockerはそれを使って新しいイメージを作成できます。これは、レモン、氷砂糖、スイカズラを用意すればレモンティーが作れるのと少し似ていると思いませんか?

この接続を行うと、Dockerfile とイメージの関係が明確になります。

Dockerfileは原材料であり、イメージは私たちが求める成果物です。特定のイメージを作成したい場合は、Dockerfileを設定し、dockerコマンドを使って簡単に作成できます。

Dockerfile なしでイメージを作成することは可能ですか?

答えは「はい、可能です」です。この場合、まずベースイメージを起動し、「docker exec」コマンドを使ってコンテナに入り、必要なソフトウェアをインストールし、「docker commit」コマンドを使って新しいイメージを生成する必要があります。この方法はDockerfileほど明確でなく、操作も面倒です。

画像とコンテナの関係

前述のように、Dockerfile はイメージの原材料です。ここでは、イメージがコンテナを実行するための基盤となります。

コンテナイメージは、私たちが普段目にするシステムイメージに似ています。CentOSイメージ(拡張子が.iso)のようなオペレーティングシステムイメージを取得する場合、通常、このCentOSオペレーティングシステムは直接サービスを提供できないため、インストールと設定を行う必要があります。

コンテナ イメージにも同じことが当てはまります。

Dockerfileを使ってイメージを作成すると、そのイメージは静的であり、必要なサービスを提供できません。Dockerを使ってイメージを実行し、イメージをコンテナに変換し、静的から動的に変換する必要があります。

簡単に言うと、イメージはファイルであり、コンテナはプロセスです。コンテナはイメージから作成されます。DockerイメージがなければDockerコンテナは作成できません。これはDockerの設計原則の一つです。

ミラーリング最適化技術

前のセクションでは、イメージとは何か、イメージがどのように保存されるか、そしてDockerfile、イメージ、コンテナの関係について説明しました。このセクションでは、主にイメージ作成時に最適化するためのテクニックを紹介します。

Dockerイメージのビルドは、`docker build`コマンドによって開始されます。`docker build`は、Dockerfile内の指示に基づいてDockerイメージをビルドします。最終的なDockerイメージは、Dockerfile内のコマンドによって表現される一連のレイヤーです。そのため、Dockerfileの作成からイメージの作成までのプロセス全体に、最適化と注意が必要な領域があります。

ミラーの最適化は 2 つの方向に分けられます。

  • 画像サイズを最適化する
  • ビルド速度を最適化する

画像サイズを最適化する

イメージ サイズの最適化では、主に Dockerfile を作成するときに考慮する点が重要になります。

前述の通り、イメージはレイヤーに保存されます。各イメージには親イメージがあり、以下のDockerfileに示すように、新しいイメージは親イメージの上に構築されます。

  1. ubuntu:latestから
  2. 追加run.sh /
  3. ボリューム/データ
  4. コマンド [ "./run.sh" ]

この Dockerfile は、ubuntu:latest を親イメージとして使用し、新しいイメージを作成するためのスクリプトを追加します。

したがって、ボリュームを最適化する際には、次の点を考慮することができます。

(1)できるだけ小さいベースイメージを選択する

Docker Hubでは、同じベースイメージの複数のバージョンが存在する場合があります。可能であれば、Alpineバージョンの使用をお勧めします。Alpineバージョンは、多数の最適化が施され、不要なパッケージが削減され、容量が節約されています。ここでは、よく使われるOpenJDKイメージを例に、サイズの違いを簡単に確認してみましょう。

まず、Docker Hub で openjdk:17-jdk と openjdk:17-jdk-alpine のイメージ サイズを以下のように確認できます。

ご覧の通り、同じ Alpine バージョンのイメージは通常バージョンよりも 50MB ほど小さいため、この 2 つをベースイメージとしてビルドしたイメージサイズも異なります。

しかし、すべてのベースイメージに Alpine バージョンを選択する必要がありますか?

いいえ、例えばアルプスの画像にも落とし穴はたくさんあります。

  • Alpineバージョンのイメージを使用すると、大幅な簡素化と最適化が施されているため、多くの依存ライブラリが欠落しており、エラーが発生しやすくなります。プログラムがダイナミックリンクライブラリに依存する必要がある場合、Goのcgo呼び出しなどのエラーが発生しやすくなります。
  • ドメイン名解決の動作はglibcとは異なります。Alpineイメージの基盤ライブラリはmusl libcであり、そのドメイン名解決の動作は標準のglibcとは異なります。特別な設定調整が必要であり、resolv.confでサポートされていないオプションもあります。
  • bash が組み込まれていないため、bash スクリプトの実行は互換性がなく、bash を使用するシェル スクリプトの実行も互換性がありません。

したがって、Alpineイメージの使用は慎重に検討する必要があります。実際のアプリケーションでは、Alpineイメージを使用する場合は、まず初期化を行い、必要な依存関係、ライブラリ、コマンドなどをカプセル化して新しいベースイメージを作成するのが最適です。その後、他のアプリケーションは、このベースイメージを親イメージとして操作に使用できます。

(2)ミラー層の数を最小限に抑える。

前述の通り、画像はレイヤー構造で保存されます。上位レイヤーから下位レイヤーのファイルを変更する必要がある場合は、コピーオンライト機構が必要です。さらに、下位レイヤーのファイルは存在し続け、消えることはありません。レイヤー数が増えるほど、画像サイズは大きくなります。

たとえば、以下の Dockerfile です。

  1. ubuntu:latestから
  2. apt update を実行する 
  3. `apt install git -y` を実行します。
  4. apt install curl -y を実行します。
  5. 追加run.sh /
  6. コマンド [ "./run.sh" ]

このDockerfileは動作しますか?もちろん、問題ありません。しかし、このように記述するとイメージレイヤーの数が非常に多くなってしまうのではないでしょうか?

親イメージ ubuntu:latest 自体のレイヤーを無視すると、上記の Dockerfile は 5 つのレイヤーを追加します。Dockerfile はコマンドのマージをサポートしているため、上記の Dockerfile を次のように変更できます。

  1. ubuntu:latestから
  2. apt update && \を実行します
  3. apt install git -y && \
  4. apt install curl -y
  5. 追加run.sh /
  6. コマンド [ "./run.sh" ]

この変更により、全体的なロジックは変更されずに、ミラー レイヤーの数が 5 から 3 に削減されます。

注: Docker 1.10以降では、RUN、COPY、ADD命令のみがレイヤーを作成します。その他の命令は一時的な中間イメージを作成するもので、ビルドイメージのサイズを直接増加させることはありません。

(3)不要なソフトウェアパッケージを削除する

画像を作成する際は、常に次の点に留意してください。画像は可能な限りシンプルにしてください。これにより、画像の移植性も向上します。

たとえば、以下の Dockerfile です。

  1. ubuntu:latestから
  2. コピー a.tar.gz /opt
  3. 実行 cd /opt && \
  4. tar xf a.tar.gz
  5. コマンド [ "./run.sh" ]

このイメージでは、外部ソースから圧縮ファイル a.tar.gz をコピーしました。解凍後、元のパッケージを削除していないため、まだスペースを占有しています。このDockerfileを以下のように修正できます。

  1. ubuntu:latestから
  2. コピー a.tar.gz /opt
  3. 実行 cd /opt && \
  4. tar xf a.tar.gz && \
  5. rm -f a.tar.gz
  6. コマンド [ "./run.sh" ]

この方法により、必要なファイルを取得できるだけでなく、不要なパッケージを保持することも回避できました。

(4)多段階ビルドを使用する

これは必須ではありません。

なぜそう言うのか?それは、マルチステージビルドは主にコンパイル環境から残った冗長ファイルを解決し、最終イメージを可能な限り小さくするためだからです。では、なぜ必須とは言わないのでしょうか?CI/CI実装では、コンパイルはコンパイルステップであり、ビルドはビルドステップであるため、マルチステージビルドは分離されていることが多いからです。そのため、必須ではないと述べます。

ただし、このアプローチは、以下に示すように、コンパイルとビルドの両方を 1 つの Dockerfile に含めることができるため優れています。

  1. golang AS build-envから
  2. ./go/src/appを追加します
  3. ワークディレクトリ /go/src/app
  4. go get -u -v github.com/kardianos/govendor を実行します。
  5. govendor syncを実行する
  6. GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server を実行します。
  7.  
  8. アルパインから
  9. apk add -U tzdataを実行
  10. RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  11. コピー--from=build-env /go/src/app/app-server /usr/local/bin/app-server  
  12. エクスポーズ8080
  13. CMD [ "アプリケーションサーバー" ]

マルチステージは主に Dockerfile 内に複数の FROM ベースイメージを定義することで実現され、ステージはインデックスやエイリアスで参照できます。

画像サイズを最適化するための4つのポイントをご紹介しました。他にも良い方法や改善方法があれば、ぜひ教えてください。

ビルド速度を最適化する

Dockerfileを作成したら、イメージをビルドする必要があります。ビルド速度が遅いとイライラすることがよくあります。では、それを最適化するにはどうすればよいでしょうか?いくつかの提案をご紹介します。

(1)ネットワーク速度を最適化する

ネットワークは諸悪の根源です。例えば、多くの人がDocker Hubから直接ベースイメージをプルしています。マシンから初めてプルする場合、非常に遅くなります。このような場合、Docker Hubからのイメージをまずローカルのプライベートリポジトリに配置することができます。同じネットワーク環境であれば、プル速度はDocker Hubから直接プルする場合の10,000倍も速くなります。

Alibaba の Dragonfly などの別の画像配信テクノロジーは、P2P の概念を最大限に活用して、画像の検索と配信の速度を向上させます。

(2)コンテキストを最適化する

`docker build` を使用してイメージをビルドすると、次のようにコンテキストが Docker デーモンに送信されることに気付いたかもしれません。

  1. # docker build -t test:v1 。
  2. ビルドコンテキストをDockerデーモン送信しています 11.26kB
  3. ステップ1/2: Ubuntuから
  4. ……

`docker build` を使用してイメージをビルドすると、Dockerfile と同じディレクトリ内のすべてのファイルが Docker デーモンに送信され、後続の操作はこのコンテキスト内で実行されます。

そのため、Dockerfile 内のディレクトリと同じディレクトリに不要なファイルが多数存在すると、メモリ消費量が増加するだけでなく、ビルドプロセス全体の速度も低下します。これを最適化する方法はありますか?

ここでは 2 つの方法が提供されています。

  • Dockerfileをコードリポジトリのルートディレクトリに配置する必要がある場合は、このディレクトリに.dockerignoreファイルを追加し、無視する必要があるファイルとフォルダを追加できます。これにより、コンテキストの送信時に不要なファイルが送信されることがなくなります。
  • Dockerfile を配置するための新しいディレクトリを作成し、このディレクトリを整理された状態に保ちます。

(3)キャッシュを最大限に活用する

Dockerイメージはレイヤーに保存されます。`docker build`を使用してイメージをビルドする際、デフォルトでキャッシュが使用されます。Dockerは新しいイメージを作成する代わりに、まずキャッシュ内から使用するイメージを検索します。ルールは次のとおりです。ベースイメージから派生したすべての子イメージは、キャッシュ内に既に存在するイメージと比較され、そのうちのどれかが全く同じ命令でビルドされているかどうかが確認されます。もし異なる場合は、キャッシュは無効化され、イメージが再構築されます。

簡単に言えば、次の 3 つの要素にまとめることができます。

  • 親イメージは変更されません。
  • ビルド手順は変更されません。
  • 追加されたファイルは変更されませんでした。

これら 3 つの要素が満たされている限りキャッシュが使用されるため、ビルド プロセスが高速化されます。

上記のセクションでは、Dockerイメージの最適化と、サイズと効率性に関する考慮事項について説明しました。このアプローチをイメージ設計に厳密に従えば、作成したイメージは長期間の使用に耐え、面接でも有利になるでしょう。

ミラーのセキュリティ管理

画像に関連する多くのトピックについて説明してきましたが、最後に画像のセキュリティについて話しましょう。

イメージはコンテナの基盤であり、アプリケーションの担い手です。最終的には、イメージが直接的または間接的にビジネスにサービスを提供します。運用・保守担当者は、オペレーティングシステムのセキュリティ強化を実施しているはずですが、イメージにもセキュリティ強化が必要です。

このセクションでは、オペレーティング システムの強化については詳しく説明せず、コンテナーのみに焦点を当てます。

(1)鏡像はシンプルに

合理化はセキュリティにつながるわけではありません。

しかし、簡素化されたオペレーティングシステムイメージは、ある程度のセキュリティ問題を軽減することができます。ご存知の通り、オペレーティングシステムには多数のソフトウェアプログラムが含まれており、日々様々な脆弱性が露呈し、悪意のある攻撃者の標的となります。オペレーティングシステムイメージは、いわば縮小版のようなものと考えることができます。同様に、イメージ内のソフトウェアの数が少なく、簡素化されているほど、脆弱性が露呈するリスクは低くなります。

(2)非ルートユーザーを使用する

コンテナと仮想マシンの主な違いは、コンテナがホストカーネルを共有することです。デフォルトでは、Dockerコンテナはルートユーザーで実行されるため、データ漏洩につながる可能性があります。コンテナが侵害されると、ホストのルートアクセス権限も漏洩する可能性があります。

したがって、次の Java サービスのように、イメージを作成するときは非 root ユーザーを使用する必要があります。

  1. openjdk:8-jre-alpineから
  2. 実行 addgroup -g 1000 -S joker && \
  3. 追加ユーザー ジョーカー -D -G ジョーカー -u 1000 -s /bin/sh
  4. ユーザージョーカー
  5. 追加  --chown=joker springboot-helloworld.jar /home/joker/app.jar  
  6. エクスポーズ8080
  7. ワークディレクトリ /home/joker
  8. CMD exec java -Djava.security.egd=file:/dev/./urandom -jar app.jar

(3)画像のセキュリティスキャンを実行します。

コンテナレジストリでセキュリティスキャンを実行すると、さらなる価値が生まれます。イメージの保存に加え、イメージレジストリによる定期的なセキュリティスキャンは脆弱性の特定にも役立ちます。Dockerは、公式イメージとDocker Cloudでホストされているプラ​​イベートイメージの両方に対してセキュリティスキャンを提供しています。

もちろん、他のリポジトリにもセキュリティスキャンツールが統合されています。例えば、Harborの新バージョンでは、イメージスキャンルールをカスタマイズしたり、ブロックルールを定義したりできるため、イメージの脆弱性を効果的に検出できます。

(4)定期的にセキュリティ結果を確認する。

他にもこんな風に感じたことはありませんか?「いろいろ加えたけど、違いが感じられない」

私も時々そう感じます。例えば、アプリケーションに監視機能を追加したものの、それを無視してしまい、監視がどのように機能するのか全く分からなくなったり、気にしなくなったりする時です。

イメージに対してセキュリティ スキャンを実行し、いくつかのツールをインストールする場合は、単にスキャンして終了するのではなく、それぞれのセキュリティ結果を確認する必要があります。

要約

こんなに小さな鏡の中に、実に多くの精巧な仕組みが隠されています。実際に見るまでは信じられないでしょうが、実際に見れば衝撃を受けるでしょう。

この記事では、Docker イメージの概念から始め、いくつかの実用的なシナリオを使用して実装プロセスをより詳細に比較および分析し、Docker イメージの理解を深めます。