web-dev-qa-db-ja.com

vethデバイスを使用して2つの名前空間を直接接続する場合、どのネットワークプレフィックスを使用する必要がありますか?

私はネットワーク名前空間の研究を始めたばかりで、非常に一般的な例を見ています。これは2つのvethのおかげで2つの名前空間を接続するだけです(ブリッジは含まれません)。

ip netns add net1
ip netns add net2
ip netns exec net1 ifconfig lo up
ip netns exec net2 ifconfig lo up
ip link add veth1 type veth peer name veth2
ip link set veth1 netns net1
ip link set veth2 netns net2
ip netns exec net1 ifconfig veth1 10.0.15.1/24 up
ip netns exec net2 ifconfig veth2 10.0.15.2/24 up
ip netns exec net1 ping 10.0.15.2

出力は次のとおりです。

PING 10.0.15.2 (10.0.15.2) 56(84) bytes of data.
64 bytes from 10.0.15.2: icmp_seq=1 ttl=64 time=0.355 ms
64 bytes from 10.0.15.2: icmp_seq=2 ttl=64 time=0.189 ms
64 bytes from 10.0.15.2: icmp_seq=3 ttl=64 time=0.187 ms
64 bytes from 10.0.15.2: icmp_seq=4 ttl=64 time=0.184 ms
64 bytes from 10.0.15.2: icmp_seq=5 ttl=64 time=0.158 ms
64 bytes from 10.0.15.2: icmp_seq=6 ttl=64 time=0.300 ms
64 bytes from 10.0.15.2: icmp_seq=7 ttl=64 time=0.189 ms
64 bytes from 10.0.15.2: icmp_seq=8 ttl=64 time=0.186 ms
64 bytes from 10.0.15.2: icmp_seq=9 ttl=64 time=0.186 ms

私が理解できないことは、私が見たすべての例で、vethにIPを与えるときに、常に/ 24クラスのIPを与える理由です。私がそれに単一のIPを与えようとしたとき:

ip netns exec net2 ifconfig veth2 10.0.15.2/32 up

私が得た出力は:

PING 10.0.15.2 (10.0.15.2) 56(84) bytes of data.
From 10.0.15.1 icmp_seq=9 Destination Host Unreachable
From 10.0.15.1 icmp_seq=10 Destination Host Unreachable
From 10.0.15.1 icmp_seq=11 Destination Host Unreachable
From 10.0.15.1 icmp_seq=12 Destination Host Unreachable
From 10.0.15.1 icmp_seq=13 Destination Host Unreachable
From 10.0.15.1 icmp_seq=14 Destination Host Unreachable
From 10.0.15.1 icmp_seq=15 Destination Host Unreachable

単一のIPアドレスを指定できないのはなぜですか?

2

TL; DR

Linuxはアドレスを追加するときに暗黙のルートを追加します。アドレスが/ 32の場合、暗黙のルートを追加することはできません。次に、ルートを他のIPに手動で追加する必要があります。 1つの宛先のみにルーティングすることを意図している場合(LANまたはIPですが、対称である場合、ピアのIPのみに送信されることが多い)、これは _ip address_peerパラメーターで省略できます。同じショットでルーティングします。したがって、2つのifconfigコマンドの代わりに、これを(新しいipコマンドで)使用すると、pingが機能します。

_ip -n net1 link set veth1 up
ip -n net2 link set veth2 up
ip -n net1 address add 10.0.15.1 peer 10.0.15.2 dev veth1
ip -n net2 address add 10.0.15.2 peer 10.0.15.1 dev veth2
_

より長い答え:

最初にいくつかの備考:

  • あなたの問題はネットワークの名前空間に関連しているのではなく、Linuxの特性とともにルーティングのみに関連しています。とにかく、ネットワーク名前空間は、セットアップ全体のモックアップを行うのに非常に便利です。
  • Linuxでは、ifconfigコマンド(およびroutebrctlなどのコマンド)の使用を中止して、 iproute2ifconfigのAPI(ioctl)は、代わりにnetlink APIを使用するためにLinuxで半分放棄されたため、一部の新しい機能は_ip ..._種類のコマンドを介してのみ使用できる場合があります。
  • 最近の十分なiproute2ツールには、名前空間を使用する場合のショートカットとして、ほとんどのサブコマンドに_-netns_オプションがあります。_ip -netns net1 FOO_は_ip netns exec net1 ip FOO_と同等です。以下で可能な場合は、このショートカットを使用します。多くのコマンドは省略バージョン(例: _ip addr_ の代わりに_ip a_または_ip address_)を使用しており、一部のパラメーターキーワードは省略できます。ここでは略語を使用しません(_-n_ではなく_-netns_を除く)。

Linuxは、ネットマスク付きのアドレスが設定されている場合、暗黙的にルートを追加します。ネットマスクが/ 32の場合、この方法でルートを追加することはできません(または実際にはまだlocalスコープルートがありますが、それはメインルーティングテーブルではなく、localルーティングテーブル(_ip -n net1 route show table local_)。この追加は、_ip address add_をで使用する場合に防止できます。暗黙的なルートが不要な一部のセットアップのフラグnoprefixrouteifconfigは、デフォルト(すべてのホストのビットセットバリアント)ブロードキャストアドレスなど、いくつかのデフォルト設定も追加することに注意してください。_ip address_を使用する場合は、明示的に要求する必要があります。

何が起こっているのかを理解するのに役立ついくつかの例を次に示します

アドレスを追加する直前に、別の端末の名前空間の1つで _ip monitor_ を実行します。ネットワーク名前空間で考えられる多くのネットワーク変更のいずれかを表示してから、最初のアドレス追加(_ip netns exec net1 ifconfig veth1 10.0.15.1/24 up_)を実行します。通常取得できるものは次のとおりです。

_# ip -4 -n net1 monitor route
local 10.0.15.1 dev veth1 table local proto kernel scope Host src 10.0.15.1 
broadcast 10.255.255.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
10.0.0.0/8 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
broadcast 10.0.0.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
Deleted 10.0.0.0/8 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
Deleted broadcast 10.255.255.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
Deleted broadcast 10.0.0.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
Deleted local 10.0.15.1 dev veth1 table local proto kernel scope Host src 10.0.15.1 
local 10.0.15.1 dev veth1 table local proto kernel scope Host src 10.0.15.1 
broadcast 10.0.15.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
10.0.15.0/24 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
broadcast 10.0.15.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown
_

ifconfig は非効率的に機能しているように見えます。最初に/ 8ルートを追加してから削除し、要求された/ 24ルートを配置します。それはおそらく過去からの残り物であり、修正されたことはありません。これは_ip -n net1 link set veth1 up; ip -n net1 address add 10.0.15.1/24 broadcast + dev veth1_と同等です:

_local 10.0.15.1 dev veth1 table local proto kernel scope Host src 10.0.15.1 
broadcast 10.0.15.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
10.0.15.0/24 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
broadcast 10.0.15.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
_

では、/ 24が必要ない場合はどうでしょうか。次のように、/ 32 IPを設定し、ルートを自分で追加できます(同時に、セットアップ全体の(おそらく)短いバージョンを書き直します)。

_ip netns add net1
ip netns add net2
ip -n net1 link set lo up
ip -n net2 link set lo up
ip -n net1 link add name veth1 type veth peer netns net2 name veth2
_

インターフェースを設定します(前でも後でもかまいませんが、起動後の最終結果は変更されません)。

_ip -n net1 link set veth1 up
ip -n net2 link set veth2 up
_

住所:

_ip -n net1 address add 10.0.15.1/32 dev veth1
ip -n net2 address add 10.0.15.2/32 dev veth2
_

ここでは、_ip -4 -n net1 monitor route_は_local 10.0.15.1 dev veth1 table local proto kernel scope Host src 10.0.15.1_のみを表示します:非表示のローカルルートのみ。

ルート:

_ip -n net1 route add 10.0.15.2/32 dev veth1
ip -n net2 route add 10.0.15.1/32 dev veth2
_

2つのアドレス値は完全に無関係にすることができます。同様に、192.0.2.1および198.51.100.2を使用できます。一部のホスティングプロバイダーは、このメカニズムを使用して追加の「フェイルオーバーIP」を提供します。実際には、この特定のケースへの近道があります。関連情報が提供されている限り、住所に沿ってルートが1回で追加されます。したがって、前の4つのコマンドの代わりに、これで十分です。

_ip -n net1 address add 10.0.15.1 peer 10.0.15.2 dev veth1
ip -n net2 address add 10.0.15.2 peer 10.0.15.1 dev veth2
_

すべての場合において、これらはポイントツーポイントではなくイーサネットインターフェイスであるため、他のIPを見つけるためにリンク層でARP要求が実行されることに注意してください。

最後の注意:3つ以上のネットワーク名前空間を一緒に使用する場合は、おそらくLANネットマスクの使用に戻す必要があり、ブリッジインターフェイスを作成する必要があります(元の名前空間に配置できます。新しく作成された名前空間ですが、予期しない相互作用を避けるために、独自の予約済み名前空間に配置することをお勧めします)。次に、vethインターフェイスの各ペアについて、片側をブリッジのネットワーク名前空間に配置し、ブリッジにスレーブ化する必要があります(例:_ip -n mybridgens link set vethp1 master bridge0_)。

1
A.B