コンテナで1つのプロセスのみを実行することが推奨されるのはなぜですか?


79

多くのブログ投稿および一般的な意見では、「コンテナごとに1プロセス」ということわざがあります。

なぜこのルールが存在するのですか?すべてのプロセスが機能する必要がある単一のコンテナでntp、nginx、uwsgiなどのプロセスを実行してみませんか?

このルールに関するブログ投稿:


しかし、まだDockerを使用できないエンタープライズサーバーの展開と運用を開始するために、多数のプロセスを備えた非常に「脂肪」の多いコンテナを用意しても大丈夫でしょうか。
ピーター

@ J.Doeはおそらく大丈夫ではないでしょう。コンテナはVMとは異なり、小規模なアプリケーションでも複数の小さな問題があります。エンタープライズの展開では、最初にコンテナですべてを実行するのに2年間のプロジェクトが必要になります。
エフゲニー

回答:


65

しばらくの間、高レベルの建築的および哲学的議論を忘れましょう。単一のコンテナ内の複数の機能が理にかなっている場合がありますが、「コンテナごとに1つの機能」を経験することをお勧めする非常に実用的な理由があります。

  • コンテナーが単一の機能に分離されている場合、コンテナーの水平方向のスケーリングははるかに簡単です。別のApacheコンテナが必要ですか?別の場所にスピンアップします。ただし、ApacheコンテナにDB、cron、およびその他の部分が含まれている場合、これは事態を複雑にします。
  • コンテナごとに単一の関数を使用すると、コンテナを他のプロジェクトや目的に簡単に再利用できます。
  • また、開発者がアプリケーション環境全体ではなく、実稼働環境からコンポーネントをプルダウンして、ローカルでトラブルシューティングするための移植性と予測性を高めます。
  • パッチ適用/アップグレード(OSとアプリケーションの両方)は、より分離され制御された方法で実行できます。コンテナ内の複数のビットアンドボブをジャグリングすると、画像が大きくなるだけでなく、これらのコンポーネントが結び付けられます。ZをアップグレードするためだけにアプリケーションXとYをシャットダウンする必要があるのはなぜですか?
    • 上記は、コードの展開とロールバックにも当てはまります。
  • 機能を複数のコンテナに分割すると、セキュリティと分離の観点から柔軟性が高まります。強力なセキュリティ態勢を維持するため、またはPCIなどに準拠するために、物理的にまたはオーバーレイネットワーク内で、ネットワークレベルでサービスを分離(または要求)することができます。
  • stdout / stderrの処理やコンテナーログへのログの送信、コンテナーをできる限り短命に保つなど、その他のより小さな要因

プロセスではなく、機能と言っていることに注意してください。その言語は時代遅れです。公式のDockerドキュメント、「1つのプロセス」と言うのではなく、コンテナごとに「1つの懸念」を推奨するようになりました。


1
それでも、スレッドに対する低レベルの議論はここに収まるようです... web.stanford.edu/~ouster/cgi-bin/papers/threads.pdf
jeffmcneill

素晴らしい、包括的な答え!
ロブ・ウェルズ

質問は実際にはOSの意味で「プロセス」を意味していなかったという考えですか?ドッカーと関連する文章は、「機能」という言葉に切り替えることで明確になった別の用語を使用していましたか?そうでなければ、これが受け入れられ、最高評価の回答であることは認めますが、尋ねられた質問に答えるとは思わないからです。
トム

27

数日前に「2プロセス」コンテナを殺害したため、2つのプロセスを開始するpythonスクリプトの代わりに2つのコンテナを使用することになったいくつかの痛みがありました。

  1. Dockerは、クラッシュしたコンテナーの認識に優れています。メインプロセスが正常に見える場合、それはできませんが、他のプロセスが恐ろしい死を遂げました。もちろん、プロセスを手動で監視できますが、なぜそれを再実装するのですか?
  2. 複数のプロセスがログをコンソールに吐き出している場合、Dockerログはあまり役に立ちません。繰り返しになりますが、ログにプロセス名を書き込むことができますが、dockerでもできます。
  3. コンテナについてのテストと推論はずっと難しくなります。

これは受け入れられた答えでなければなりません。
ClintM

同意した。いくつかの大きなポイントといくつかの他の回答がありますが、重要な点は、PID 1のドッキングウィンドウの取り扱いについてです
ブレット・ワグナー

13

推奨事項は、オペレーティングシステムレベルの仮想化の目標と設計に基づいています。

コンテナは、独自のユーザースペースとファイルシステムを与えることにより、他のプロセスを分離するように設計されています。
これはchroot分離されたファイルシステムを提供する論理的進化であり、次のステップはメモリの上書きを回避するためにプロセスを他のプロセスから分離し、競合することなく複数のプロセスから同じリソース(TCPポート8080など)を使用できるようにすることでした。

コンテナの主な目的は、バージョンの競合を心配することなく、プロセスに必要なライブラリをパッケージ化することです。同じユーザー空間とファイルシステムで同じライブラリの2つのバージョンを必要とする複数のプロセスを実行する場合、プロセスごとに少なくともLDPATHを調整する必要があったため、適切なライブラリが最初に見つかり、一部のライブラリはこの方法で調整できません。それらのパスはコンパイル時に実行可能ファイルにハードコーディングされているため、詳細についてはこのSOの質問を参照してください。
ネットワークレベルでは、同じポートを使用しないように各プロセスを構成する必要があります。

同じコンテナで複数のプロセスを実行するには、かなりの調整が必要であり、同じユーザー空間内で複数のプロセスを実行し、同じファイルシステムとネットワークリソースを共有しても問題ない場合は、1日の終わりに分離の目的を無効にします。ホスト自体に?

私が考えることができる重い微調整/落とし穴の非網羅的なリストは次のとおりです。

  • ログの処理

    マウントされたボリュームを使用するか、stdoutにインターリーブすることにより、管理が必要になります。マウントされたボリュームを使用する場合、コンテナはホスト上に独自の「場所」を持つ必要があります。そうしないと、2つの同じコンテナが同じリソースを奪い合います。docker logsソースを簡単に識別できない場合、stdoutをインターリーブして利用する場合、分析の悪夢になります。

  • ゾンビプロセスに注意してください

    コンテナ内のプロセスの1つがクラッシュした場合、supervisordはゾンビ状態の子をクリーンアップできず、ホストのinitはそれらを継承しません。使用可能なpidの数(2 ^ 22で約400万)を使い果たすと、多くのことが失敗します。

  • 関心事の分離

    同じコンテナ内でapacheサーバーとlogstashのように2つに分けて実行すると、ログの処理が容易になる場合がありますが、logstashを更新するにはapacheをシャットダウンする必要があります。(実際には、Dockerのロギングドライバーを使用する必要があります)現在のセッションが終了するのを待つかどうかは、グレースフルストップですか?正常に停止する場合は、時間がかかり、新しいバージョンを展開するのに時間がかかることがあります。キルすると、ログシッパーのユーザーに影響を与えるため、私見を避ける必要があります。

最後に、複数のプロセスがある場合、OSを再現します。この場合、ハードウェア仮想化の使用は、このニーズに沿ったものになります。


3
これらの議論は納得がいかないと思う。複数のコンテナを持つプロセスとホストで実行するプロセスには大きな違いがあります。コンテナの本来の意図を説明することはいくらか関連がありますが、マルチプロセスコンテナを避けることは本当に説得力のある理由ではありません。IOW、あなたは「なぜ」と「なぜ」と答えていますが、これはあまり有用ではありません。同じコンテナ内で複数のプロセスを実行すると非常に便利な場合があります-それが理由です。その理由はまだ説明されていません。
アサフラビー

1
あなたが念頭に置いていた種類の微調整について詳しく説明していません。そして、この調整は、複数のコンテナを設定するよりも多くの作業であると主張していません。具体例を見てみましょう。メインプロセスと補助プロセスを実行しているスーパーバイザーがパッケージ化されたドッカーイメージをよく目にします。これは非常に簡単に設定できます。ほぼ間違いなく、コンテナを分離するのと同じくらい簡単です。例:アプリとログの配送業者。したがって、なぜそうではないのかを議論するのはあなたの責任です。
アサフラビー

1
ところで、マルチプロセスコンテナに対する有効な引数があると思いますが、それらのいずれにも言及していません。しかし、いずれにせよ、明確なケースではありません。場合によっては、複数のプロセスを許可してもまったく問題ありません。ヘック、いくつかの非常に人気のある画像はいくつかのサブプロセスを生み出します-それも悪ですか?私が言っていることは、トレードオフがあり、あなたの答えは、ニュアンスとディテールを欠いた一方的な絵を描きます。
アサフラビー

1
おもしろい...これについても同様の(同一の)意見があるようです。たぶん、あなたはそれを獲得したかった誰かからだったので、この場合には、それを無視するべきである評論家のバッジを ... ...そしてそのバッジを得るためにあなたの答えを悪用することを決めた
Pierre.Vriens

1
私は結論に「急ぐ」ことはしません...それを無視することをお勧めします。しかし、「あなた」は、あなたの答えの匿名の支持者が誰であるかについて私自身の目で見たものについて、私の考えを変えることはできません。とにかく、先に進む時間...
Pierre.Vriens

6

ほとんどの場合のように、それはオールオアナッシングではありません。「コンテナごとに1つのプロセス」のガイダンスは、コンテナが明確な目的を果たすべきであるという考えに由来しています。たとえば、コンテナはWebアプリケーション Redisサーバーの両方であってはなりません。

両方のプロセスが単一のモジュール機能をサポートしている限り、単一のコンテナで複数のプロセスを実行することが理にかなっている場合があります。


2

ここでサービスとして呼び出すプロセス、1 container〜1 service、私のサービスのいずれかが失敗した場合、そのコンテナのみを起動し、数秒ですべてが再び起動します。したがって、サービス間に依存関係はありません。コンテナサイズを200 MB未満、最大500 MBに保つことをお勧めします(Windowsネイティブコンテナの例外は2 GBを超えます)。そうでない場合、仮想マシンとまったく同じようになりますが、パフォーマンスは十分です。また、スケーリング、サービスの復元力、自動展開などの方法として、いくつかのパラメーターを考慮してください。

そして、あなたの環境に最適なコンテナ技術を使用してポリゴット環境でマイクロサービスのようなアーキテクチャパターンを作成する必要がある方法をあなたの純粋に呼び出し、あなたのために物事を自動化します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.