【入門編】Docker Swarmのトラフィック制御術:Ingressルーティングメッシュの仕組みと動作原理 – インフラ構成管理(IaC)活用バイブル

こんにちは!インフラエンジニアの先輩です。

日々のコンテナ運用の現場、本当にお疲れ様です。Kubernetes(K8s)は確かに強力だけど、ちょっとオーバースペックだな……と感じることはありませんか?「もっとシンプルに、Dockerの延長線上でクラスタを組んで、安全にトラフィックをさばきたい!」そんな悩みを抱えるあなたにこそ知ってほしいのが、Docker Swarmです。

今回は、Swarmの心臓部であり、最も美しく、そして誤解されやすい「Ingressルーティングメッシュ」の仕組みと動作原理を徹底解剖します。

これをマスターすれば、「あれ?なんでこのコンテナにトラフィックが届かないんだろ……」という夜間障害の恐怖から解放され、毎日のインフラ作業が劇的に楽になりますよ。さあ、深淵なるコンテナネットワークの世界へ一緒に出発しましょう!

—

1. なぜDocker Swarmなのか?(そして「ルーティングメッシュ」とは何か)

Docker Swarmは、Docker Engineに標準で組み込まれているオーケストレーションツールです。追加の重いミドルウェアを入れる必要がなく、`docker swarm init`の一撃でプロダクション品質のクラスタが手に入ります。

そのSwarmが持つ最大の魔法が、「Ingressルーティングメッシュ(Routing Mesh)」です。

従来のDocker(スタンドアロン)の悩み

通常の`docker run -p 80:80`では、ポートをバインドした「そのコンテナが動いているホスト」にしかアクセスが来ません。もしそのノードが落ちたら?ロードバランサーの設定を書き換えないといけませんよね。面倒です。

SwarmのIngressルーティングメッシュの思想

Swarmでは、クラスタ内のどのノードの公開ポート(例: `80`)にアクセスしても、自動的に、そのコンテナが実際に動いているコンテナ(タスク)へトラフィックが転送されます。
つまり、外部のロードバランサーから見れば、クラスタのどのIPを叩いても正解になるという、圧倒的な可用性をもたらす仕組みです。

—

2. 基礎セットアップ:手を動かしてクラスタを構築する

百聞は一見に如かず。実際にローカル(または手元のVM)でSwarmクラスタを立ち上げ、ルーティングメッシュの動きを体感してみましょう。

ここでは、Dockerがインストールされている環境を前提に話を進めますね。

ステップ1: Swarmの初期化(マネージャーノード)

まずは、あなた自身をクラスタの「マネージャー」に仕立て上げます。

Docker Swarmを初期化する(eth0などのプライベートIPのインターフェースを指定)
docker swarm init –advertise-addr <あなたのマシンのIPアドレス>

成功すると、以下のようなワーカー参加用のコマンドが出力されます
docker swarm join –token SWMTKN-1-xxxxxxxx 192.168.1.10:2377

たったこれだけで、クラスタの制御中枢が完成しました。

ステップ2: 動作確認用のオーバーレイネットワークの確認

Swarmを初期化すると、自動的にいくつかのネットワークが作成されます。その中で今回主役になるのが、`ingress` という名前のネットワークです。

docker network ls

出力の中に `ingress`(ドライバー: `overlay`)が見つかるはずです。これが、クラスタ全体を包み込む魔法のネットワーク布陣です。

—

3. HelloWorldで検証:ルーティングメッシュの挙動を図解する

それでは、実際にサービスをデプロイし、トラフィックがどう流れるのかを検証しましょう。今回は、アクセスすると「自分がどのホスト・どのコンテナのIPで応答しているか」を返してくれる軽量なWebサーバーをデプロイします。

ステップ3: レプリカ数「3」のサービスをデプロイ

コンテナをクラスタ内に3つ起動し、ホストのポート `8080` を公開するように指示します。

docker service create \
–name web-app \
–replicas 3 \
–publish 8080:80 \
nginxdemos/hello

  • `–replicas 3`: クラスタ内に同じコンテナを3つ並行稼働させます。
  • `–publish 8080:80`: クラスタ内のどのノードであっても、ポート `8080` に来たリクエストを、コンテナ内のポート `80` にルーティングします。

ステップ4: マジックの目撃(トラフィックの分散)

それでは、コンテナがどこで動いているかを確認してみましょう。

docker service ps web-app

出力結果を見ると、3つのタスク(コンテナ)が、マネージャーノードやワーカーノードに分散して配置されているのがわかります。

ここで、ブラウザを開くか、コマンドラインから次のように連続でリクエストを送ってみてください。

curl http://localhost:8080

何度か実行すると、レスポンスに含まれる「Server Address」や「Hostname」が切り替わることが分かりますか?
あなたがアクセスしたのは「ただ一つのポート(8080)」ですが、Swarmのルーティングメッシュが背後でL4(トランスポート層)の負荷分散を行い、3つのコンテナへ綺麗にトラフィックを分配しているのです。

—

4. 内部構造の深層:IPVS(IP Virtual Server)の裏側

「一体どうやってこのルーティングを実現しているのか?」
ここからが少しディープで面白いところです。シニアエンジニアなら知っておくべき、Linuxカーネルの機能のお話。

Docker Swarmのルーティングメッシュは、アプリケーションレイヤーのプロキシ(NginxやEnvoyなど)だけで動いているわけではありません。パフォーマンスを極限まで高めるため、Linuxカーネルに標準搭載されているIPVS(IP Virtual Server)というレイヤー4ロードバランサーを内部で利用しています。

マネージャーやワーカーノードの内部(コンテナ空間ではなくホストのネットワーク名前空間)を覗いてみると、次のようなIPVSのルールが自動構築されているのが見つかります。

ホスト側でIPVSのルールを確認してみる(要権限)
sudo ipvsadm -ln

ここには、外部から公開されたポート(`8080`)宛てのパケットを、`ingress`ネットワーク内にある各コンテナの仮想IP(VIP)へ振り分けるためのルーティングテーブルが、動的に書き込まれています。

通信のフロー(パケットの旅)

1. 外からのリクエスト: クライアントが、クラスタ内の任意のノードのポート `8080` にアクセス。
2. IPVSによるキャッチ: ノードのOSカーネル(IPVS)がパケットをキャッチ。
3. オーバーレイネットワーク経由の転送: `ingress`ネットワークのオーバーレイ(VXLANトンネル)を介して、実際にコンテナが動いているノード(あるいは自分自身)へパケットをカプセル化して転送。
4. コンテナへ到達: コンテナ内のWebサーバーがレスポンスを返す。

この一連の動きが、Docker Engineによって完全に自動化・冪等(べきとう)に管理されているのです。

—

5. 現場で役立つ「知っておくべきハマりどころ」と対策

最後に、現場でこのルーティングメッシュを使うときに必ず直面する「罠」と、その回避策を授けます。これを覚えておくだけで、障害シューティングの時間が10分の1になりますよ。

トラブル1: クライアントのIPアドレスがログに見えない?

  • 現象: アプリケーションのアクセスログを見ると、アクセス元のIPアドレスがすべて同じ(または見慣れないブリッジのIP)になってしまう。
  • 原因: ルーティングメッシュを経由する際、NAT(Network Address Translation)処理が行われるためです。
  • 対策: もしクライアントの真のグローバルIPをどうしてもアプリでロギングしたい場合は、`–publish` のモードを `ingress`(デフォルト)から `host` モードに変更します。

docker service create –publish published=8080,target=80,mode=host …

※ただし、`mode=host` にすると「そのポートはどのノードでも1つしか使えない(ポート競合が起きる)」というスタンドアロンに近い制約に戻るため、可用性とのトレードオフに注意してください。

トラブル2: 外部のロードバランサーとの組み合わせ方

AWSのALBやGCPのHTTP(S) Load BalancerなどのクラウドLBを使う場合、Swarmクラスタの「どのノード」にトラフィックを流せばいいでしょうか?

  • 正解: クラスタに参加しているすべてのノードのIP(またはパブリックIP)をターゲットグループに登録します。
  • ルーティングメッシュがあるおかげで、LBがどのノードにリクエストを投げても、最終的に適切なコンテナへたどり着くため、LB側の設定が非常にシンプルになります。

—

おわりに

いかがでしたでしょうか?
Docker SwarmのIngressルーティングメッシュは、単なる「ポートフォワーディングの拡張」ではなく、LinuxカーネルのIPVS技術を裏側に隠し持った、非常に洗練された分散ルーティングシステムです。

「複雑すぎるKubernetesを導入するほどの規模ではないけれど、冗長性とロードバランシングはしっかり担保したい」
そんな現場において、Swarmとこのルーティングメッシュの仕組みを理解していれば、あなたにとって最強の武器となるはずです。

ぜひ、自分の手でクラスタを組んで、`curl`を叩きながらパケットの流れを想像してみてください。インフラの仕組みが手に取るようにわかる喜びが、そこにはありますよ。

それでは、また次回の深淵なインフラ世界でお会いしましょう!

タイトルとURLをコピーしました