多くのブログ投稿および一般的な意見では、「コンテナごとに1プロセス」ということわざがあります。
なぜこのルールが存在するのですか?すべてのプロセスが機能する必要がある単一のコンテナでntp、nginx、uwsgiなどのプロセスを実行してみませんか?
このルールに関するブログ投稿:
多くのブログ投稿および一般的な意見では、「コンテナごとに1プロセス」ということわざがあります。
なぜこのルールが存在するのですか?すべてのプロセスが機能する必要がある単一のコンテナでntp、nginx、uwsgiなどのプロセスを実行してみませんか?
このルールに関するブログ投稿:
回答:
しばらくの間、高レベルの建築的および哲学的議論を忘れましょう。単一のコンテナ内の複数の機能が理にかなっている場合がありますが、「コンテナごとに1つの機能」を経験することをお勧めする非常に実用的な理由があります。
プロセスではなく、機能と言っていることに注意してください。その言語は時代遅れです。公式のDockerドキュメントは、「1つのプロセス」と言うのではなく、コンテナごとに「1つの懸念」を推奨するようになりました。
数日前に「2プロセス」コンテナを殺害したため、2つのプロセスを開始するpythonスクリプトの代わりに2つのコンテナを使用することになったいくつかの痛みがありました。
推奨事項は、オペレーティングシステムレベルの仮想化の目標と設計に基づいています。
コンテナは、独自のユーザースペースとファイルシステムを与えることにより、他のプロセスを分離するように設計されています。
これは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を再現します。この場合、ハードウェア仮想化の使用は、このニーズに沿ったものになります。
ほとんどの場合のように、それはオールオアナッシングではありません。「コンテナごとに1つのプロセス」のガイダンスは、コンテナが明確な目的を果たすべきであるという考えに由来しています。たとえば、コンテナはWebアプリケーションと Redisサーバーの両方であってはなりません。
両方のプロセスが単一のモジュール機能をサポートしている限り、単一のコンテナで複数のプロセスを実行することが理にかなっている場合があります。
ここでサービスとして呼び出すプロセス、1 container〜1 service、私のサービスのいずれかが失敗した場合、そのコンテナのみを起動し、数秒ですべてが再び起動します。したがって、サービス間に依存関係はありません。コンテナサイズを200 MB未満、最大500 MBに保つことをお勧めします(Windowsネイティブコンテナの例外は2 GBを超えます)。そうでない場合、仮想マシンとまったく同じようになりますが、パフォーマンスは十分です。また、スケーリング、サービスの復元力、自動展開などの方法として、いくつかのパラメーターを考慮してください。
そして、あなたの環境に最適なコンテナ技術を使用してポリゴット環境でマイクロサービスのようなアーキテクチャパターンを作成する必要がある方法をあなたの純粋に呼び出し、あなたのために物事を自動化します。