Dockerを使用すべきでない時: コンテナが役立たないケース
Dockerは間違いなく過去10年間で最も影響力のある開発者技術の1つです。コンテナは、アプリケーションの隔離、物理マシン間でのスケーリング、および環境間の違いの抽象化に対する解決策を提供しました。
Dockerやその隣接するコンテナ化技術を採用する多くの組織は、それが効率を高め、開発プロセスを加速させることを見出します。しかし、Dockerはすべてのシステムを魔法のように改善するものではありません。この記事では、コンテナに移行することが助けよりも障害になる可能性のあるいくつかのシナリオを見ていきます。
パフォーマンスが重要なとき
Dockerは、パフォーマンスが重要なシステムには最適な選択肢ではないかもしれません。コンテナ化の性質は、ソフトウェアがホストマシンに直接インストールされる場合には存在しないオーバーヘッドを生み出します。
もちろん、Dockerはパフォーマンスを向上させるのにも役立ちます。特に、アプリケーションを水平にスケーリングしやすくすることで。したがって、この判断は、システムの要件や基盤となるオペレーティングシステムとの相互作用の文脈で行われることが重要です。
DockerはVMよりはるかに少ないリソースを使用しますが、ホスト上で実行する必要がある別のプロセスです。リソースが制約された環境では、コンテナプロセスやDockerデーモン自体がOSのアウト・オブ・メモリーキラーの標的となり、アプリケーションの一部がエビクションされることで連鎖的な失敗が発生する可能性があります。
多くの持続的なデータ
Dockerコンテナはデフォルトで一時的に設計されています。永続的なデータはボリュームを使用することでサポートされています。これらはホスト上の別の場所にデータを保存するためにコンテナにマウントされます。
ボリュームストレージのパフォーマンスは、選択したドライバーとホスト環境によって異なります。最良のシナリオであっても、ホストのファイルシステムと直接やり取りする場合と比較して、追加のオーバーヘッドがあります。これは、ファイルの読み取りまたは書き込みのボリュームが高い場合に重要となる可能性があります。
ボリュームに保存されたデータは、管理と維持が難しいことがあります。ボリュームと対話するにはDockerコマンドを使用する必要があります。データの検査は、コンテナにシェルを取得して、その内部からボリュームの内容を列挙するのが最適です。
Dockerは、ストレージについて考え、自分自身の永続性戦略を選ぶことを要求します。これは、後での管理方法を気にせずに任意のディレクトリにデータを安全に保存できるVMやOSパッケージのインストールとは異なります。
地域ツールとアプリの開発
Dockerは、各環境にインストールしたくない依存関係を持つ長期的なサービスを構築する際に最も理にかなっています。一般的な例としては、NGINXウェブサーバーの背後で動作するPHPウェブアプリケーションがあります。この場合、単一のコマンドから起動したいバックグラウンドサーバーを含む複数のコンポーネントがあります。
Dockerは、デスクトッププログラムやモバイルアプリなどのローカル使用のためのツールを作成しているときにはあまり価値を追加しません。この種のソフトウェア開発は、コンテナ内で実行できないか、ユーザーによって一般的にコンテナ化されないアーティファクトを生成する傾向があります。
これらの状況では、最終的な出力ではなく、ツールチェーンをパッケージするためにDockerを使用することで、依然としてDockerの恩恵を受けることができます。例えば、JavaとAndroidプラットフォームツールを含むDockerイメージを作成することで、新しい開発者がこれらのパッケージを自分のマシンに追加する必要を回避できます。
ただし、これはAndroid Studio、Visual Studio、XcodeのようなIDEによって推進される分野で、より複雑さを増すことになりがちです。開発者はIDEをインストールし、その環境を自動的に設定することに慣れています。したがって、Dockerは解釈型言語のワークフローに比べて、コンパイル型言語のワークフローにはあまり価値を加えない傾向があります。解釈器の正しいバージョンをイメージに焼き付けることができるためです。
セキュリティが最優先事項です
Dockerはあなたのスタックのセキュリティを向上させることができますが、インストールを適切に強化するには作業が必要です。よくある誤解は、Dockerが初めから安全であると仮定することです。はっきり言うと、そうではありません。
Dockerの存在自体がセキュリティリスクであるとは言っていませんが、それは事実ではありません。それでも、Dockerには独自のリスクが伴うことを認識することが重要ですし、それはテクノロジーの使用方法によって異なります。他のソフトウェアコンポーネントと同様に、これらのリスクを理解し、それがあなたにとって重要なセキュリティ基準へのコンプライアンスにどのように影響するか、そしてそれらに対処するために何をすべきかを考える時間を取る必要があります。
「孤立したアプリケーション」の提案を聞いて、それがサンドボックスレベルのセキュリティにまで及ぶと仮定するのは簡単です。実際には、標準のDockerインストールはコンテナプロセスを次のように実行します。
rootコンテナのブレイクアウトはあなたのホストを危険にさらす可能性があります。
Dockerのセキュリティは多面的なトピックであり、ホスト環境、Dockerデーモン、イメージを構築および維持する方法を考慮する必要があります。開発者もコンテナ内で実行されるコードのリスクの高い操作を最小限に抑えることで役割を果たします。
これはすべて、Dockerがセキュリティが重要な設定にとって最良の選択肢ではないかもしれないことを意味しています。Dockerはセキュリティ保護を提供できますが、新たに導入される問題に対処するためには、スキルのあるチームメンバーとセキュリティを意識したマインドセットが必要です。
あなたのコードベースはモノリスです
おそらく、コンテナはマイクロサービスと密接に関係していると読んだことがあるでしょう。この考え方は、システムを独立したコンポーネントに分割し、それを容易にコンテナ化できるプロセスを説明しています。サービスを分割した後、それらは個別にスケールでき、他の部分に影響を与えることなく、一部を交換することができます。
アプリがモノリスであると、これらの利点を見ることはできません。しかし、モノリシックなシステムをそのままコンテナ化することは、間違ったアプローチかもしれません。大規模なレガシーアプリケーションは、多くの依存関係と長いビルドプロセスを持つ傾向があり、それが迅速にDockerイメージを膨らませてしまいます。その結果、イメージビルド中の苛立たしい待機時間や、余分なストレージと帯域幅コストが発生します。
いつものように、このコインには二つの側面があります:モノリスをコンテナ化することは、しばしばスタックを現代化し、それをより小さなサービスに分割するための第一歩です。それは、コードベースをそれが結びついてしまった環境から分割するポイントです。
しかし、将来的にリファクタリングを続ける意志がない場合は、あなたの動機を再考することが最良かもしれません。複数の機能コンポーネントを含む大きなコンテナイメージは、コンテナのベストプラクティスに合っていないことの良い指標です。時間が経つにつれて、そのアプローチが実際にあなたを後退させ、問題の一部となることがあるかもしれません。
あなたは複雑さを減らそうとしている
複雑さを減らそうとしているのですか?コンテナ化が開発とデプロイメントに新たなシンプルさをもたらすと考えていますか?再び言いますが、それは「状況による」という瞬間ですが、シンプルさを主な動機としてDockerの流行に飛び乗ることは避けるべきだと警告します。
Dockerにはマインドセットの転換が必要であり、新しいツールや概念に慣れる必要があります。開発者はそれに慣れることができるでしょうか、そしてそれが採用プロセスにどのように影響するでしょうか?これらは見落としがちな質問ですが、早い段階で考慮すべきです。
Dockerは多くの形の複雑さを取り除くものの、異なる形で再浮上する傾向があります。Dockerイメージをローカルの開発者マシンやCIパイプラインの一部として、書いて、文書化し、維持し、構築する必要があります。開発者はDocker CLIを学び、コンテナの基本を理解し、アプリケーションをコンテナ化する際に注意すべき潜在的な問題を把握する必要があります。
本番環境でコンテナを実行する予定なら、さらに考慮すべき点があります。ネットワークトラフィックはどのようにコンテナにルーティングされますか?コンテナが予期せず停止した場合、システムはどのように応答しますか?
「Dockerは簡単」という考え方の支持者は、既に持っているイメージのインスタンスを単純に開始することの容易さに狭く焦点を当てがちです。確かに、ラップトップに新しいMySQLデータベースを持ちたい場合、単にそれを行うことができます。
docker run -d mysql:8しかし、ベストプラクティスを守り、一般的な落とし穴を避けながら、自分自身のソフトウェアを構築して実行するためにDockerを成功裏に使用するには、まだ学ぶべきことがたくさんあります。
なぜコンテナ化しているのかわからない
コンテナはどこにでもあります。ソフトウェア開発に関する記事を数本読むだけでも、それに出会うことができ、支持者たちは声高で熱心です。この人気は、他の人々が役立つと感じている「現代的」なツールであるDockerを採用するよう圧力をかけることがあります。
これはコンテナ化するための良い理由ではありません。"開発者は本番環境を正確にローカルで再現できるべき"や"私たちのサービスのレプリカを水平にスケールできる必要がある"など、より具体的な目標が必要です。Dockerの明確な使用ケースを感じていないなら、現在のワークフローに満足しているのであれば、うまくいっているものを維持するのが最良の選択かもしれません。退屈な選択に思えるかもしれませんが、Dockerは完璧な変革の力ではなく、成功した導入が保証されているわけではありません。
プロセスにDockerを追加することは、かなりの初期投資が必要になる場合があります。コードベースをリファクタリングし、Dockerfileを作成してテストし、開発者に学ぶ時間を与え、セキュリティ評価を完了する必要があるかもしれません。得られる利益が不明な場合や、成功がどのようなものかを特定していない場合、その努力はシステムの生産的な作業を妨げる負担になる可能性があります。
結論
Dockerは当然人気のある技術です。多くのチームや開発者にとって、使いやすさ、柔軟性、性能の理想的なバランスを提供し、実際の開発プロセスを簡素化することができます。ただし、Dockerは魔法ではありません。既存の技術、プロセス、考え方によっては機能しない場合や、多くのケースでは動作しない場合もあります。
たとえDockerが今日のプロジェクトに完全に適していなくても、段階的に導入することで何らかの利点を得られるかもしれません。プロセスにおける課題を特定し、その特定の領域でDockerが役立つかどうかを評価してください。たとえば、開発者がAPIのステージングインスタンスを立ち上げるのに時間をかけすぎている場合、そのスタックの一部をDocker化することでボトルネックを解消できるかもしれません。たとえ本番環境でコンテナを実行できなくても。
コンテナの本質は、アプリの一部を独立して動作する孤立したコンポーネントとしてパッケージ化できることです。これは自動的にすべてのコンポーネントをコンテナとしてパッケージ化する必要があるという意味ではありません。客観的になり、意味のあるところでコンテナ化の機会を探しつつ、Dockerが既存のワークフローに価値を付加しない状況を認識する準備をしてください。
