私は現在、アプリケーションをDockerコンテナーに移動するためのアプローチを研究していて、明確な答えが見つからない質問に出くわしました。
私たちのアプリケーションには、現在1つのデータベースサーバーでホストされているいくつかの個別のデータベースがあります。 Dockerに移行する場合、アーキテクチャを同じに保つ必要がありますか(つまり、すべてのデータベースを含む1つのコンテナー)、またはデータベースごとに1つのコンテナーを使用する必要がありますか?
後者のアプローチは、私には「ドッカー」のように思えます。 1つのコンテナーで2つのアプリケーションをホストしないのと同様に、1つのコンテナーで2つのデータベースをホストしないことも理にかなっているようです。
確立されたベストプラクティスはありますか?問題のデータベースのパラメーター(サイズ、アクセス頻度など)または使用されているデータベースサーバー(SQLサーバー、PostgreSQLなど)に依存しますか?
私が知る限り、「DBごとのコンテナー」アプローチは、オーバーヘッドを増やして(つまり、データベースサーバーのオーバーヘッドは、データベース全体で1回ではなく1回だけ発生します)、柔軟性を高めます(DBごとにメモリ制限を適用するなど)。他に考慮すべき利点/欠点はありますか?
前回確認したのはnotデータベースをdockerで実行することをお勧めします。
簡単に言えば、Dockerはステートレスなコンテナとして設計されており、必要に応じてスピンアップおよびダウンすることができます。ここで、データベースは非常に完全な状態です。
単純なDockerデータベースアプローチでは、コンテナーがクラッシュした場合にすべてのデータが失われます。新しいインスタンスにまたがると、空のデータベースが作成されます。
これは開発環境には理想的ですが、本番環境では非常に悪いです。
これで、ボリュームを使って賢いことができるようになりますが、なぜこれをしようとしているのかを自問する必要があります。データベースは一般に非常に成熟した製品であり、さまざまなバックアップ、フェイルオーバー、高可用性オプションが組み込まれています。一般に、データベースにはコンテナーの概念が組み込まれているため、コンテナーで実行することは望ましくありません。
コンテナーは、最終的には(マシンではなく)プロセスの単なる小さなラッパーであり、それについてそれらについて考えると役立ちます。この場合、各データベースには独自の長期間有効なマスタープロセスがあるため、おそらくそれぞれに独自のコンテナーが必要です。これは、将来的にコンテナーがクラスター全体に透過的に分散される可能性があるKubernetesのようなツールへの拡張にも役立ちます。
コンテナで複数のプロセスを使用することはもちろん正常ですが、通常、1つのプロセスが同じコンテナ内の他のプロセスを制御します。たとえば、ウェブサーバーが複数のワーカープロセスを生成する場合がありますが、コンテナのルートプロセスはその子を担当します。
その結果、do1つのコンテナに複数のデータベースサーバーを追加する場合、多くのマスタープロセスを管理するためにロジックを追加する必要があります。たとえば、1つのPostgresインスタンスが停止した場合、その1つのインスタンスを再起動するだけの方法が必要になります。各データベースマスタープロセスに独自のコンテナーがある場合、KubernetesまたはDockerはこれを無料で管理できます。
編集:明確なコメントの後、データベースデータ(データベースアプリケーションではなく、アプリケーション内の「データベース」!)を参照していることがわかります。上記の推論はフレーミングに役立ちます。これは単なるプロセス分離であり、他のストレージやパーティションの問題とは関係ありません。複数のデータベースに複数のプロセスを使用する理由、または反対する理由がある場合でも、コンテナに同じことが適用されます。
データベースデータ自体は必ずボリュームに配置する必要があることに注意してください(ほとんどのデータベースイメージは、おそらくそのボリュームをDockerfileですでに宣言しています)。
通常、データベースはスキーマを使用して、無関係なものを論理的に分離します。
独自の永続化ボリュームを持つ独自のDockerインスタンスで、各スキーマを移動することを検討することをお勧めします。
また、Kubernetesは予告なしにポッドを強制終了する可能性があることにも注意してください。それに応じてデータベースを構成する必要があります。
「コンテナ内の1つのサーバー上に複数のデータベースを持っている」という質問への答えとして、次のようにします。
したがって、1つのデータベースと通信する1つのコンテナ/サービスを使用して、コンテナ環境の外部にDBを実装します。
私の(許可された限定された)経験から、4つの異なる視点からセットアップを検討します。
データ(有効期間/優先度)
スケール
リスク
パフォーマンス
在庫(データベースA)、いくつかのショッピングカート(データベースB)、注文リスト(データベースC)を備えたシンプルなWebショップがあるとしましょう。
最も重要なデータから始めましょう:注文のリスト。ここでは、リスク回避が鍵となります。このデータを失うか破損すると、ビジネスが台無しになる可能性があるためです。同時に、これにはPII(住所や支払いデータなどの個人を特定できる情報)が含まれる可能性があり、これらも保護する必要があります。
このため、Dockerボリュームを使用しても、Docker化されたデータベースサーバーはデータが実際にディスクに格納される方法を完全に制御できない(仮想化のレイヤーが多すぎる)ため、保守的になり、より伝統的なデータベースサーバーの設定を使用します。重要なデータストレージに不要なリスクを導入しないでください。
次に、ショッピングカートを見てみましょう。基本的な概念では、このデータは揮発性であると規定されています。買い物客は、注文を確定するよりもはるかに頻繁にアイテムを追加および削除します。つまり、挿入、更新、削除が多数行われます。また、それは定期的に発生するはずのないことですが、この種のデータの損失は、ユーザーにとって最悪の場合わずかな不快感です。
ここでは、パフォーマンスとスケールにもっと注意を払います:ほとんどのデータベース操作はここで行われるため、and偶発的なデータ損失のリスクはそれほど高くないため、Dockerizedを使用したくなるかもしれません特に十分な規模での負荷分散を目的としたデータベースコンテナー。 (これは実際の要件に大きく依存するため、これを塩の粒と一緒に服用してください!)
最後に、在庫。頻繁に更新されない静的データ(単純な価格表)である場合、パフォーマンスが問題になる場合は、集中型ストレージからプルするドッキングされたキャッシュを使用すると興味深いかもしれません。 (もちろん、キャッシュ自体の元のソースは、責任の理由から、注文と同様にリスク回避の方法で保持する必要があります。)
ただし、在庫も利用可能な在庫を追跡する必要がある場合や、はるかに動的な場合(リアルタイムの株価、ユーザーコンテンツなど)、突然のスケールも非常に大きな問題になります。その時点で、私は従来のデータベースサーバー(またはおそらくそれらのクラスター)に注目します。
多くの要因が関係しているので、簡単な答えはありません。一般に、データが短期間で信頼性の要件が低いか、または静的なもの(キャッシュ)でない限り、私は従来のデータベースサーバー設定を好む傾向があります。