2015年6月16日火曜日

Linux Network Namespace メモ

勉強資料

Introducing Linux Network Namespaces
チュートリアル形式で基礎が学べる

Linux Switching – Interconnecting Namespaces
veth ペアの基礎や Linux Bridge/Open vSwitch での 2 つの名前空間の接続が図入りで解説されている

Linux Network Namespace で遊んでみる
具体的なコマンド例が多数

network lxc Linux Containers
LXC とネットワーク名前空間を関連させた話
「ネットワーク名前空間は1つ以上のプロセスに割り当てられたプライベートなネットワークリソースの集合」

ifconfig vs ip
ifconfig は deprecated になりこれからは ip の時代。ということで具体例でコマンドの比較。

LXC と ネットワーク名前空間

veth ペアの片側を LXC コンテナの名前空間に移動させる

# lxc-info -n NAME
でそのコンテナの init の PID が分かる。その PID に対して
# ip link set VETHNAME netns PID
とやれば veth ペアの片側(VETHNAME で指定した側)が PID が属する名前空間に移動する。

移動後に確認するには下記コマンドを実行してみる。
# lxc-console -n NAME
でコンテナに入り込んでから
[root@arch1 ~]# ip link
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: veth-arch:  mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 3e:a5:f7:ed:54:9a brd ff:ff:ff:ff:ff:ff link-netnsid 0
みたいに VETHNAME がちゃんとコンテナに移動したことが分かる。(この例では VETHNAME = veth-arch)

veth ペアの片側を元の名前空間に引き戻す

普通、ある名前空間から別の名前空間にネットワークインタフェースを移動するには
# ip netns exec 移動元名前空間 ip link set インターフェース名 netns 移動先名前空間
としてやればよい。が、移動元名前空間が ip netns add 以外で作ったもの(LXC の名前空間はまさにそれ)である場合、名前空間に名前が付いてなくてコマンドが実行できない。

ということで、まずは一時的な名前空間名を付与してあげる。
# ln -s /proc/PID/ns/net /var/run/netns/NSNAME
PID はコンテナの PID で NSNAME は任意の名前空間名。/proc/PID/ns/net が「PID が属する名前空間」を表すファイルになっている。

とにかく /var/run/netns/ 以下に名前を付けてあげると ip コマンドが認識するという仕組み。(ここでは NSNAME = ns-arch1)
# ls /var/run/netns
ns-arch1
# ip netns list
ns-arch1 (id: 0)

こんな感じに名前が付けば、あとは ip netns exec コマンドを使うだけ。
# ip netns exec NSNAME ip link set VETHNAME netns NSNAME_TO

NSNAME_TO にはもちろん PID も指定できて、つまり 1 を指定してあげると元々の名前空間に VETHNAME が戻ってくる。親元に帰ってくる子どもみたいな感じ。

個人的には ip netns exec NSNAME にも PID を指定させてくれればいいのに、と思うけどなぜかそれは出来ないので、リンクを張るという技を使わざるを得ないようだ。
作ったリンクは iproute2 も LXC も管理してないものなので、必要が無くなったら手動で削除しておくのが望ましい。
# rm /var/run/netns/NSNAME

以上の知識はツイッターで教えていただいた。ありがとうございます。
https://twitter.com/Flast_RO/status/610953725054615552