🎉

network namespaceごとに/etc/ファイルを使い分ける

2022/06/11に公開

構成

以下の構成を考えます。Web3層モデルを究極的に簡素化したものです。


名前解決の問題

この環境でサーバの名前解決を/etc/hostsで行うことを考えます。

web01, db01のIPアドレスは10.0.1.10、10.0.2.12に解決すればよいので何も問題はないです。
ap01は10.0.1.11にすべきでしょうか?10.0.2.11にすべきでしょうか?

web01, ap01, db01が別のVMであればもちろんそれぞれ別の/etc/hostsを持つので、サーバによって/etc/hostsの内容を変えてあげればOKです。

web01サーバの/etc/hosts
127.0.0.1       localhost
10.0.1.11       ap01
db01サーバの/etc/hosts
127.0.0.1       localhost
10.0.2.11       ap01

ただ、network namespaceで仮想的に分割した場合、同じLinux上に"web01" network namespaceと"db01" network namespaceが同居して、Linux上の/etc/hostsを共有しています。

対処

man ip-netnsでマニュアルを見ると以下の記載があります。

For applications that are aware of network namespaces, the convention is to look for global network configuration files first in /etc/netns/NAME/ then in /etc/. For example, if you want a different version of /etc/resolv.conf for a network namespace used to isolate your vpn you would name it /etc/netns/myvpn/resolv.conf.

「/etc/nets/ネットワークネームスペース名/」配下にファイルを作ると「/etc/」の代わりに使われると書いてあります。

今回の目的を達成するには以下でOKです。

mkdir -p /etc/netns/web01/
/etc/hosts /etc/netns/web01/hosts
echo '10.0.1.11 ap01'>>/etc/netns/web01/hosts

mkdir -p /etc/netns/ap01/
cp /etc/hosts /etc/netns/ap01/hosts
echo '10.0.1.10 web01'>>/etc/netns/ap01/hosts
echo '10.0.2.12 db01'>>/etc/netns/ap01/hosts

mkdir -p /etc/netns/db01/
cp /etc/hosts /etc/netns/db01/hosts
echo '10.0.2.11 ap01'>>/etc/netns/db01/hosts

上記のコマンドで以下のファイルが作成されます。

/etc/netns/web01/hosts
127.0.0.1       localhost
10.0.1.11       ap01
/etc/netns/ap01/hosts
127.0.0.1       localhost
10.0.1.10       web01
10.0.2.12       db01
/etc/netns/db01/hosts
127.0.0.1       localhost
10.0.2.11       ap01

実行結果

この状態でweb01内でap01にPingすると10.0.1.11に名前解決され、db01内でap01にPingすると10.0.2.11に名前解決されます。うまいこと/etc/配下のファイルを使い分けることができました。

# ip netns exec web01 ping -c 1 ap01
PING ap01 (10.0.1.11) 56(84) bytes of data.
64 bytes from ap01 (10.0.1.11): icmp_seq=1 ttl=64 time=0.022 ms

--- ap01 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.022/0.022/0.022/0.000 ms
# ip netns exec db01 ping -c 1 ap01
PING ap01 (10.0.2.11) 56(84) bytes of data.
64 bytes from ap01 (10.0.2.11): icmp_seq=1 ttl=64 time=0.016 ms

--- ap01 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.016/0.016/0.016/0.000 ms

注意事項

この「/etc/nets/ネットワークネームスペース名/」のファイルで置き換える仕組みは「/etc/」配下に同名のファイルがある場合にだけ働きます。

具体的に言うと、/etc/aiueoというファイルが存在しない状況で/etc/netns/web01/aiueoファイルを作成し、web01内部でこのファイルを参照しようとしても失敗します。

# ls /etc/aiueo
ls: '/etc/aiueo' にアクセスできません: そのようなファイルやディレクトリはありません
# echo 12345 > /etc/netns/web01/aiueo
# ip netns exec web01 cat /etc/aiueo
Bind /etc/netns/web01/aiueo -> /etc/aiueo failed: No such file or directory
cat: /etc/aiueo: そのようなファイルやディレクトリはありません

からっぽのファイルでいいので/etc/aiueoを作成してあげると、先ほど失敗したweb01内部でのaiueoファイルの参照ができるようになります。

# touch /etc/aiueo
# ls /etc/aiueo
/etc/aiueo
# ip netns exec web01 cat /etc/aiueo
12345

参考:動作確認を行った環境について

# cat /etc/issue
Ubuntu 22.04 LTS \n \l

# uname -r
5.15.0-33-generic
# dpkg -l iproute2 iputils-ping
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name           Version         Architecture Description
+++-==============-===============-============-===============================================
ii  iproute2       5.15.0-1ubuntu2 amd64        networking and traffic control tools
ii  iputils-ping   3:20211215-1    amd64        Tools to test the reachability of network hosts

参考:資材

使ったファイルはこちらに置いてあります。興味があればどうぞ。

https://github.com/takai404/hakoniwa/tree/main/networks/etc_hosts

Discussion