2016年10月、Arch LinuxとUbuntu16.04で動作確認してます。

$ sudo lxd init でエンター連打して作成される lxdbr0 (というかLXD管理下のブリッジ)では難しそうなので、別にブリッジを作成して設定していきます。

簡単に点順をまとめると

  1. IPv4の転送の有効化
  2. ブリッジの作成(netctl、bridge-utils)
  3. NATとブリッジを経由したパケット透過の設定(iptables)
  4. DNSとDHCPの設定(dnsmasq)

の4つの作業が必要となる。

IPv4の転送の有効化

$ sysctl net.ipv4.ip_forward      
net.ipv4.ip_forward = 0

となっていたら

$ echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

として有効化する

ブリッジの作成

netctlでやる(Arch向け)

/etc/netctl/lxdbr1 というファイルを作って

Description="LXD Bridge"
Interface=lxdbr1
Connection=bridge
BindsToInterfaces=()
IP=static
Address=10.0.40.1/24
SkipForwardingDelay=yes

と書き込んで、

$ sudo netctl start lxdbr1

でブリッジを作成し、

$ sudo netctl enable lxdbr1

で起動時に毎回勝手に作成するようにする。

bridge-utilsでやる(Ubuntuやその他向け)

/etc/network/interfaces

auto lxdbr1
iface lxdbr1 inet static
  address 10.0.40.1
  netmask 255.255.255.0
  bridge_ports all

を追記。bridge_ports allが無いと自動でブリッジが立ち上がらない。

ブリッジのNATとパケット透過許可の設定

iptablesサービスが使える場合

NATとブリッジを経由したパケットの透過を許可する設定をする。/etc/iptables/iptables.rules

*nat
-A POSTROUTING -s 10.0.40.1/24 -j MASQUERADE
COMMIT

*filter
-A FORWARD -i lxdbr1 -j ACCEPT
-A FORWARD -o lxdbr1 -j ACCEPT
COMMIT

って感じで記入。必要に応じて $ sudo systemctl restart iptables など。

注)iptablesのサービスを再起動すると、LXD管理下のブリッジ(デフォルトで作成されるlxdbr0など)の設定がリセットされて使えなくなる。dockerも同様にdocker0が使えなくなる。これはLXDもdockerもネットワーク周りをiptablesで設定していて、その設定がiptablesの再起動で消えてしまうためで、単純にLXDもdockerもサービスの再起動をすれば再設定されてまた使えるようになる(なんとなく釈然としないが)。

cf. Docker networking fails after iptables service is restarted · Issue #12294 · docker/docker

iptablesサービスが使えない場合(Ubuntu向け)

iptablesサービスというものがないので、/etc/rc.localなどに

iptables -t nat -A POSTROUTING -s 10.0.40.1/24 -j MASQUERADE
iptables -t filter -A FORWARD -i lxdbr1 -j ACCEPT   
iptables -t filter -A FORWARD -o lxdbr1 -j ACCEPT   

と書いておく。ll /etc/network/if-up.d/の下に上記を書いたものを置いても良い。起動時に実行されればどこでもいい。

ローカルDNSとDHCPの設定

dnsmasqを使うが、NetworkManagerプラグインとして使いたい派(というかその方が楽)なので、まず/etc/NetworkManager/NetworkManager.conf

dns=dnsmasq

を追記しておく。その後 /etc/NetworkManager/dnsmasq.d/lxd.confを作って

interface=lxdbr1
except-interface=lo
bind-interfaces
dhcp-range=10.0.40.2,10.0.40.254,1h
local=/lxd/
domain=lxd,10.0.40.1/24

と記入し、 sudo systemctl restart NetworkManager で再起動すればそ場で有効になる。

※XenialだとNetworkManagerdnsmasqプラグインだとうまく動かない可能性がある(たぶんバグ)ので、普通に /etc/dnsmasq.confに書いた方がいいかもしれない。

LXDの設定

lxd initでエンター連打したばあい)デフォルトだと lxdbr0 を使うようになってるので、

$ lxc profile edit default
name: default
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    nictype: bridged
-    parent: lxdbr0
+    parent: lxdbr1
    type: nic
usedby: []

で新しく作ったlxdbr1を使うように変更。

どうなるか

~ $ lxc launch xenial u1    
Creating u1
Starting u1
~ $ lxc list            
+------+---------+-------------------+------+------------+-----------+
| NAME |  STATE  |       IPV4        | IPV6 |    TYPE    | SNAPSHOTS |
+------+---------+-------------------+------+------------+-----------+
| u1   | RUNNING | 10.0.40.76 (eth0) |      | PERSISTENT | 0         |
+------+---------+-------------------+------+------------+-----------+
~ $ ping -c 1 u1.lxd
PING u1.lxd (10.0.40.76) 56(84) bytes of data.
64 bytes from u1.lxd (10.0.40.76): icmp_seq=1 ttl=64 time=0.047 ms

--- u1.lxd ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.047/0.047/0.047/0.000 ms

こんな感じになる。

執筆時2016年10月のUbuntu16.04だとLXDのバージョンが古くてlxc networkコマンドが無く不便なので、$ sudo apt install -t xenial-backports lxd でbackportsから新しいのを引っ張ってやると良い。

参考