2012年10月21日日曜日

Linux Network Namespace

Linux が持つネットワーク仮想化機能の話。

kernel 2.6.24 以降でサポートされる。実行にはiprouteパッケージの 3(おそらく) 以降が必要。

Fedora16, 17、Ubuntu12.04 は標準で利用可能を確認。
RHEL6系はiprouteのバージョンが低いため利用不可。

利用可否は以下のコマンドで確認可能。

# ip netns

このコマンドがエラーにならなければ、利用条件を満たせている(はず

利用方法は以下

Network Namespaceとは?

一つのホスト内で独立したネットワーク環境を作成できる。
作成したネームスペースはホストの物理環境や、他のネームスペースの干渉を受けない。

特に1ホスト上での仮想マシンのネットワーク的な分離に利用される。


■作成方法
# ip netns add testns01


■ネームスペースの確認
# ip netns
testns01

■ネームスペースのネットワーク設定

2つの方法があり、一つは、

# ip netns exec testns01 command

として、コマンドを実行する。こうすると実行されるコマンドは、ネームスペース内のネットワーク環境で動作する。実行するコマンドは何でも良い。


もうひとつは、

# ip netns exec testns01 bash

として、ネームスペース内でシェルを起動する。


ここでは後者の例を示す。
# ip netns exec testns01 bash
# ip link list
5: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN 
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
# iptables -nvL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination 

作成したばかりのネームスペースには何の設定も入っていないので、特に何も(インターフェース)も存在しない。

ここにtapやveth等を追加していく事で、ネットワーク環境を作っていく。

ネームスペースを指定していない場合は、デフォルトのネームスペース(OSの起動時から存在する環境)が使われる。


環境作成の例

以下のネットワーク環境を構築してみる。

事前にルーティングを有効化しておく必要あり。
# echo 1 > /proc/sys/net/ipv4/ip_forward

# 面倒なのでiptables を無効にしておく。
iptables -F

# まず一つ目のネットワーク環境を作成
export NSNAME1=ns01
export IF_INT1=v1-eth0
export IF_EXT1=v1-eth1

export NSNAME2=ns02
export IF_INT2=v2-eth0
export IF_EXT2=v2-eth1

export BRNAME=vswitch0

# ネームスペースの作成
ip netns add $NSNAME1

# vethのペアを作成(vethは2つのNICが作られ、その2つがクロスケーブルで接続されているかの様に振る舞う)
ip link add name $IF_INT1 type veth peer name $IF_EXT1

# 作成したペアの片方をネームスペースに所属させる
ip link set $IF_EXT1 netns $NSNAME1

# ネームスペース内でNICへアドレスを割当てる
ip netns exec $NSNAME1 ip link set $IF_EXT1 up
ip netns exec $NSNAME1 ip addr add 172.26.0.11/24 dev $IF_EXT1

# 2つ目のペアを設定
ip netns add $NSNAME2
ip link add name $IF_INT2 type veth peer name $IF_EXT2
ip link set $IF_EXT2 netns $NSNAME2
ip netns exec $NSNAME2 ip link set $IF_EXT2 up
ip netns exec $NSNAME2 ip addr add 172.26.0.254/24 dev $IF_EXT2

# ブリッジを作成し、vethの残っているインターフェースを接続する
brctl addbr $BRNAME
brctl setfd $BRNAME 0
brctl addif $BRNAME $IF_INT1
brctl addif $BRNAME $IF_INT2
ip link set $IF_INT1 up
ip link set $IF_INT2 up
ip link set $BRNAME up

# 2つめのネットワークを作成する。
export BRNAME_ADD=vswitch1
export IF_INT3=v2-eth2
export IF_EXT3=v2-eth3

# 3つ目のペアの作成と設定
ip link add name $IF_INT3 type veth peer name $IF_EXT3
ip link set $IF_EXT3 netns $NSNAME2
ip netns exec $NSNAME2 ip link set $IF_EXT3 up
ip netns exec $NSNAME2 ip addr add 172.26.10.254/24 dev $IF_EXT3

# 4つ目のペアの作成
export NSNAME4=ns03
export IF_INT4=v3-eth0
export IF_EXT4=v3-eth1

ip netns add $NSNAME4
ip link add name $IF_INT4 type veth peer name $IF_EXT4
ip link set $IF_EXT4 netns $NSNAME4
ip netns exec $NSNAME4 ip link set $IF_EXT4 up
ip netns exec $NSNAME4 ip addr add 172.26.10.21/24 dev $IF_EXT4

# 同じくブリッジの作成と、vethの片側を接続
brctl addbr $BRNAME_ADD
brctl setfd $BRNAME_ADD 0
brctl addif $BRNAME_ADD $IF_INT3
brctl addif $BRNAME_ADD $IF_INT4
ip link set $IF_INT3 up
ip link set $IF_INT3 up
ip link set $BRNAME_ADD up

# ルーティングをネームスペース内に設定
ip netns exec $NSNAME1 route add default gw 172.26.0.254
ip netns exec $NSNAME3 route add default gw 172.26.10.254

brctl show

# ns01 から 同じセグメントの254へ
ip netns exec $NSNAME1 ping 172.26.0.254 -c 3

# ns01 から 隣のセグメントへ
ip netns exec $NSNAME1 ping 172.26.10.21 -c 3

ちゃんと設定できていると、ping応答が拾える。
このブリッジにKVM等からtapで接続してやることで、高度な仮想マシンのネットワーク環境を構成できるようになる。

OpenStackのQuantum等はこの機能を使っている。

0 件のコメント:

コメントを投稿