概要
VirtualBox や VMware であれば、ゲストOS のネットワークインターフェイスを「ブリッジアダプター」に設定することで、ゲストOS で動く HTTPサーバーや SSHサーバーに対して LAN側から直接接続できるようになります。
同様に LXC/LXD でも、物理マシンであれば、ネットワークインターフェースに macvlan を設定することで、LXD上のコンテナに LAN側から直接接続できるそうですが、物理マシンが用意できなかったので、VirtualBox で動く Linux上の LXD コンテナに LAN側のマシンから接続できるようにする方法について、「How to make your LXD containers get IP addresses from your LAN using macvlan」などを参考に確認した時のメモです。
確認した構成
- ホストOS: MacOS Mojave
- 仮想化: VirtualBox 5.2 または 6.0
- VirtualBox上の OS: Ubuntu: 18.04
- コンテナ: LXD 3.0
- コンテナ上のOS: CentOS 7
前提としてホストOSは、有線でLANと接続している必要があります。無線LANではうまくいきませんでした。(無線LANで使われている IEEE802.11 の仕様で、複数のMACアドレスが使えないからだそうです。)
手順
次の 2つの方法で確認しました。
- macvlan を使うように設定したプロファイルを用意してコンテナを新規作成
→ ネットワークインターフェイスは macvlan だけ - bridged を使っている既存のコンテナに macvlan のネットワークインターフェースを追加
→ ネットワークインターフェイスは、既存の bridged に加えて macvlan の 2個になる
どちらの場合も次に説明するように VirtualBox と Ubuntu の両方でプロミスキャスモードを有効にしておく必要があります。
また、VirtualBox ではブリッジアダプターを使うようにします(コンテナなしで普通に Linux を動して LAN側から接続する場合と同じですね)。
VirtualBox 設定
VirtualBox で Ubuntu 18.04 のネットワークアダブター割り当てが「ブリッジアダプター」になっているかを確認します。なっていない場合は「ブリッジアダプター」に設定します。
合わせてブリッジアダプターのプロミスキャスモードが「すべて許可」に設定されているか確認します。なっていない場合は「すべて許可」に設定します。
Ubuntu 18.04 でのネットワーク設定
Ubuntu 18.04 が LAN と接続しているインターフェースを確認します。
ip route show default 0.0.0.0/0
default via 192.168.1.1 dev enp0s3 proto dhcp src 192.168.1.100 metric 100
上記の例では enp0s3 が LANに接続しているネットワークインターフェイスになります。
次に Ubuntu でプロミスキャスモードを有効にします。
sudo ip link set enp0s3 promisc on
または
sudo ifconfig enp0s3 promisc
Ubuntu 18.04 が起動したら、自動的にプロミスキャスモードになるようにする場合は、rc.local にコマンドを記述するなどしておきます。
sudo vi /etc/rc.local
#!/bin/sh
/sbin/ip link set enp0s3 promisc on
sudo chmod 755 /etc/rc.local
コンテナ設定
次にコンテナ側を設定していきます。
方法1: macvlan を使うように設定したプロファイルを用意してコンテナを新規作成する場合
default のプロファイルでは bridged ネットワークインターフェイスを使うように設定されています。
lxc profile show default
config: {}
description: Default LXD profile
devices:
eth0:
name: eth0
nictype: bridged
parent: lxdbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
そこで default プロファイルを lanprofile という名前でコピーします。
lxc profile copy default lanprofile
lanprofile で使用するネットワークインターフェイスを macvlan に変更します。
lxc profile device set lanprofile eth0 nictype macvlan
続けて先ほど ip route コマンドで確認した Ubuntu 18.04 が LANと接続しているネットワークインターフェイス(ここでは enp0s3)と関連付けます。
lxc profile device set lanprofile eth0 parent enp0s3
lanprofile の内容を確認します。
lxc profile show lanprofile
config: {}
description: Default LXD profile
devices:
eth0:
name: eth0
nictype: macvlan
parent: enp0s3
type: nic
root:
path: /
pool: default
type: disk
name: lanprofile
nictype が macvlan に、parent が enp0s3 になっています。
このプロファイルを使って CentOS 7 のコンテナを作成します。
lxc launch -p lanprofile images:centos/7/amd64 centos7
コンテナ上で動いている CentOS 7 のネットワーク状態を確認します。
lxc exec centos7 ip a s
6: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:11:22:33 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.101/24 brd 192.168.1.255 scope global dynamic eth0
valid_lft 86371sec preferred_lft 86371sec
inet6 fe80::216:3eff:fe11:2233/64 scope link
valid_lft forever preferred_lft forever
ここでは DHCP サーバから取得した IPアドレスが割り当てられています。
別のマシンからコンテナ上の CentOS 7 に対して ping を打ってみます。
ping 192.168.1.101
PING 192.168.1.101 (192.168.1.101): 56 data bytes
64 bytes from 192.168.1.101: icmp_seq=0 ttl=64 time=0.603 ms
方法2: bridged を使った既存のコンテナに macvlan のネットワークインターフェースを追加する場合
次のようなコマンドを実行すことで default プロファイルを使った CentOS 7 のコンテナを作成済みだとします。
(プロファイルを指定しないと、default プロファイルが使われます。
このコンテナに macvlan のネットワークインターフェイスを追加し、LAN側から接続できるようにしていきます。)
lxc launch images:centos/7/amd64 centos7-2
CentOS 7 コンテナのネットワーク状態を表示します。
lxc exec centos7-2 ip a s
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:11:22:34 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.13.73.225/24 brd 10.13.73.255 scope global dynamic eth0
valid_lft 3597sec preferred_lft 3597sec
inet6 fe80::216:3eff:fe11:2233/64 scope link
valid_lft forever preferred_lft forever
bridged インターフェイスの IPアドレスが使われています。
このままでは LAN側から直接接続することができません。
そこでコンテナOSを止めてから macvlan で enp0s3 と関連付けられた eth1 を CentOS 7 コンテナに追加します。
lxc stop centos7-2
lxc config device add centos7-2 eth1 nic name=eth1 nictype=macvlan parent=enp0s3
これだけでは IPアドレスが割り当てられませんので、コンテナOSを起動して、コンテナ内に DHCP サーバから IPアドレスを取得するよう、設定ファイルを作成します。
lxc start centos7-2
lxc exec centos7-2 vi /etc/sysconfig/network-scripts/ifcfg-eth1
記述する内容は次のような感じにしました。
DEVICE=eth1
BOOTPROTO=dhcp
ONBOOT=yes
HOSTNAME=centos7-2
NM_CONTROLLED=no
TYPE=Ethernet
DHCP_HOSTNAME=`hostname
設定ファイル ifcfg-eth1 を作成したら、CentOS 7 コンテナのネットワークをリスタートします。
lxc exec centos7-2 systemctl restart network
再度ネットワーク状態を表示します。
lxc exec centos7-2 ip a s
9: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:11:22:34 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.13.73.225/24 brd 10.13.73.255 scope global dynamic eth0
valid_lft 3596sec preferred_lft 3596sec
inet6 fe80::216:3eff:fea6:90a0/64 scope link
valid_lft forever preferred_lft forever
11: eth1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:11:22:35 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.1.102/24 brd 192.168.1.255 scope global dynamic eth1
valid_lft 86398sec preferred_lft 86398sec
inet6 fe80::216:3eff:fe11:2233/64 scope link
valid_lft forever preferred_lft forever
DHCP サーバーから IPアドレスが取得できていますので、別のマシンからコンテナ上の CentOS 7 に対して ping を打ってみます。
ping 192.168.1.102
PING 192.168.1.102 (192.168.1.102): 56 data bytes
64 bytes from 192.168.1.102: icmp_seq=0 ttl=64 time=0.347 ms