libvirtは構成定義ファイルに従い、仮想ネットワークを作成する。
KVMインストールデフォルトの状態では、defaultネットワークが設定される。
これを手動で設定することで、どのようなに実現されているか理解する。
インストールデフォルトの状態
仮想ネットワーク構成定義
# virsh net-dumpxml default <network> <name>default</name> <uuid>74b8baf4-6ebb-41d3-8cea-5b42efad0b89</uuid> <forward mode='nat'> <nat> <port start='1024' end='65535'/> </nat> </forward> <bridge name='virbr0' stp='on' delay='0'/> <mac address='52:54:00:d0:13:d6'/> <ip address='192.168.122.1' netmask='255.255.255.0'> <dhcp> <range start='192.168.122.2' end='192.168.122.254'/> </dhcp> </ip> </network> #
/etc/libvirt/qemu/networks/default.xml ファイルの中身と同じ。
libvirtは、これをインプットとし仮想ネットワークを生成している。
ネットワークデバイス
# ip -d link ※-dオプションをつけるとタイプ(tun/bridge/)も表示される。 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 addrgenmode eui64 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 08:00:27:db:6e:6a brd ff:ff:ff:ff:ff:ff promiscuity 0 addrgenmode eui64 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 0 bridge forward_delay 200 hello_time 200 max_age 2000 addrgenmode eui64 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 1 tun bridge_slave addrgenmode eui64 # ip -d a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:db:6e:6a brd ff:ff:ff:ff:ff:ff promiscuity 0 inet 192.168.43.197/24 brd 192.168.43.255 scope global dynamic enp0s3 valid_lft 3229sec preferred_lft 3229sec inet6 fe80::a00:27ff:fedb:6e6a/64 scope link valid_lft forever preferred_lft forever 3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 0 bridge forward_delay 200 hello_time 200 max_age 2000 inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever 4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 1 tun bridge_slave #
ネットワークデバイスにはTypeがあり。
virbr0はTypeがbridge
virbr0-nicはTypeがtun
tunについては、以下URL参照。
iproute2 cheat sheet
type tunはユーザースペースのプログラムが使える仮想ネットワークデバイスファイル。
仮想マシンのネットワーク通信に利用。ソケットのようなもの。
ソケットはtcp/udpポート番号指定。tun/tapは、より低レイヤーの通信を扱える。
type tunは更にtapとtunに分かれる。
tapはL2フレームの送受信をするデバイスファイル
tunはIPパケットの送受信をするデバイスファイル
仮想ブリッジ
# brctl show bridge name bridge id STP enabled interfaces virbr0 8000.525400d013d6 yes virbr0-nic #
iptables
# iptables -L -n -v Chain INPUT (policy ACCEPT 1617 packets, 998K bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67 Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED 0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0 0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0 0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable 0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable Chain OUTPUT (policy ACCEPT 780 packets, 966K bytes) pkts bytes target prot opt in out source destination 0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68 # iptables -L -n -t nat -v Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain INPUT (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 Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 RETURN all -- * * 192.168.122.0/24 224.0.0.0/24 0 0 RETURN all -- * * 192.168.122.0/24 255.255.255.255 0 0 MASQUERADE tcp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE udp -- * * 192.168.122.0/24 !192.168.122.0/24 masq ports: 1024-65535 0 0 MASQUERADE all -- * * 192.168.122.0/24 !192.168.122.0/24
dnsmasq
# ps -C dnsmasq -o command COMMAND /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper #
defaultネットワークを無効化した状態
以下コマンドでefaultネットワークを無効化
# virsh net-destroy default Network default destroyed
ネットワークデバイス
# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 08:00:27:db:6e:6a brd ff:ff:ff:ff:ff:ff # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 08:00:27:db:6e:6a brd ff:ff:ff:ff:ff:ff inet 192.168.43.197/24 brd 192.168.43.255 scope global dynamic enp0s3 valid_lft 3387sec preferred_lft 3387sec inet6 fe80::a00:27ff:fedb:6e6a/64 scope link valid_lft forever preferred_lft forever #
仮想ブリッジ
# brctl show bridge name bridge id STP enabled interfaces #
iptables
# iptables -L -n -v Chain INPUT (policy ACCEPT 49 packets, 3336 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 26 packets, 3624 bytes) pkts bytes target prot opt in out source destination # iptables -L -n -t nat -v Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain INPUT (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 Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination #
dnsmasq
# ps -C dnsmasq -o command COMMAND #
手動設定
仮想ブリッジ(virbr0)作成
brctlコマンドで作るかと思いきや、brctlコマンドではMACアドレスが指定できないっぽい。ipコマンドで作っていると想定される。
# ip link add virbr0 type bridge # ip link set dev virbr0 address 52:54:00:d0:13:d6 # ip addr add 192.168.122.1/24 brd 192.168.122.255 dev virbr0 # brctl setfd virbr0 2
→STP関連設定?
http://www.tldp.org/HOWTO/BRIDGE-STP-HOWTO/set-up-the-bridge.html
Sets the forwarding delay time. The forwarding delay time is the time spent in each of the Listening and Learning states before the Forwarding state is entered.
これでdefaultのvirbr0とip -d link・ip -d aコマンドの結果が同じになる。
# ip -d link show virbr0 5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 0 bridge forward_delay 200 hello_time 200 max_age 2000 addrgenmode eui64 # ip -d a show virbr0 5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 0 bridge forward_delay 200 hello_time 200 max_age 2000 inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever #
TUN/TAPデバイスv(irb0-nic)生成
次にvirb0-nicを作る。typeはtun(tun/tap)。
http://baturin.org/docs/iproute2/#Tun%20and%20Tap%20devices
以下で作成
# ip tuntap add dev virbr0-nic mode tap # ip link set dev virbr0-nic address 52:54:00:d0:13:d6 master virbr0 # ip link set virbr0 up # ip link set virbr0-nic up
※tapを指定する。tunで作ると、ip -d aコマンドの結果が異なった。(POINTOPOINTがついた)
# ip -d a show virbr0-nic 13: virbr0-nic: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN qlen 500 link/none promiscuity 0 tun
※削除する時は、以下の様にmodeも指定する必要あり。
ip tuntap add dev virbr0-nic mode tap
これでdefaultのvirbr0とip -d link・ip -d aコマンドの結果が同じになる。
# ip -d link show dev virbr0-nic 6: virbr0-nic: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 1 tun bridge_slave addrgenmode eui64 # ip -d a show dev virbr0-nic 6: virbr0-nic: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN qlen 1000 link/ether 52:54:00:d0:13:d6 brd ff:ff:ff:ff:ff:ff promiscuity 1 tun bridge_slave #
※IFをupしないと、virbr0-nicのqdiscのパラメタがnoopになった。以下URLを参考にしたが、分からず。IFをupしたら、pfifo_fastになった。
http://inokara.hateblo.jp/entry/2016/02/14/191853
※NO-CARRIERでが異なるが、以下URLを見るとケーブルがつながってない状態を示すよう。これは問題なし。
http://blog.goo.ne.jp/takuminews/e/3ada9ac4a3bfaf6d9f35b284a9b6eb58
dnsmasq構成
そもそもdnsmasqとは
dnsmasqで始めるプライベートDNSサーバ - GeekFactory
→手軽なDNS/DHCPサーバ
→hostsファイルをゾーンファイルにできる。
→管理外ドメインのクエリを受け付け、OSリゾルバ設定に従い代理応答する。
dnsmasqでDNSおよびDHCPサービスを強化する | OSDN Magazine
→dhcpを有効にするには、dhcp-range=にレンジ記載する。
→DGWをDHCPクライアントに提供するには、dhcp-option=3,DGWのIP。3がDGWを意味するオプション
→同一ホストに常に同じ名前/IPを割り当てたい時。dchp-host=MACアドレス,IPアドレス,名前
kvmによるdnsmasqの起動状態は
# systemctl list-unit-files | egrep dnsmasq dnsmasq.service disabled # ps -C dnsmasq -o command= /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper #
自動起動は無効。libvirtが起動してるとよう。
NWごとに起動される。設定ファイルは/var/lib/libvirt/dnsmasq/NW名.conf
起動オプションの意味は以下の通り。
・--conf-file
コンフィグファイルの指定。デフォルトは/etc/dnsmasq.conf
・--leasefile-ro
リースファイルは使わない。dhcp-scriptで指定されたスクリプトでリース状況を管理する場合などに指定されるオプション
・--dhcp-script
DHCPリース・破棄するスクリプト
コンフィグファイルとスクリプトが重要そう。
内容を確認する。
conf-fileの内容
# cat /var/lib/libvirt/dnsmasq/default.conf ##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE ##OVERWRITTEN AND LOST. Changes to this configuration should be made using: ## virsh net-edit default ## or other application using the libvirt API. ## ## dnsmasq conf file created by libvirt strict-order pid-file=/var/run/libvirt/network/default.pid except-interface=lo bind-dynamic interface=virbr0 dhcp-range=192.168.122.2,192.168.122.254 dhcp-no-override dhcp-lease-max=253 dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts #
・コメント部分
libvirtが自動生成したファイルだから変更するな!変更する時は、net-edit使え。
・strict-order
resolv.confの順番をしっかり守れ。守らないと意図しないサーバが応答してしまうケースを想定?
・except-interface=lo
ループバックデバイスではlistenしない。
・bind-dynamic
動的に生成されたインターフェースでもlistenする。libvirtが作るインターフェースでlistenするってことでしょう。
・interface
ここで指定されたインターフェースだけでlistenする。(loは自動的に追加される?)。
基本的に内部NW以外では動作させないってことでしょう。(ホストサーバの外部ホストと通信するIFではlistenさせない。)
・dhcp-range
DHCPレンジ
・dhcp-no-override
よく分からない。pxebootで使うDHCPサーバとfilenameの情報の扱いを制御
・dhcp-lease-max
dhcpリースの上限する。デフォルトは1000
・dhcp-hostsfile
dhcp-hostsオプションのファイル保存版。
ファイル変更でDHCP割り当て変更可能にする。(dnsmasqの再起動不要・SIGHUPシグナル受信時に再読み込み)
仮想マシン作成時は以下となった。
・addn-hosts
追加の名前解決用ファイル
※上記はmanより調査
スクリプトの内容
# file /usr/libexec/libvirt_leaseshelper /usr/libexec/libvirt_leaseshelper: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=7c1aff42497cf9a60d3db90e8a6391c4b7f30626, stripped #
バイナリファイルだった。。。
残り調査項目
★virbr0-nicとdnsmasqの関係性有無について調査
★iptablesによるNAT実装
★実際に仮想マシンを接続して通信確認
★dnsmasqを活用したPXEBoot