Kubernetes のマルチコンテナ Pod と Pod 内のコンテナ間通信

Kubernetes のマルチコンテナ Pod と Pod 内のコンテナ間通信

コンテナはマイクロサービスなどの単一の問題を解決するためによく使用されますが、実際のシナリオでは、問題を解決するには複数のコンテナ ソリューションが必要になることがよくあります。この記事では、複数のコンテナを単一の Kubernetes Pod に統合する方法と、Pod 内のコンテナが相互に通信する方法について説明します。

[[282920]]

1. Kubernetes Podについて

1.1 Kubernetes Pod とは何ですか?

まず、Pod とは何かについて説明しましょう。 Pod は、Kubernetes でデプロイおよび管理可能な最小の単位です。つまり、Kubernetes で単一のコンテナを実行する必要がある場合は、そのコンテナ用の Pod を作成する必要があります。同時に、Pod には複数のコンテナを含めることができ、多くの場合、コンテナは密接に結合されています。タイトカップリングとは何ですか?ポッド内の複数のコンテナが、同じサーバー上で実行する必要がある複数のプロセスを表すシナリオを想像してみてください。この類推は、多くの点で Pod がサーバーに似ているため、理にかなっています。たとえば、各コンテナは localhost を介してそのポッド内の他のコンテナにアクセスできます。

1.2 Kubernetes では、デプロイ可能な最小単位として単一のコンテナではなく Pod を使用するのはなぜですか?

単一のコンテナを直接デプロイする方が簡単かもしれませんが、Pod の新しい抽象化レイヤーを追加すると、新たな利点がもたらされます。コンテナは、特定のものを表す実際のエンティティです。この「何か」は、Docker コンテナまたは rkt コンテナになります。それぞれの「もの」には異なる目的があります。コンテナを管理するには、Kubernetes には、コンテナが終了したときに再起動する方法を定義する再起動ポリシーや、Web サーバー プロセスが HTTP 要求に応答できるかどうかなど、アプリケーションの観点からコンテナ内のプロセスがアクティブかどうかを検出する方法を定義するライブネス プローブなどの追加の情報が必要です。

既存のコンテナ エンティティにこれらの新しい属性が追加されないようにするために、Kubernetes アーキテクトは新しいエンティティである Pod を使用することを決定しました。論理的には 1 つ以上のコンテナーが含まれます。

1.3 Kubernetes では、なぜ Pod 内に 1 つ以上のコンテナが存在することを許可するのですか?

Pod 内のコンテナは論理的な「ホスト」上で実行されます。これらは同じネットワーク名前空間 (つまり、同じ IP アドレスとポート空間)、同じ IPC (プロセス間通信) 名前空間を使用し、共有ボリュームも使用します。これらの機能により、Pod 内のコンテナは効率的に相互に通信できるようになります。同時に、Pod を使用すると、密に結合された複数のアプリケーション コンテナーを単一のエンティティとして管理できます。

したがって、アプリケーションを同じサーバー上の複数のコンテナーで実行する必要がある場合、すべてを 1 つのコンテナーに配置してはいかがでしょうか。まず第一に、それは「コンテナごとに 1 つのプロセス」仕様に違反することになります。この仕様が重要なのは、コンテナ内に複数のプロセスがある場合、異なるプロセスのログが混在し、これらのプロセスのライフサイクルを管理するのが難しくなるため、デバッグが非常に困難になるためです。 2 番目に、アプリケーションに複数のコンテナを使用すると、よりシンプルでわかりやすくなり、ソフトウェアの依存関係が分離されます。さらに、より細かい粒度のコンテナをチーム間で再利用できます。

1.4 マルチコンテナポッドの使用例

マルチコンテナ Pod の主な目的は、共存および共同管理されるヘルパー プロセスをサポートすることです。プロセスを支援する一般的なシナリオはいくつかあります。

サイドカー コンテナー: たとえば、ログまたはデータ変更モニター。チームがログウォッチャーを作成すると、さまざまなアプリケーションで使用できるようになります。サイドカー コンテナーのもう 1 つの例は、メイン コンテナーのデータを生成するファイル ローダーまたはデータ ローダーです。

プロキシ、ブリッジ、アダプター: メイン コンテナーを外部に接続します。たとえば、Apache HTTP サーバーまたは nginx は静的ファイルを読み取ります。メイン コンテナー内の Web アプリケーションのリバース プロキシとしても使用できます。

マルチティアアプリケーション (WordPress など) を Pod で実行する場合、各ティアに個別の Pod を使用することをお勧めします。最も単純な理由は、これにより各レイヤーを個別にスケーリングし、異なるノードに分散できるようになることです。

2. ポッド内のコンテナ間の通信

Pod 内で複数のコンテナを実行すると、コンテナ間の通信が非常に簡単になります。独自のコミュニケーション方法がいくつかあります。

2.1 共有ボリューム経由の通信

Kubernetes では、Pod 内のコンテナは、データを共有するためのシンプルで効率的な方法として共有ボリュームを使用できます。ほとんどのシナリオでは、ホスト上の単一のディレクトリを使用し、それを複数のコンテナー間で共有するのが効率的なアプローチです。

Kubernetes ボリュームを使用すると、コンテナの再起動後もデータを保持できます。ボリュームのライフサイクルはポッドと同じです。つまり、ポッドが存在する限り、ボリュームも存在することになります。 Pod が削除された場合、同一の Pod が作成されたとしても、元の Pod の共有ボリュームは破棄され、新しい共有ボリュームが作成されます。

ポッド内の複数のコンテナで共有ボリュームを使用する標準的な使用例は、1 つのコンテナがログやその他のファイルを共有ディレクトリに書き込み、他のコンテナが共有ディレクトリからデータを読み取る場合です。たとえば、次の Pod を作成します。

  1. APIバージョン: v1
  2. 種類: ポッド
  3. メタデータ:
  4. 名前: mc1
  5. 仕様:
  6. ボリューム:
  7. -名前:html
  8. 空ディレクトリ: {}
  9. コンテナ:
  10. -名前: 1st
  11. 画像: nginx
  12. ボリュームマウント:
  13. -名前:html
  14. マウントパス: /usr/share/nginx/html
  15. -名前: 2番目
  16. 画像: debian
  17. ボリュームマウント:
  18. -名前:html
  19. マウントパス: /html
  20. コマンド: [ "/bin/sh" , "-c" ]
  21. 引数:
  22. -真の場合;する
  23. 日付>> /html/ index .html;
  24. 睡眠1;
  25. 終わり

この例では、html という名前のボリュームが定義されています。そのタイプは emptyDir です。つまり、Pod がノードに割り当てられると、空のディレクトリに基づいてボリュームが作成され、Pod が実行されている限りボリュームが存在することになります。最初のコンテナは nginx サーバーを実行し、共有ボリュームを /usr/share/nginx/html ディレクトリにマウントします。 2 番目のコンテナは Debian イメージを使用し、共有ボリュームを /html ディレクトリにマウントします。 2 番目のコンテナは、毎秒、現在の日付と時刻を共有ボリューム内の index.html ファイルに書き込みます。ユーザーが Pod に HTTP リクエストを送信すると、Nginx はこのファイルの内容を読み取り、ユーザーに返します。

nginx ポートを公開するか、ブラウザでアクセスするか、コンテナの共有ディレクトリを直接確認することで、Pod を検査できます。

  1. $ kubectl exec mc1 -c 1st -- /bin/cat/usr/share/nginx/html/index.html  
  2. ...
  3. 2019年8月25日金曜日 18:36:06 UTC
  4.   
  5. $kubectl exec mc1 -c 2番目-- /bin/cat /html/index.html  
  6. ...
  7. 2019年8月25日金曜日 18:36:06 UTC
  8. 2019年8月25日金曜日 18:36:07 UTC

2.2 プロセス間通信 (IPC)

Pod 内のコンテナは同じ IPC 名前空間を共有します。つまり、SystemV セマフォや POSIX 共有メモリなどの標準のプロセス間通信方法を使用して相互に通信できます。

次の例では、2 つのコンテナを含む Pod を定義します。同じ画像を使用します。最初のコンテナーはプロデューサーであり、標準の Linux メッセージ キューを作成し、いくつかのランダムな文字列をキューに書き込み、その後に特殊な終了文字を書き込みます。 2 番目のコンテナーはコンシューマーであり、同じキューを開いて、特殊な終了文字を読み取るまで文字を読み取ります。 Pod の再起動ポリシーを「Never」に設定しているため、両方のコンテナが終了した後に Pod は停止します。

  1. APIバージョン: v1
  2. 種類: ポッド
  3. メタデータ:
  4. 名前: mc2
  5. 仕様:
  6. コンテナ:
  7. -名前:プロデューサー
  8. 画像: allingeek/ch6_ipc
  9. コマンド: [ "./ipc" , "-producer" ]
  10. -名前: 消費者
  11. 画像: allingeek/ch6_ipc
  12. コマンド: [ "./ipc" , "-consumer" ]
  13. 再起動ポリシー: なし

Pod の実行後、各コンテナのログをチェックして、特定の終了メッセージを含む、2 番目のコンテナが 1 番目のコンテナからのすべてのメッセージを受信したことを確認します。

  1. $ kubectl ログ mc2 -c プロデューサー
  2. ...
  3. 生産: f4
  4. 生産: 1日
  5. 制作: 9e
  6. 生産数: 27
  7. $ kubectl ログ mc2 -c コンシューマー
  8. ...
  9. 消費: f4
  10. 消費: 1d
  11. 消費: 9e
  12. 消費: 27
  13. 消費: 完了

デフォルトでは、1 つのコンテナを別のコンテナの後に起動するように指定する方法がないため、Pod 内のすべてのコンテナは並行して起動されます。たとえば、IPC の例では、最初のコンテナが起動されてメッセージ キューが作成される前に、2 番目のコンテナが起動される可能性があります。この時点で、2 番目のコンテナーは失敗するため、起動時にメッセージ キューが既に存在している必要があります。

Kubernetes Init Containers など、コンテナの起動順序を制御する方法はいくつかあり、初期化コンテナが最初に起動されます。しかし、クラウドネイティブ環境では、あらゆる制御不能な障害に備えることが最善です。たとえば、上記の問題を解決する最善の方法は、メッセージ キューが作成されるまで待機するようにアプリケーションを変更することです。

2.3 コンテナ間のネットワーク通信

Pod 内のコンテナは同じネットワーク名前空間を使用するため、「localhost」を介して相互に通信できます。さらに、コンテナの場合、ホスト名は Pod の名前になります。 Pod 内のすべてのコンテナは同じ IP アドレスとポート空間を共有するため、接続を受信する必要があるコンテナごとに異なるポートを割り当てる必要があります。つまり、Pod 内のアプリケーションはポートの使用を自ら調整する必要があります。

次の例では、1 つのコンテナで Nginx を実行し、別のコンテナで実行されている Web アプリケーションのリバース プロキシとして機能するマルチコンテナ Pod を作成します。

(1)ステップ1、nginx設定ファイルのConfigMapを作成します。ポート 80 から受信した HTTP リクエストは、ローカルホストのポート 5000 に転送されます。

  1. APIバージョン: v1
  2. 種類: ConfigMap
  3. メタデータ:
  4. 名前: mc3-nginx-conf
  5. データ:
  6. nginx.conf: |-
  7. ユーザーnginx;
  8. ワーカープロセス 1;
  9.   
  10. error_log /var/log/nginx/error.log 警告;
  11. pid /var/run/nginx.pid;
  12.   
  13. イベント {
  14. ワーカー接続 1024;
  15. }
  16.   
  17. http {
  18. /etc/nginx/mime.types を含めます。
  19. デフォルトタイプ アプリケーション/オクテットストリーム;
  20.   
  21. ファイル送信オン;
  22. キープアライブタイムアウト65;
  23.   
  24. アップストリームウェブアプリケーション {
  25. サーバー 127.0.0.1:5000;
  26. }

(2)ステップ2:2つのコンテナのポッドを作成します。1つのコンテナはnginxを実行し、もう1つのコンテナは単純なWebアプリケーションを実行します。 Pod にはポート 80 のみを定義していることに注意してください。ポート 5000 には Pod の外部からアクセスできません。

  1. APIバージョン: v1
  2. 種類: ポッド
  3. メタデータ:
  4. 名前: mc3
  5. ラベル:
  6. アプリ: mc3
  7. 仕様:
  8. コンテナ:
  9. -名前: ウェブアプリ
  10. 画像: トレーニング/ウェブアプリ
  11. -名前: nginx
  12. 画像: nginx:alpine
  13. ポート:
  14. -コンテナポート: 80
  15. ボリュームマウント:
  16. -名前: nginx-proxy-config
  17. マウントパス: /etc/nginx/nginx.conf
  18. サブパス: nginx.conf
  19. ボリューム:
  20. -名前: nginx-proxy-config
  21. 構成マップ:
  22. 名前: mc3-nginx-conf

ポッド内のポートスペースを確認すると、ポート 80 と 5000 が表示されます。

  1. # ネットスタット -lntp
  2. アクティブなインターネット接続(サーバーのみ
  3. プロトコル 受信Q 送信Qローカルアドレス外部アドレス 状態 PID/プログラム 
  4. tcp 0 0 0.0.0.0:80 0.0.0.0:* 聞く -
  5. tcp 0 0 0.0.0.0:5000 0.0.0.0:* LISTEN 1/python

(3)ステップ3:PodをNodePortサービスとして公開する

  1. $ kubectl ポッド mc3 を公開--type=NodePort--port=80  
  2. サービス「mc3」が公開されました

(4)ステップ4:サービスを確認する

  1. [root@master1 ~]# kubectl describe svc mc3
  2. 名前: mc3
  3. 名前空間: testproject
  4. ラベル: app=mc3
  5. 注釈: <なし>
  6. セレクター: app=mc3
  7. タイプ: NodePort
  8. IP: 172.30.34.232
  9. ポート: <未設定> 80/TCP
  10. ターゲットポート: 80/TCP
  11. ノードポート: <未設定> 32728/TCP
  12. エンドポイント: 10.130.0.190:80
  13. セッションアフィニティ: なし
  14. 外部トラフィックポリシー: クラスター
  15. イベント: <なし>

これで、ブラウザまたは curl ツールを使用して Web アプリケーションにアクセスできるようになります。

  1. [root@master1 ~]# カール 10.70.209.68:32728
  2. こんにちは世界!

nginx コンテナのポート 80 で受信した HTTP リクエストは、Web アプリケーション コンテナのポート 5000 に転送されます。

上記の例では、ポッド内の 1 つのコンテナが他のコンテナにアクセスするだけを示しています。実際、Pod 内の複数のコンテナが異なるポートをリッスンし、それらのポートがすべて公開されるのが一般的です。これを実装するには、複数のポートを公開するサービスを作成するか、公開するポートごとにサービスを作成します。

3. まとめ

Kubernetes は、Pod コンセプトを作成することで、コンテナの動作とコンテナ間の通信のオーケストレーションに非常に便利です。コンテナはストレージ ボリュームを共有し、ネットワークや IPC を介して相互に通信できます。

元記事: https://www.mirantis.com/blog/multi-container-pods-and-container-communication-in-kubernetes/

原作者: パベル・チェキン

<<:  業界アプリケーションの革新とアップグレードのコアビジネスクラウド実装

>>:  クラウド導入を成功させるためのベストプラクティス 10

推薦する

ウェブサイトランキングの実践事例分析第1章

この記事「ウェブサイトランキングの実践的なケース分析の第1章」は、主に百度検索結果で1位になったウェ...

外部リンクは予備的な作業であり、コンテンツは後から作業するものである

なぜ私のウェブサイトのインデックスが 1 位のウェブサイトよりも高く、外部リンクが多いのかとよく聞か...

Li Jiaqi 氏と Viya 氏はどのようにしてライブストリーミング e コマースに火をつけたのでしょうか?

李佳奇は2019年の電子商取引ライブストリーミングで最も代表的な人物となった。口紅の販売で有名になっ...

クラウド インフラストラクチャの詳細: さまざまなコンポーネントの探索

クラウドの実装は現代の IT システムの重要なコンポーネントとなり、組織が業務を拡大し、コストを削減...

Istio は Spring Cloud を置き換えることができますか?

過去には、私たちは「あらゆることを行う」大規模なモノリシック アプリケーションを運用していました。最...

IBMは座って雲が上がり、青が白に変わるのを眺める

歴史が川であるならば、過去 100 年間は最も流れが激しい時期です。ここで突然加速し、巨大な波が広大...

温州捷順網は中国電信に巨額のブロードバンド料金を滞納して倒産し、社長は逃亡したとみられる

中国IDCレビューネットワークは6月8日に次のように報じた。「2012年6月5日、温州捷順網絡が代表...

ブルーグリーンデプロイメント、A/B テスト、Lark リリース

近年、「DevOps」が非常に人気になっています。最近、私たちのチームでは、デプロイメントのベストプ...

エンタープライズマーケティングソフト記事の品質とスピードを確保する方法

企業のウェブサイトでは、ソフトテキストマーケティングが最も一般的に使用されているマーケティング手法で...

Google ADID の登場後、Cookie に代わるものは何でしょうか?

最近、Google は従来の Cookie 追跡技術を新しい匿名広告識別子システムである AdID ...

8つの視点から語る:ユーザージャーニーに基づいたチャネル配信方法

ユーザー ジャーニーとは、最初のコンタクトから支払いの完了、製品やサービスの享受に至るまで、ユーザー...

ウェブマスターネットワークニュース:JD.comが再びSina Weiboを放棄、Pacific Direct Purchaseが崩壊

1. 菜鳥の最新動向:アリババの物流事業を統合昨日(9月3日)、Cainiao Networkは最初...

知っておくべきトップ 15 のクラウド管理サービス プロバイダー

クラウド コンピューティングの時代において、マネージド サービス プロバイダーが重要な位置を占めてい...

企業にとってのオンラインニュースの意義と解決策

インターネットが世界中で急速に発展している現代では、雨後の筍のようにオンラインメディアが次々と登場し...