序章

コンテナイメージは、Kubernetes内でアプリケーションを定義するための主要なパッケージ形式です。 画像はポッドやその他のオブジェクトの基盤として使用され、Kubernetesの機能を効率的に活用する上で重要な役割を果たします。 適切に設計された画像は、安全で、パフォーマンスが高く、焦点が合っています。 Kubernetesによって提供される構成データまたは命令に対応できます。 これらは、デプロイメントが内部アプリケーションの状態を理解するために使用するエンドポイントを実装します。

この記事では、高品質のイメージを作成するためのいくつかの戦略を紹介し、アプリケーションをコンテナー化する際の決定を導くのに役立ついくつかの一般的な目標について説明します。 Kubernetesで実行することを目的としたイメージの構築に焦点を当てますが、これらの提案の多くは、他のオーケストレーションプラットフォームまたは他のコンテキストでのコンテナーの実行にも同様に当てはまります。

効率的なコンテナ画像の特徴

コンテナイメージを構築するときに実行する特定のアクションについて説明する前に、優れたコンテナイメージを作成する方法について説明します。 新しい画像をデザインするときのあなたの目標は何ですか? どの特性とどのような動作が最も重要ですか?

目指すべきいくつかの資質は次のとおりです。

明確に定義された単一の目的

コンテナイメージには、単一の個別のフォーカスが必要です。 コンテナイメージを仮想マシンと考えることは避けてください。仮想マシンでは、関連する機能を一緒にパッケージ化することが理にかなっています。 代わりに、コンテナイメージをUnixユーティリティのように扱い、1つの小さなことをうまく行うことに厳密に焦点を合わせます。 アプリケーションは、個々のコンテナーのスコープ外で調整して、より複雑な機能を提供できます。

実行時に構成を挿入する機能を備えた汎用設計

コンテナイメージは、可能な場合は再利用を念頭に置いて設計する必要があります。 たとえば、本番環境にデプロイする前にイメージをテストするなどの基本的な要件を満たすには、実行時に構成を調整する機能が必要になることがよくあります。 小さな一般的なイメージをさまざまな構成で組み合わせて、新しいイメージを作成せずに動作を変更できます。

小さい画像サイズ

小さい画像には、Kubernetesのようなクラスター環境で多くの利点があります。 それらは新しいノードにすばやくダウンロードされ、多くの場合、インストールされているパッケージのセットが少ないため、セキュリティが向上します。 コンテナイメージを簡素化すると、関連するソフトウェアの量を最小限に抑えることで、問題のデバッグが簡単になります。

外部管理状態

クラスター化された環境のコンテナーは、リソースの不足、スケーリング、またはノードの障害による計画的および計画外のシャットダウンを含む、非常に不安定なライフサイクルを経験します。 一貫性を維持し、サービスの回復と可用性を支援し、データの損失を回避するには、アプリケーションの状態をコンテナー外の安定した場所に保存することが重要です。

わかりやすい

コンテナイメージをできるだけシンプルで理解しやすいものにすることが重要です。 トラブルシューティングを行う場合、構成とログを直接表示したり、コンテナーの動作をテストしたりできると、解決に早く到達するのに役立ちます。 コンテナイメージを、マシン構成ではなくアプリケーションのパッケージ形式と考えると、適切なバランスを取るのに役立ちます。

コンテナ化されたソフトウェアのベストプラクティスに従う

画像は、コンテナモデルに対して作用するのではなく、コンテナモデル内で機能することを目的とする必要があります。 完全な初期化システムやデーモン化アプリケーションを含めるなど、従来のシステム管理手法の実装は避けてください。 にログイン stdout そのため、Kubernetesは、内部ログデーモンを使用する代わりに、データを管理者に公開できます。 これらの推奨事項は、完全なオペレーティングシステムのベストプラクティスとは大きく異なります。

Kubernetesの機能を最大限に活用

コンテナモデルに準拠するだけでなく、Kubernetesが提供するツールを理解して調整することが重要です。 たとえば、ライブネスと準備状況のチェック用のエンドポイントを提供したり、構成や環境の変更に基づいて操作を調整したりすると、アプリケーションがKubernetesの動的デプロイ環境を有利に使用できるようになります。

機能性の高いコンテナイメージを定義するいくつかの品質を確立したので、これらの目標を達成するのに役立つ戦略をさらに深く掘り下げることができます。

最小限の共有ベースレイヤーを再利用する

まず、コンテナイメージが構築されるリソースであるベースイメージを調べることから始めます。 各コンテナイメージは、親イメージ、開始点として使用されるイメージ、または抽象から構築されます scratch レイヤー、ファイルシステムのない空の画像レイヤー。 ベースイメージは、基本的なオペレーティングシステムを定義し、コア機能を提供することにより、将来のイメージの基盤として機能するコンテナイメージです。 画像は、最終的な画像を形成するために互いに積み重ねられた1つまたは複数の画像レイヤーで構成されます。

から直接作業する場合、標準のユーティリティやファイルシステムは利用できません。 scratch、つまり、非常に限られた機能にしかアクセスできません。 から直接作成された画像 scratch 非常に合理化され、最小限に抑えることができます。その主な目的は、ベースイメージを定義することです。 通常、コンテナイメージは、アプリケーションが実行される基本的な環境をセットアップする親イメージの上に構築するため、すべてのイメージに対して完全なシステムを構築する必要はありません。

さまざまなLinuxディストリビューションのベースイメージがありますが、どのシステムを選択するかについて慎重に検討することをお勧めします。 新しいマシンごとに、親イメージと追加した追加のレイヤーをダウンロードする必要があります。 大きなイメージの場合、これはかなりの量の帯域幅を消費し、コンテナの最初の実行時の起動時間を著しく長くする可能性があります。 コンテナビルドプロセスの下流で親として使用されるイメージを削減する方法はないため、最小限の親から始めることをお勧めします。

Ubuntuのような機能豊富な環境では、使い慣れた環境でアプリケーションを実行できますが、考慮すべきトレードオフがいくつかあります。 Ubuntuイメージ(および同様の従来のディストリビューションイメージ)は比較的大きい(100MBを超える)傾向があります。つまり、Ubuntuイメージから構築されたコンテナーイメージはすべてその重みを継承します。

Alpine Linuxは、多くの機能を非常に小さなベースイメージ(〜5MB)に正常にパッケージ化できるため、ベースイメージの人気のある代替手段です。 これには、かなりのリポジトリを備えたパッケージマネージャーが含まれており、最小限のLinux環境に期待されるほとんどの標準ユーティリティが含まれています。

アプリケーションを設計するときは、各イメージに同じ親を再利用することをお勧めします。 イメージが親を共有している場合、コンテナを実行しているマシンは親レイヤーを1回だけダウンロードします。 その後、画像間で異なるレイヤーをダウンロードするだけで済みます。 つまり、共通の機能または各イメージに埋め込みたい機能がある場合は、継承する共通の親イメージを作成することをお勧めします。 系統を共有する画像は、新しいサーバーにダウンロードする必要のある余分なデータの量を最小限に抑えるのに役立ちます。

コンテナレイヤーの管理

親イメージを選択したら、ソフトウェアを追加し、ファイルをコピーし、ポートを公開し、実行するプロセスを選択することで、コンテナーイメージを定義できます。 イメージ構成ファイル内の特定の指示(例: Dockerfile Dockerを使用している場合)は、イメージにレイヤーを追加します。

前のセクションで説明したのと同じ理由の多くで、結果として生じるサイズ、継承、および実行時の複雑さのために、画像にレイヤーを追加する方法に注意することが重要です。 大きくて扱いにくいイメージを作成しないようにするには、コンテナーレイヤーがどのように相互作用するか、ビルドエンジンがレイヤーをキャッシュする方法、および同様の命令の微妙な違いが作成するイメージに大きな影響を与える可能性があることをよく理解することが重要です。

画像レイヤーとビルドキャッシュを理解する

Dockerは、実行するたびに新しいイメージレイヤーを作成します。 RUN, COPY、 また ADD 命令。 イメージを再度ビルドする場合、ビルドエンジンは各命令をチェックして、操作用にキャッシュされたイメージレイヤーがあるかどうかを確認します。 キャッシュ内で一致が見つかった場合は、命令を再実行してレイヤーを再構築するのではなく、既存のイメージレイヤーを使用します。

このプロセスにより、ビルド時間を大幅に短縮できますが、潜在的な問題を回避するために使用されるメカニズムを理解することが重要です。 次のようなファイルコピー手順の場合 COPYADD、Dockerはファイルのチェックサムを比較して、操作を再度実行する必要があるかどうかを確認します。 為に RUN 命令では、Dockerは、その特定のコマンド文字列用にキャッシュされた既存のイメージレイヤーがあるかどうかを確認します。

すぐにはわからないかもしれませんが、注意しないと、この動作によって予期しない結果が生じる可能性があります。 この一般的な例は、ローカルパッケージインデックスの更新と2つの別々のステップでのパッケージのインストールです。 この例ではUbuntuを使用しますが、基本的な前提は他のディストリビューションのベースイメージにも同様に当てはまります。

パッケージのインストール例Dockerfile
FROM ubuntu:20.04
RUN apt -y update
RUN apt -y install nginx
. . .

ここでは、ローカルパッケージインデックスが1つで更新されます RUN 命令 (apt -y update)そしてNginxは別の操作でインストールされます。 これは、最初に使用したときに問題なく機能します。 ただし、Dockerfileを後で更新して追加のパッケージをインストールする場合は、次の問題が発生する可能性があります。

パッケージのインストール例Dockerfile
FROM ubuntu:20.04
RUN apt -y update
RUN apt -y install nginx php-fpm
. . .

2番目の命令によって実行されるインストールコマンドに2番目のパッケージを追加しました。 前回のイメージビルドからかなりの時間が経過すると、新しいビルドが失敗する可能性があります。 これは、パッケージインデックスの更新命令(RUN apt -y update not が変更されたため、Dockerはその命令に関連付けられたイメージレイヤーを再利用します。 古いパッケージインデックスを使用しているため、 php-fpm ローカルレコードにあるパッケージがリポジトリにない可能性があり、2番目の命令の実行時にエラーが発生する可能性があります。

このシナリオを回避するには、相互に依存しているすべてのステップを1つに統合してください。 RUN 変更が発生したときにDockerが必要なすべてのコマンドを再実行するように命令します。 シェルスクリプトで、論理AND演算子を使用する &&、は、それぞれが成功している限り、同じ行で複数のコマンドを実行しますが、これを実現するための良い方法です。

パッケージのインストール例Dockerfile
FROM ubuntu:20.04
RUN apt -y update && apt -y install nginx php-fpm
. . .

この命令は、パッケージリストが変更されるたびにローカルパッケージキャッシュを更新するようになりました。 別の方法は RUN 全体 shell.sh 複数行の命令を含むスクリプトですが、最初にコンテナで利用できるようにする必要があります。

RUN命令を微調整して画像レイヤーサイズを縮小する

前の例は、Dockerのキャッシング動作がどのように期待を覆すことができるかを示していますが、その方法について覚えておくべき他のいくつかのことがあります RUN 命令はDockerの階層化システムと相互作用します。 先に述べたように、それぞれの終わりに RUN 命令では、Dockerは追加のイメージレイヤーとして変更をコミットします。 生成される画像レイヤーの範囲を制御するために、実行するコマンドによって導入されたアーティファクトに注意を払うことで、不要なファイルをクリーンアップできます。

一般に、コマンドを1つにまとめます RUN 命令は、書き込まれるレイヤーを大幅に制御します。 コマンドごとに、レイヤーの状態を設定できます(apt -y update)、コアコマンドを実行します(apt install -y nginx php-fpm)、コミットする前に環境をクリーンアップするために不要なアーティファクトを削除します。 たとえば、多くのDockerfilesチェーン rm -rf /var/lib/apt/lists/* の終わりまで apt コマンド、ダウンロードしたパッケージインデックスを削除して、最終的なレイヤーサイズを縮小します。

パッケージのインストール例Dockerfile
FROM ubuntu:20.04
RUN apt -y update && apt -y install nginx php-fpm && rm -rf /var/lib/apt/lists/*
. . .

作成する画像レイヤーのサイズをさらに小さくするには、実行しているコマンドの他の意図しない副作用を制限することをお勧めします。 たとえば、明示的に宣言されたパッケージに加えて、 apt また、デフォルトで「推奨」パッケージをインストールします。 含めることができます --no-install-recommends あなたに apt この動作を削除するコマンド。 推奨パッケージによって提供される機能のいずれかに依存しているかどうかを確認するために、実験が必要になる場合があります。

このセクションでは例としてパッケージ管理コマンドを使用しましたが、これらの同じ原則が他のシナリオにも当てはまります。 一般的な考え方は、前提条件を構築し、実行可能な最小限のコマンドを実行してから、不要なアーティファクトを1つでクリーンアップすることです。 RUN 作成するレイヤーのオーバーヘッドを減らすコマンド。

マルチステージビルドの使用

マルチステージビルドはDocker17.05で導入され、開発者が作成する最終的なランタイムイメージをより厳密に制御できるようになりました。 マルチステージビルドを使用すると、Dockerfileを複数のセクションに分割して、それぞれに個別のステージを表すことができます。 FROM 個別の親イメージを指定するステートメント。

前のセクションでは、アプリケーションの構築とアセットの準備に使用できるイメージを定義します。 これらには、多くの場合、アプリケーションの作成に必要なビルドツールと開発ファイルが含まれていますが、アプリケーションの実行には必要ありません。 ファイルで定義された後続の各ステージは、前のステージで生成されたアーティファクトにアクセスできます。

最後 FROM ステートメントは、アプリケーションの実行に使用されるイメージを定義します。 通常、これは、必要なランタイム要件のみをインストールしてから、前のステージで生成されたアプリケーションアーティファクトをコピーする簡素化されたイメージです。

このシステムにより、最適化の心配が少なくなります RUN これらのコンテナレイヤーは最終的なランタイムイメージに存在しないため、ビルド段階の命令。 ビルド段階で命令がレイヤーキャッシングとどのように相互作用するかに注意を払う必要がありますが、最終的なイメージサイズではなく、ビルド時間を最小限に抑えることに努力を向けることができます。 画像サイズを縮小するには、最終段階の指示に注意を払うことが依然として重要ですが、コンテナビルドのさまざまな段階を分離することで、それほど多くなくても合理化された画像を簡単に取得できます。 Dockerfile 複雑。

コンテナおよびポッドレベルでのスコープ機能

コンテナの構築手順に関して行う選択は重要ですが、サービスをコンテナ化する方法に関するより広範な決定は、多くの場合、成功により直接的な影響を及ぼします。 このセクションでは、アプリケーションを従来の環境からコンテナプラットフォームで実行するように最適に移行する方法についてもう少し説明します。

関数によるコンテナ化

一般に、独立した機能の各部分を個別のコンテナイメージにパッケージ化することをお勧めします。

これは、VMの実行に必要なリソースを最小限に抑えてサイズを縮小するために、アプリケーションが同じイメージ内で頻繁にグループ化される仮想マシン環境で採用されている一般的な戦略とは異なります。 コンテナはオペレーティングシステムスタック全体を仮想化しない軽量の抽象化であるため、このトレードオフはKubernetesではそれほど魅力的ではありません。 そのため、Webスタック仮想マシンはNginx WebサーバーとGunicornアプリケーションサーバーを1台のマシンにバンドルして、Djangoアプリケーションを提供する場合がありますが、Kubernetesではこれらを別々のコンテナーに分割する場合があります。

サービスに1つの個別の機能を実装するコンテナーを設計すると、多くの利点があります。 サービス間の標準インターフェースが確立されていれば、各コンテナーを個別に開発できます。 たとえば、Nginxコンテナは、さまざまなバックエンドにプロキシするために使用される可能性があります。また、異なる構成が指定されている場合は、ロードバランサーとして使用される可能性があります。

デプロイされると、各コンテナイメージを個別にスケーリングして、さまざまなリソースと負荷の制約に対処できます。 アプリケーションを複数のコンテナイメージに分割することで、開発、編成、および展開に柔軟性を持たせることができます。

ポッド内のコンテナ画像の組み合わせ

Kubernetesでは、ポッドは、コントロールプレーンで直接管理できる最小のユニットです。 ポッドは、1つ以上のコンテナーと、それらのコンポーネントの実行方法をプラットフォームに指示する追加の構成データで構成されます。 ポッド内のコンテナーは常にクラスター内の同じワーカーノードでスケジュールされ、システムは障害が発生したコンテナーを自動的に再起動します。 ポッドの抽象化は非常に便利ですが、アプリケーションのコンポーネントをバンドルする方法について、別の決定層が導入されます。

コンテナイメージと同様に、単一のエンティティにバンドルされている機能が多すぎると、ポッドの柔軟性が低下します。 ポッド自体は他の抽象化を使用してスケーリングできますが、内部のコンテナーを個別に管理またはスケーリングすることはできません。 したがって、前の例を引き続き使用するには、個別のNginxコンテナとGunicornコンテナを1つのポッドにバンドルしないでください。 このようにして、それらを個別に制御および展開できます。

ただし、機能的に異なるコンテナを1つのユニットとして組み合わせることが理にかなっているシナリオがあります。 一般に、これらは、追加のコンテナがメインコンテナのコア機能をサポートまたは強化する状況、またはその展開環境への適応を支援する状況として分類できます。 一般的なパターンは次のとおりです。

  • Sidecar :セカンダリコンテナは、サポートユーティリティの役割で機能することにより、メインコンテナのコア機能を拡張します。 たとえば、サイドカーコンテナは、リモートリポジトリが変更されたときに、ログを転送したり、ファイルシステムを更新したりする場合があります。 プライマリコンテナは引き続きそのコアの責任に焦点を当てていますが、サイドカーによって提供される機能によって強化されています。
  • アンバサダー:アンバサダーコンテナーは、(多くの場合複雑な)外部リソースの検出と接続を担当します。 プライマリコンテナは、内部ポッド環境を使用して、既知のインターフェイス上のアンバサダーコンテナに接続できます。 アンバサダーはバックエンドリソースを抽象化し、プライマリコンテナとリソースプール間のトラフィックをプロキシします。
  • Adapter :アダプターコンテナーは、プライマリコンテナーのインターフェース、データ、およびプロトコルを正規化して、他のコンポーネントで期待されるプロパティと整合させる役割を果たします。 プライマリコンテナはネイティブ形式を使用して動作でき、アダプタコンテナはデータを変換および正規化して、外部と通信します。

お気づきかもしれませんが、これらの各パターンは、さまざまなコンテキストや構成で展開できる標準の汎用プライマリコンテナイメージを構築する戦略をサポートしています。 セカンダリコンテナは、プライマリコンテナと使用されている特定のデプロイメント環境との間のギャップを埋めるのに役立ちます。 一部のサイドカーコンテナは、複数のプライマリコンテナを同じ環境条件に適合させるために再利用することもできます。 これらのパターンは、ポッドの抽象化によって提供される共有ファイルシステムとネットワーク名前空間の恩恵を受けながら、標準化されたコンテナーの独立した開発と柔軟な展開を可能にします。

ランタイム構成の設計

標準化された再利用可能なコンポーネントを構築したいという願望と、アプリケーションをランタイム環境に適合させるための要件との間には、ある程度の緊張関係があります。 ランタイム構成は、これらの懸念間のギャップを埋める最良の方法の1つです。 このように、コンポーネントは汎用として構築され、追加の構成の詳細を提供することにより、実行時に必要な動作の概要が示されます。 この標準的なアプローチは、アプリケーションと同様にコンテナでも機能します。

ランタイム構成を念頭に置いて構築するには、アプリケーションの開発とコンテナー化の両方のステップで事前に検討する必要があります。 アプリケーションは、起動または再起動時にコマンドラインパラメーター、構成ファイル、または環境変数から値を読み取るように設計する必要があります。 この構成の解析と注入のロジックは、コンテナー化の前にコードで実装する必要があります。

Dockerfileを作成するときは、コンテナーもランタイム構成を念頭に置いて設計する必要があります。 コンテナには、実行時にデータを提供するためのメカニズムがいくつかあります。 ユーザーは、ホストからコンテナー内のボリュームとしてファイルまたはディレクトリーをマウントして、ファイルベースの構成を有効にすることができます。 同様に、コンテナの起動時に環境変数を内部コンテナランタイムに渡すことができます。 The CMDENTRYPOINT Dockerfile命令は、ランタイム構成情報をコマンドラインパラメーターとして渡すことができるように定義することもできます。

Kubernetesは、コンテナを直接管理するのではなく、ポッドなどの上位レベルのオブジェクトを操作するため、構成を定義し、実行時にコンテナ環境に注入するために利用できるメカニズムがあります。 Kubernetes ConfigMapsおよびSecretsを使用すると、構成データを個別に定義し、実行時にこれらの値をコンテナー環境に投影できます。 ConfigMapは、環境、テスト段階などに基づいて変化する可能性のある構成データを格納することを目的とした汎用オブジェクトです。 シークレットは同様のインターフェースを提供しますが、アカウントのパスワードやAPIクレデンシャルなどの機密データ用に特別に設計されています。

抽象化の各レイヤーで利用可能なランタイム構成オプションを理解して正しく使用することにより、環境から提供された値からヒントを得る柔軟なコンポーネントを構築できます。 これにより、非常に異なるシナリオで同じコンテナイメージを再利用できるようになり、アプリケーションの柔軟性が向上するため、開発のオーバーヘッドが削減されます。

コンテナを使用したプロセス管理の実装

コンテナベースの環境に移行する場合、ユーザーは多くの場合、ほとんどまたはまったく変更を加えずに、既存のワークロードを新しいシステムに移行することから始めます。 新しい抽象化ですでに使用しているツールをラップすることにより、アプリケーションをコンテナーにパッケージ化します。 通常のパターンを使用して移行されたアプリケーションを稼働させることは有用ですが、以前の実装をコンテナー内にドロップすると、設計が効果的でない場合があります。

コンテナをサービスではなくアプリケーションのように扱う

開発者がコンテナ内に重要なサービス管理機能を実装すると、問題が頻繁に発生します。 たとえば、コンテナ内でsystemdサービスを実行したり、Webサーバーをデーモン化したりすることは、通常のコンピューティング環境でのベストプラクティスと見なされる場合がありますが、コンテナモデルに固有の仮定と矛盾することがよくあります。

ホストは、コンテナー内でPID(プロセスID)1として動作するプロセスに信号を送信することにより、コンテナーのライフサイクルイベントを管理します。 PID 1は最初に開始されるプロセスであり、従来のコンピューティング環境ではinitシステムになります。 ただし、ホストはPID 1しか管理できないため、従来のinitシステムを使用してコンテナー内のプロセスを管理すると、プライマリアプリケーションを制御する方法がない場合があります。 ホストは内部のinitシステムを開始、停止、または強制終了できますが、プライマリアプリケーションを直接管理することはできません。 これらの信号は、意図した動作を実行中のアプリケーションに伝播する場合がありますが、それでも複雑さが増し、常に必要なわけではありません。

ほとんどの場合、PID 1がプライマリアプリケーションをフォアグラウンドで実行するように、コンテナー内の実行環境を単純化することをお勧めします。 複数のプロセスを実行する必要がある場合、PID1は後続のプロセスのライフサイクルを管理する責任があります。 Apacheなどの特定のアプリケーションは、接続を処理するワーカーを生成および管理することにより、これをネイティブに処理します。 他のアプリケーションでは、ラッパースクリプト、またはdumb-initや付属のtiniinitシステムなどの非常に無駄のないinitシステムを使用できます。 選択した実装に関係なく、コンテナ内でPID1として実行されているプロセスは適切に応答する必要があります TERM 期待どおりに動作するようにKubernetesから送信されたシグナル。

Kubernetesでのコンテナヘルスの管理

Kubernetesのデプロイとサービスは、基盤となるコンテナを再起動する必要がある場合や実装自体が変更された場合でも、実行時間の長いプロセスのライフサイクル管理とアプリケーションへの信頼性の高い永続的なアクセスを提供します。 コンテナーからサービスの正常性を監視および維持する責任を抽出することにより、正常なワークロードを管理するためのプラットフォームのツールを活用できます。

Kubernetesがコンテナを適切に管理するには、コンテナ内で実行されているアプリケーションが正常であり、作業を実行できるかどうかを理解する必要があります。 これを有効にするために、コンテナーは活性プローブ、つまり、アプリケーションの状態を報告するために使用できるネットワークエンドポイントまたはコマンドを実装できます。 Kubernetesは、定義された活性プローブを定期的にチェックして、コンテナが期待どおりに動作しているかどうかを判断します。 コンテナが適切に応答しない場合、Kubernetesは機能を再確立するためにコンテナを再起動します。

Kubernetesは、同様の構成である準備プローブも提供します。 準備プローブは、コンテナー内のアプリケーションが正常であるかどうかを示すのではなく、アプリケーションがトラフィックを受信する準備ができているかどうかを判断します。 これは、コンテナ化されたアプリケーションに、接続を受信する準備ができる前に完了する必要のある初期化ルーチンがある場合に役立ちます。 Kubernetesは準備プローブを使用して、ポッドをサービスに追加するか、サービスから削除するかを決定します。

これら2つのプローブタイプのエンドポイントを定義すると、Kubernetesがコンテナを効率的に管理し、コンテナのライフサイクルの問題がサービスの可用性に影響を与えるのを防ぐことができます。 これらのタイプのヘルスリクエストに応答するメカニズムは、アプリケーション自体に組み込まれている必要があり、Dockerイメージ構成で公開されている必要があります。

結論

このガイドでは、Kubernetesでコンテナ化されたアプリケーションを実行する際に留意すべきいくつかの重要な考慮事項について説明しました。 繰り返しになりますが、私たちが行った提案のいくつかは次のとおりです。

  • 最小限の共有可能な親イメージを使用して、最小限の膨張でイメージを構築し、起動時間を短縮します
  • マルチステージビルドを使用して、コンテナビルド環境とランタイム環境を分離します
  • Dockerfile命令を組み合わせて、クリーンな画像レイヤーを作成し、画像キャッシュの間違いを回避します
  • 個別の機能を分離してコンテナ化し、柔軟なスケーリングと管理を可能にします
  • 単一の集中的な責任を持つようにポッドを設計する
  • ヘルパーコンテナをバンドルして、メインコンテナの機能を強化したり、展開環境に適合させたりします
  • ランタイム構成に応答するアプリケーションとコンテナーを構築して、デプロイ時の柔軟性を高めます
  • アプリケーションをコンテナのプライマリプロセスとして実行して、Kubernetesがライフサイクルイベントを管理できるようにします
  • Kubernetesがコンテナのヘルスを監視できるように、アプリケーションまたはコンテナ内でヘルスとライブネスのエンドポイントを開発します

開発および実装プロセス全体を通じて、サービスの堅牢性と有効性に影響を与える可能性のある決定を行う必要があります。 コンテナ化されたアプリケーションが従来のアプリケーションとどのように異なるかを理解し、それらがマネージドクラスター環境でどのように動作するかを学ぶことで、いくつかの一般的な落とし穴を回避し、Kubernetesが提供するすべての機能を利用できるようになります。