これは、なにをしたくて書いたもの?
Vagrantで時々プライベートIPアドレスを固定しているのですが、複数設定した時の挙動を見てみようかなと思いまして。
Vagrantのネットワーク設定
Vagrantのネットワーク設定には、Private NetworkとPublic Networkがあります。
Private Networks - Networking | Vagrant by HashiCorp
Public Networks - Networking | Vagrant by HashiCorp
Public Networkの方は、いわゆるブリッジですね。自分は、今のところ使う予定がないので、今回はPrivate Networkのみを見ていきます。
Private Networkは、ホスト側と通信できるネットワークを構成するものです。いわゆるNATでの構成ですね。
環境
今回の環境は、こちらです。Ubuntu Linux 18.04 LTSで、Vagrantは2.2.7です。
$ uname -srvmpio Linux 4.18.0-25-generic #26~18.04.1-Ubuntu SMP Thu Jun 27 07:28:31 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.4 LTS Release: 18.04 Codename: bionic $ vagrant -v Vagrant 2.2.7
VagrantのProviderとしては、libvirtを使用します。
$ vagrant plugin list vagrant-libvirt (0.0.45, global) - Version Constraint: > 0
使用するBoxとしては、ホスト側と同じくUbuntu Linux 18.04 LTSを使用します。
https://app.vagrantup.com/generic/boxes/ubuntu1804
こちらの環境で、プライベートIPアドレスを設定しないところから始めて、少しずつ設定を変えながら挙動を見てみましょう。
プライベートIPアドレス未設定の場合
まずは、なにも設定を変えずデフォルトのままで起動してみましょう。
「vagrant init」。
$ vagrant init generic/ubuntu1804
$ vagrant up $ vagrant ssh
起動した仮想マシンのネットワークインターフェースおよび、IPアドレスを確認してみましょう。
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:31:1c:53 brd ff:ff:ff:ff:ff:ff inet 192.168.121.3/24 brd 192.168.121.255 scope global dynamic eth0 valid_lft 3579sec preferred_lft 3579sec inet6 fe80::5054:ff:fe31:1c53/64 scope link valid_lft forever preferred_lft forever
ループバック以外に、eth0があります。これは、ホスト側からもアクセス可能なIPアドレスです。
ルーティングを確認。
$ ip route default via 192.168.121.1 dev eth0 proto dhcp src 192.168.121.3 metric 100 192.168.121.0/24 dev eth0 proto kernel scope link src 192.168.121.3 192.168.121.1 dev eth0 proto dhcp scope link src 192.168.121.3 metric 100
とりあえず、情報を見てみたので、仮想マシンを破棄します。
$ vagrant destroy -f
固定のプライベートIPアドレスを設定する
次は、仮想マシンにプライベートIP
Vagrantファイルの以下のようにコメントアウトされている部分を解除して、
# Create a private network, which allows host-only access to the machine # using a specific IP. # config.vm.network "private_network", ip: "192.168.33.10"
固定のプライベートIPアドレスを設定します。
config.vm.network "private_network", ip: "192.168.33.10"
Vagrantのドキュメントとしては、こちらですね。
$ vagrant up $ vagrant ssh
ネットワークインターフェースを確認してみます。
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:10:b8:0f brd ff:ff:ff:ff:ff:ff inet 192.168.121.192/24 brd 192.168.121.255 scope global dynamic eth0 valid_lft 3595sec preferred_lft 3595sec inet6 fe80::5054:ff:fe10:b80f/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:cd:58:c5 brd ff:ff:ff:ff:ff:ff inet 192.168.33.10/24 brd 192.168.33.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fecd:58c5/64 scope link valid_lft forever preferred_lft forever
eth1が増えましたね。こちらに、指定したプライベートIPアドレスが反映されています。eth0も存在していますが、こちらはDHCPですね。
ルーティングを確認。
$ ip route default via 192.168.121.1 dev eth0 proto dhcp src 192.168.121.192 metric 100 192.168.33.0/24 dev eth1 proto kernel scope link src 192.168.33.10 192.168.121.0/24 dev eth0 proto kernel scope link src 192.168.121.192 192.168.121.1 dev eth0 proto dhcp scope link src 192.168.121.192 metric 100
確認したので、仮想マシンを破棄。
$ vagrant destroy -f
今回はIPアドレスのみ指定しましたが、ネットマスクを指定することもできます。
たとえば、こんな感じで。
config.vm.network "private_network", ip: "10.0.0.10", netmask: "16"
仮想マシンを起動してSSH接続し、ネットワークインターフェースの確認をしてみます。
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:cc:f4:c2 brd ff:ff:ff:ff:ff:ff inet 192.168.121.3/24 brd 192.168.121.255 scope global dynamic eth0 valid_lft 3578sec preferred_lft 3578sec inet6 fe80::5054:ff:fecc:f4c2/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:4e:5e:b3 brd ff:ff:ff:ff:ff:ff inet 10.0.0.10/16 brd 10.0.255.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fe4e:5eb3/64 scope link valid_lft forever preferred_lft forever
ネットマスクが、指定した16になっていますね。デフォルトのネットマスクは、24ということですね。
※IPv6はまた別。
ルーティング。
$ ip route default via 192.168.121.1 dev eth0 proto dhcp src 192.168.121.3 metric 100 10.0.0.0/16 dev eth1 proto kernel scope link src 10.0.0.10 192.168.121.0/24 dev eth0 proto kernel scope link src 192.168.121.3 192.168.121.1 dev eth0 proto dhcp scope link src 192.168.121.3 metric 100
ちなみに、DHCPでも割り当てることができます。こちらで割り当てられているIPアドレスに、「vagrant ssh」で接続していることに
なっているようですね。
eth0に残っていたのは、デフォルトで作られるネットワークインターフェースだと思うので、Private Networkの設定を行うと、
実質「ネットワークインターフェースを追加する」ということになりそうな感じですね。
仮想マシン間の通信を行う
最後に、仮想マシンを2つ用意して、以下のような通信を行ってみましょう。
仮想マシン1で動作するApacheは、仮想マシン2で動作するApacheへのリバースプロキシとして動作させます。
仮想マシン1には2つのプライベートIPアドレス(192.168.33.10、10.0.0.10)を与え、ホスト側からは仮想マシン1の192.168.33.10に
対してHTTPリクエストを投げ、仮想マシン2へはソースIPが10.0.0.10となっていることが確認できればOKです。
同じサブネットの方のIPアドレスを使ってくれますよね、と。
仮想マシン1の作成。
$ vagrant init generic/ubuntu1804
プライベートIPアドレスは、以下のように設定します。
config.vm.network "private_network", ip: "192.168.33.10" config.vm.network "private_network", ip: "10.0.0.10"
$ vagrant up $ vagrant ssh
ネットワークインターフェースを見てみます。eth1、eth2が追加されていますね。
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:b4:15:04 brd ff:ff:ff:ff:ff:ff inet 192.168.121.202/24 brd 192.168.121.255 scope global dynamic eth0 valid_lft 3308sec preferred_lft 3308sec inet6 fe80::5054:ff:feb4:1504/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:64:ce:38 brd ff:ff:ff:ff:ff:ff inet 192.168.33.10/24 brd 192.168.33.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fe64:ce38/64 scope link valid_lft forever preferred_lft forever 4: eth2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:e2:ba:6c brd ff:ff:ff:ff:ff:ff inet 10.0.0.10/24 brd 10.0.0.255 scope global eth2 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fee2:ba6c/64 scope link valid_lft forever preferred_lft forever
ルーティングも見てみます。eth1の分も増えていますね。
$ ip route default via 192.168.121.1 dev eth0 proto dhcp src 192.168.121.202 metric 100 10.0.0.0/24 dev eth2 proto kernel scope link src 10.0.0.10 192.168.33.0/24 dev eth1 proto kernel scope link src 192.168.33.10 192.168.121.0/24 dev eth0 proto kernel scope link src 192.168.121.202 192.168.121.1 dev eth0 proto dhcp scope link src 192.168.121.202 metric 100
次に、仮想マシン2の作成。
$ vagrant init generic/ubuntu1804
仮想マシン2には、プライベートIPアドレスをひとつ設定します。
config.vm.network "private_network", ip: "10.0.0.11"
$ vagrant up $ vagrant ssh
ネットワークインターフェースの確認。
$ ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:0a:0c:ac brd ff:ff:ff:ff:ff:ff inet 192.168.121.87/24 brd 192.168.121.255 scope global dynamic eth0 valid_lft 3349sec preferred_lft 3349sec inet6 fe80::5054:ff:fe0a:cac/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 52:54:00:3f:ad:e3 brd ff:ff:ff:ff:ff:ff inet 10.0.0.11/24 brd 10.0.0.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::5054:ff:fe3f:ade3/64 scope link valid_lft forever preferred_lft forever
ルーティングの確認。
$ ip route default via 192.168.121.1 dev eth0 proto dhcp src 192.168.121.87 metric 100 10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.11 192.168.121.0/24 dev eth0 proto kernel scope link src 192.168.121.87 192.168.121.1 dev eth0 proto dhcp scope link src 192.168.121.87 metric 100
仮想マシンの準備ができたので、Apacheをインストールしましょう。仮想マシン1、仮想マシン2のいずれにも、Apacheをインストールします。
$ sudo apt install apache2
仮想マシン1側のみ、リバースプロキシとして構築するので、mod_proxyおよびmod_proxy_httpを有効にします。
$ sudo a2enmod proxy proxy_http
仮想マシン2へのリバースプロキシとして設定。
/etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined ProxyPass / http://10.0.0.11 ProxyPassReverse / http://10.0.0.11 </VirtualHost>
Apacheを再起動します。
$ sudo systemctl restart apache2
また、仮想マシン2の方は、アクセス確認のためにindex.htmlを変更します(HTMLになってないですけど)。
/var/www/html/index.html
Hello Apache!!
ここで、ホスト側から仮想マシン1に対してHTTPリクエストを投げます。
$ curl -i 192.168.33.10 HTTP/1.1 200 OK Date: Sat, 11 Apr 2020 13:14:34 GMT Server: Apache/2.4.29 (Ubuntu) Last-Modified: Sat, 11 Apr 2020 13:13:03 GMT ETag: "f-5a3039c1f6fed" Accept-Ranges: bytes Content-Length: 15 Content-Type: text/html Hello Apache!!
まず、仮想マシン2まで到達していることが確認できました。
192.168.33.1 - - [11/Apr/2020:13:14:34 +0000] "GET / HTTP/1.1" 200 241 "-" "curl/7.58.0"
次に、仮想マシン2のApacheのアクセスログを確認します。ソースIPが、仮想マシン1の「10.0.0.10」となっています。
10.0.0.10 - - [11/Apr/2020:13:14:34 +0000] "GET / HTTP/1.1" 200 297 "-" "curl/7.58.0"
想定通りの挙動ですね。
tcpdumpでも、パケットを見ておきました。
$ sudo tcpdump -i any tcp port 80 -n tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes 13:14:34.437266 IP 192.168.33.1.36380 > 192.168.33.10.80: Flags [S], seq 4126635863, win 29200, options [mss 1460,sackOK,TS val 1069883733 ecr 0,nop,wscale 7], length 0 13:14:34.437347 IP 192.168.33.10.80 > 192.168.33.1.36380: Flags [S.], seq 3231866269, ack 4126635864, win 65160, options [mss 1460,sackOK,TS val 3515437649 ecr 1069883733,nop,wscale 7], length 0 13:14:34.437425 IP 192.168.33.1.36380 > 192.168.33.10.80: Flags [.], ack 1, win 229, options [nop,nop,TS val 1069883733 ecr 3515437649], length 0 13:14:34.437448 IP 192.168.33.1.36380 > 192.168.33.10.80: Flags [P.], seq 1:78, ack 1, win 229, options [nop,nop,TS val 1069883733 ecr 3515437649], length 77: HTTP: GET / HTTP/1.1 13:14:34.437478 IP 192.168.33.10.80 > 192.168.33.1.36380: Flags [.], ack 78, win 509, options [nop,nop,TS val 3515437649 ecr 1069883733], length 0 13:14:34.437759 IP 10.0.0.10.39794 > 10.0.0.11.80: Flags [F.], seq 3809542179, ack 1644144670, win 501, options [nop,nop,TS val 3564697986 ecr 3477033970], length 0 13:14:34.437815 IP 10.0.0.10.39796 > 10.0.0.11.80: Flags [S], seq 1591844355, win 64240, options [mss 1460,sackOK,TS val 3564697986 ecr 0,nop,wscale 7], length 0 13:14:34.438097 IP 10.0.0.11.80 > 10.0.0.10.39794: Flags [.], ack 1, win 508, options [nop,nop,TS val 3477042455 ecr 3564697986], length 0 13:14:34.438117 IP 10.0.0.11.80 > 10.0.0.10.39796: Flags [S.], seq 3826655060, ack 1591844356, win 65160, options [mss 1460,sackOK,TS val 3477042456 ecr 3564697986,nop,wscale 7], length 0 13:14:34.438129 IP 10.0.0.10.39796 > 10.0.0.11.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 3564697986 ecr 3477042456], length 0 13:14:34.438182 IP 10.0.0.10.39796 > 10.0.0.11.80: Flags [P.], seq 1:193, ack 1, win 502, options [nop,nop,TS val 3564697986 ecr 3477042456], length 192: HTTP: GET / HTTP/1.1 13:14:34.438291 IP 10.0.0.11.80 > 10.0.0.10.39796: Flags [.], ack 193, win 508, options [nop,nop,TS val 3477042456 ecr 3564697986], length 0 13:14:34.439187 IP 10.0.0.11.80 > 10.0.0.10.39796: Flags [P.], seq 1:298, ack 193, win 508, options [nop,nop,TS val 3477042457 ecr 3564697986], length 297: HTTP: HTTP/1.1 200 OK 13:14:34.439201 IP 10.0.0.10.39796 > 10.0.0.11.80: Flags [.], ack 298, win 501, options [nop,nop,TS val 3564697987 ecr 3477042457], length 0 13:14:34.439327 IP 192.168.33.10.80 > 192.168.33.1.36380: Flags [P.], seq 1:242, ack 78, win 509, options [nop,nop,TS val 3515437651 ecr 1069883733], length 241: HTTP: HTTP/1.1 200 OK 13:14:34.439381 IP 192.168.33.1.36380 > 192.168.33.10.80: Flags [.], ack 242, win 237, options [nop,nop,TS val 1069883735 ecr 3515437651], length 0 13:14:34.439469 IP 192.168.33.1.36380 > 192.168.33.10.80: Flags [F.], seq 78, ack 242, win 237, options [nop,nop,TS val 1069883735 ecr 3515437651], length 0 13:14:34.439543 IP 192.168.33.10.80 > 192.168.33.1.36380: Flags [F.], seq 242, ack 79, win 509, options [nop,nop,TS val 3515437652 ecr 1069883735], length 0 13:14:34.439650 IP 192.168.33.1.36380 > 192.168.33.10.80: Flags [.], ack 243, win 237, options [nop,nop,TS val 1069883736 ecr 3515437652], length 0
なんとなく、確認しておくと安心かな、というPrivate Networkの設定回りでした、と。