Docker サイドカーを使用するとホームラボが簡素化されると思っていましたが、実際は逆でした

in tech

Docker エコシステム内でサイドカー パターンに初めて出会ったとき、その概念的な優雅さは真実を語るにはあまりにも素晴らしすぎると感じました。補助コンテナをプライマリ アプリケーション コンテナの横に直接接続し、同じネットワーク名前空間とストレージ ボリュームを共有するという概念は、あらゆる運用上の悩みを解決するモジュール化への道を提供しました。

サイドカー アーキテクチャでは、懸念事項をより明確に分離することが約束されており、各プライマリ コンテナはコア ビジネス ロジックのみに集中でき、コンパニオン コンテナは横断的なインフラストラクチャの負担を処理できます。サービス メッシュを取り巻くコミュニティの熱意は、このパターンが私の小規模な自宅インフラストラクチャにとっても正しいアーキテクチャの方向性を表しているという私の確信をさらに強めました。

初期実装の成果

初期のデプロイメントの欺瞞的なスムーズさ

私の最初のサイドカー実装では、アプリケーション ログを集中管理された Loki インスタンスに送信する専用のログ フォワーダーを使用して自己ホスト型 Gitea インスタンスを強化しました。 Gitea は、小さな Git リポジトリ、設定ファイル、中途半端なスクリプト、および公開 GitHub リポジトリに値しない種類のプライベート プロジェクトに使用していたので、すでに私のホームラボにきちんと収まっていました。これは監視するのに十分重要であり、有益なログを生成するのに十分なノイズがあり、ログ作成サイドカーは無害な最初の実験になるだろうと思うほど単純でした。

docker compose マニフェストに必要な追加行は、適切なイメージを使用してサイドカー コンテナーを定義し、Gitea のログ ファイルが含まれている同じボリュームをマウントし、プライマリ コンテナーと一致するようにネットワーク モードを構成するわずか数行の追加だけです。 compose コマンドを実行すると、両方のコンテナが完全に同期して起動し、サイドカーが律儀にログ ファイルを追跡し、無視できる遅延で各行をアグリゲータに転送しました。 Gitea 自体は幸いにもこのコンパニオンに気づかず、何も変わっていないかのようにファイル システムにログを書き込み続け、集中ログ ダッシュボードには数秒以内にこの新しいソースからのエントリが取り込まれ始めました。

docker compose ファイルのスクリーンショット

コンテナと NAS サーバーを運ぶ様式化されたクジラを特徴とする Docker ロゴのイラスト。

このトリックで Docker の更新を最適化する

まだ Docker コンテナを手動で更新していますか?

この最初の成功に勇気づけられて、私はサイドカー戦略を拡張して、他のいくつかの重要なサービスを包含するようにしました。リバース プロキシ サイドカーがプライマリ API ゲートウェイに接続され、メイン アプリケーション コードに負担をかけずに SSL 終了とリクエスト ルーティングを処理しました。メトリクス エクスポータ サイドカーがデータベース コンテナから Prometheus エンドポイントをスクレイピングし始め、監視ダッシュボードに入力された標準化された測定値が公開されました。追加するたびにパターンの価値が検証され、プライマリ コンテナ イメージの複雑さが軽減され、以前はアプリケーション イメージ全体の再構築が必要だったインフラストラクチャ コンポーネントへの独立した更新が可能になりました。

複雑さへの降下

複数のサイドカーが予期せず相互作用を開始した場合

journalctl docker ログのスクリーンショット

最初の警告は、ロギング サイドカーが過剰なメモリを消費し始め、アプリケーション スループットが高いときにバッファが際限なく増加し、最終的に共有ボリューム ロックを通じてプライマリ コンテナにカスケードされる OOM Kill を引き起こしたときに届きました。

メトリクス サイドカーは、ログ サイドカーのリソース競合により一時的に応答しなくなったエンドポイントを収集しようとしましたが、再試行ループに入り、さらにログ エントリが生成され、ポッド全体がすぐに不安定になる正のフィードバック サイクルが発生しました。これらの懸念事項を分離すると、私が単純に分離されたままになるだろうと思っていた共有リソースを介した予期せぬ結合が明らかに発生しました。

デバッグ プロセスにより、サイドカー コンテナーは概念的には独立しているにもかかわらず、複数の隠れたチャネルを通じて相互作用しており、診断が大幅に複雑になっていることが明らかになりました。共有ネットワーク名前空間は、プライマリ コンテナまたは他のサイドカーがすでに要求しているポートにサイドカーがバインドしようとすると、予期せずポートの競合が発生する可能性があることを意味していましたが、Docker からのエラー メッセージには、どのコンテナがどのバインディングを担当しているのかがほとんど示されていませんでした。

ドッカーデスクトップ

OS

Windows、macOS、Linux

ブランド

ドッカー

価格

月額11ドルから

無料トライアル

機能が制限された無料版

Docker は、新しいアプリを簡単に開発できるようにするアプリケーションです。


共有ボリュームによりロック競合が発生し、断続的なファイル アクセス エラーが発生し、再現が難しく、正しい原因を特定することが困難でした。コンテナー間のプロセス シグナリング、特に構成のリロード中に 1 つのサイドカーがプライマリ アプリケーションを再起動する必要がある場合、競合状態が発生し、状態の不整合が発生し、解決するには手動介入が必要でした。

従来の単一コンテナの展開内で障害が発生した場合、診断ワークフローは、アプリケーション ログ、システム メトリクス、プロセス状態の検査を介した比較的単純なパスに従います。

ラップトップ上で実行されている incus webui の写真

Docker デスクトップをネイティブ Linux コンテナーに置き換えて以来、決して振り返ることはありませんでした

コンテナーをシンプルにするために秘密の仮想マシンは必要ありません。

サイドカーの導入により、このプロセスは、複数のコンテナー ログの同時検査、クロック スキューによってわずかにずれることがあるタイムスタンプの相互参照、複数のプロセスのいずれかで発生した可能性のあるイベントの関連付け、共有リソースを介したコンテナーの境界を越える因果関係の連鎖の再構築を必要とする多次元の探索に変換されます。かつては静かな満足の源だった私の自宅研究室は、機能が停止するたびに何時間もの綿密な調査作業が必要となるフラストレーションの実験室になりました。

運用負担が倍増

コンテナの普及に伴う隠れたコスト

CPU使用率のスクリーンショット

差し迫ったデバッグの課題を超えて、サイドカー パターンにより、私が最初に熱心に取り組んでいたときには十分に予想していなかった重大な運用上のオーバーヘッドが課せられました。追加のコンテナーごとに、独自のリソース割り当て、独自の更新スケジュール、独自のセキュリティ パッチ適用計画、および独自の構成管理ライフサイクルが必要です。私のホームラボは、以前は時折のメンテナンス時間枠で管理できていましたが、サイドカー イメージがさまざまな頻度でアップデートをリリースするため、常に注意を払う必要があり、それぞれが特定のプライマリ コンテナーと一緒にデプロイされたサイドカーの特定の組み合わせに応じて異なる形で現れる可能性のある潜在的な回帰を引き起こします。

複数のサイドカーによる累積リソース消費量は、特にメモリと CPU の制約が既に厳しい私の小規模なハードウェアではかなり大きいことが判明しました。各サイドカーには、独自のランタイム オーバーヘッド、イメージ レイヤーからの独自のファイル システム フットプリント、ヘルス チェックと監視プローブからの独自のネットワーク接続オーバーヘッドが追加されました。監視サイドカーは、アプリケーション自体よりも多くの総 CPU サイクルを消費しましたが、どのサイドカーがどのメトリックを生成したかを区別することがますます困難になるにつれて、可観測性への貢献は減少しました。

Gitea grafana メトリクスのスクリーンショット

Ugreen iDX6011 Pro NAS から広げられたドライブ トレイ。工具不要のトレイ設計と取り付けられたハード ドライブを示しています。

99% のユーザーが NAS の設定を間違っています。1% になる方法は次のとおりです。

NAS は 1 つの間違いで非常に悪い日になる

避けられない撤退

アーキテクチャのトレードオフを再検討する

gitea ログのスクリーンショット

数か月間、運営上の苦痛が増大した後、私は熱心に構築したサイドカーのインフラストラクチャをしぶしぶ解体し始めました。最初に導入されたのはロギング サイドカーで、アプリケーションが標準化されたライブラリ インターフェイスを通じて集中ロギング エンドポイントに直接書き込む、より単純なアプローチに置き換えられました。その後、メトリクス サイドカーが登場し、コンテナごとに個別のスクレーパーをデプロイするのではなく、アプリケーション エンドポイントから直接データを取得する単一の集約メトリクス コレクターに取って代わられました。明確さよりも混乱を引き起こしていたリバース プロキシ サイドカーは、プライマリ アプリケーションのリクエスト処理パイプラインに直接統合され、ネットワーク ルーティングが簡素化され、不透明なエラーの原因が排除されました。

Docker Compose ファイルの差分のスクリーンショット

この後退は、サイドカー パターンの全面的な拒否として解釈されるべきではありません。サイドカー パターンは、独立したアップグレード、言語に依存しない実装、または運用上の問題の厳密な分離が複雑さのコストを上回るシナリオにおいて真の価値を保持します。しかし、私のホームラボではこれらのシナリオはどれも当てはまらず、パターンの利点は完全に理論上のものであることが証明されましたが、そのコストは時間のロス、信頼性の低下、インフラストラクチャの信頼の低下として具体的に現れました。


面倒な方法で学んだこと

すべてのサイドカーには関係が追加され、その関係はホームラボのバグが好んで隠れる場所です。シンプルなスタックは、原因から障害に至るまでの道筋がたどりやすいため、多くの困難な状況に耐えることができます。すべてのファイル、ポート、ルート、および起動ステップが小さなヘルパー コンテナーを通過すると、システムがクリーンになったことにはなりません。あなたは混乱を、より悪い名前と短いログを持つ場所に移しました。最近では、何かを「処理するだけ」ためにコンテナを 1 つ追加する前に、将来、疲れていてもデバッグできるかどうかを尋ねます。答えが疑わしい場合は、通常、すっきりとしたデザインのほうが退屈なものです。

関連情報は以下のリンクからご確認いただけます

詳しい情報を見る

関連記事

前の投稿
Series 11を含むすべてのApple Watchが現在プライムデーのセール中です
次の投稿
ビデオゲーム、コントローラー、周辺機器のセールは今夜プライムデーが終了すると終了します