Linux ネットワーク名前空間:コンテナネットワークの仕組みを理解する

Networking tutorial - IT technology blog
Networking tutorial - IT technology blog

内部のエンジン:なぜ名前空間が重要なのか

Kubernetes クラスターで「Connection Refused」エラーのデバッグに一晩中費やしたことがあるなら、コンテナネットワークがしばしばブラックボックスのように感じられることを知っているでしょう。私たちは docker run を実行し、接続が魔法のように確立されることを期待します。しかし、パケットがドロップしたりルーティングループが発生したりしたとき、表面的な知識だけでは本番環境を救うことはできません。

Linux ネットワーク名前空間(netns)は、コンテナの隔離を可能にするコア技術です。これにより、単一のカーネル上で完全に独立した複数のネットワークスタックを実行できます。

各名前空間は、独自のインターフェース、IP アドレス、ルーティングテーブル、ファイアウォールルールを保持し、CPU オーバーヘッドは 1% 未満です。OS 全体を必要とする仮想マシン(VM)とは異なり、名前空間は軽量なプリミティブです。これらをマスターすることで、パケットが物理 NIC に到達する前に、仮想的な境界をどのように通過するのかを正確に視覚化できるようになります。

最近、私は生の名前空間を使用して、1 台のラップトップ上に 3 層のファイアウォールアーキテクチャをシミュレートしました。Docker の抽象化を取り除くことで、veth ペアとブリッジインターフェースがどのように相互作用するかを正確に確認することができました。この実践的なアプローチにより、「ネットワークの魔法」が予測可能なロジックへと変わります。

前提条件:Linux 環境の確認

これに必要なツールはおそらくすでに揃っています。この機能は Linux カーネルに組み込まれており、<a href="https://itnotes.dev/ja/tc-%e3%81%a8-iproute2-%e3%81%ab%e3%82%88%e3%82%8b-linux-qos%ef%bc%9a%e3%83%90%e3%83%83%e3%82%af%e3%82%a2%e3%83%83%e3%83%97%e3%81%8c%e3%82%a2%e3%83%97%e3%83%aa%e3%82%92%e5%9c%a7%e8%bf%ab%e3%81%99/">iproute2</a> スイートを介して管理されます。

ターミナルで ip netns を実行してください。ヘルプメニューが表示されれば準備完了です。Ubuntu 22.04 や Fedora などの最新のシステムのほとんどには、これがデフォルトで含まれています。環境にない場合でも、インストールは数秒で完了します。

# Ubuntu または Debian ベースのシステムの場合
sudo apt update && sudo apt install iproute2 -y

# RHEL、CentOS、または Rocky Linux の場合
sudo dnf install iproute2 -y

安定した名前空間のサポートを確保するために、カーネルバージョン 4.15 以上を目指してください。uname -r で確認できます。このガイドのテストは、ネットワークエンジニアリングの信頼できるベースラインである標準の Ubuntu 22.04 LTS インスタンスで実行されました。

初めての仮想ネットワークの構築

仮想ネットワークは 3 つ sensory 段階で構築します。まず隔離された環境を作成し、次にそれらを「配線」し、最後に IP やルートなどのロジックを設定します。

1. 隔離された名前空間の作成

別々のコンテナを表す redblue という 2 つの名前空間を作成しましょう。

sudo ip netns add red
sudo ip netns add blue

クイックリストコマンドで存在を確認します:

ip netns list

現時点では、これらは別々の部屋に置かれた 2 台のラップトップのようなものです。接続されておらず、ローカルループバック(lo)インターフェースさえ管理上ダウンしています。

2. 仮想イーサネット(veth)ペア

この隙間を埋めるために、veth ペアを使用します。これは仮想的なパッチケーブルだと考えてください。一方の端に入ったビットは、即座に反対側の端から出てきます。

sudo ip link add veth-red type veth peer name veth-blue

次に、それぞれの端を特定の名前空間に差し込みます:

sudo ip link set veth-red netns red
sudo ip link set veth-blue netns blue

3. IP の割り当てとインターフェースの有効化

ケーブルを接続したら、ソフトウェアレイヤーを設定する必要があります。ip netns exec を使用して、隔離された環境内でコマンドを実行します。

# 'red' 側の設定
sudo ip netns exec red ip addr add 10.0.0.1/24 dev veth-red
sudo ip netns exec red ip link set veth-red up
sudo ip netns exec red ip link set lo up

# 'blue' 側の設定
sudo ip netns exec blue ip addr add 10.0.0.2/24 dev veth-blue
sudo ip netns exec blue ip link set veth-blue up
sudo ip netns exec blue ip link set lo up

4. 仮想ブリッジによるスケーリング

ポイントツーポイント接続は 2 つのノードには適していますが、拡張性がありません。3 つ以上の名前空間を接続するには、仮想ブリッジが必要です。これはまさに <a href="https://itnotes.dev/ja/%e3%83%9d%e3%83%bc%e3%83%88%e7%ae%a1%e7%90%86%e3%81%8b%e3%82%89%e8%a7%a3%e6%94%be%e3%81%95%e3%82%8c%e3%82%88%e3%81%86%ef%bc%9atraefik%e3%81%a8lets-encrypt%e3%81%a7docker%e3%83%88%e3%83%a9%e3%83%95/">docker0</a> インターフェースが機能する方法と同じです。各名前空間は、相互に接続するのではなく、中央のハブに接続します。

# ホスト上にハブを作成
sudo ip link add br0 type bridge
sudo ip link set br0 up

# 'green' という名前の 3 番目の名前空間を追加
sudo ip netns add green
sudo ip link add veth-green type veth peer name veth-br-green

# green 名前空間をブリッジに接続
sudo ip link set veth-green netns green
sudo ip link set veth-br-green master br0

# 接続を完了
sudo ip netns exec green ip addr add 10.0.0.3/24 dev veth-green
sudo ip netns exec green ip link set veth-green up
sudo ip link set veth-br-green up

検証:仮想世界の中を覗く

検証は最も重要なステップです。ここで、隔離によって接続性が損なわれていないことを確認します。

接続テスト

単純な ping から始めましょう。red 名前空間から blue 名前空間への到達を試みます:

sudo ip netns exec red ping -c 3 10.0.0.2

成功すれば、仮想的な配線が正しいことが証明されます。失敗した場合は、通常 ip netns exec red ip link を実行して、インターフェースが ‘DOWN’ になっていないか確認します。

ルーティングテーブルの検査

隔離されているということは、red はホストのルートを見ることができないことを意味します。インターネットにアクセスするには、デフォルトゲートウェイを設定し、ホスト側で IP マスカレード(NAT)を設定する必要があります。隔離されたテーブルを表示するには:

sudo ip netns exec red ip route

tcpdump によるデバッグ

パケットが見当たらないとき、<a href="https://itnotes.dev/ja/tcpdump-linux%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e3%83%a9%e3%82%a4%e3%83%b3%e3%81%8b%e3%82%89%e3%81%ae%e3%83%8d%e3%83%83%e3%83%88%e3%83%af%e3%83%bc%e3%82%af%e3%83%91%e3%82%b1%e3%83%83%e3%83%88/">tcpdump</a> は最良の友になります。特定の名前空間をターゲットにして、ホストのノイズをフィルタリングできます:

sudo ip netns exec red tcpdump -i veth-red -nnvv

最近のプロジェクトで、このコマンドは 1500 バイトの MTU の不一致 を特定するのに役立ちました。ICMP の ‘Fragmentation Needed’ パケットがアプリケーションによって無視されているのを確認できたのです。名前空間内のトラフィックを監視することで、カーネルレベルで何が起きているかが明確になりました。

最後に

本番環境で名前空間を手動で構築することは滅多にありませんが、この知識はトラブルシューティングにおいて強力な武器になります。コンテナがクラッシュしてシェルが使えない場合でも、ホストから nsenter を使用してそのネットワーク名前空間に参加できます。このレベルのきめ細かな制御こそが、Linux が現代のクラウドインフラストラクチャのバックボーンであり続ける理由です。

Share: