TenForward

技術ブログ。はてなダイアリーから移転しました

LXD コンテナに物理NICを直接与える

あまり役に立たないメモです。

コンテナホスト上でコンテナを起動する場合、ホスト上にブリッジを作成し、そこにアタッチする veth インターフェースを接続する場合が多いかと思います。

しかし、ベアメタル上に物理 NIC が多数あったり、SR-IOV で物理 NIC 上で仮想的な NIC が多数作成できる場合は、LXD コンテナに直接 NIC をアタッチできます(ただし、最新の LXD は SR-IOV 対応していたのでこのブログエントリは関係ないかも? < 良く知らない)。

コンテナホスト上にブリッジを作成し、veth でアタッチしてコンテナを起動する場合、コンテナに割り当てる profile は default として、veth でホスト上のブリッジにアタッチするデバイスが定義されています(環境依存です)。

ホスト上の NIC を直接割り当てる場合はこのような profile は無駄ですので、一旦デバイスとして nic が存在しないコンテナ用 profile を作成します。これは default プロファイルをコピーすれば良いでしょう。

LXD 用に、ネットワークは定義しないプロファイル nonet を定義しましょう。defaultlxd init 時に設定されそうなので環境依存だと思う)をコピーして lxc profile edit nonet とかやるとエディタで編集できます。

$ lxc profile copy default nonet
$ lxc profile edit nonet
$ lxc profile show nonet
config: {}
description: Default LXD profile
devices:
  root:
    path: /
    pool: default
    type: disk
name: nonet
used_by: []

コンテナを作ります。

$ lxc init ubuntu:18.04 --profile=nonet
Creating the container
Container name is: still-hamster              
$ lxc list
+---------------+---------+------+------+------------+-----------+
|     NAME      |  STATE  | IPV4 | IPV6 |    TYPE    | SNAPSHOTS |
+---------------+---------+------+------+------------+-----------+
| still-hamster | STOPPED |      |      | PERSISTENT | 0         |
+---------------+---------+------+------+------------+-----------+

ネットワーク設定のないコンテナが作られます。

$ lxc config show still-hamster | grep devices
devices: {}

ここで、ホスト上にあるけど使われていない物理 NIC を確認してみましょう。次のようなアドレスも割当らず、UP していないインターフェース eth1 がありました。この eth1 が接続されているネットワークには DHCP サーバがあり、そこからアドレスがもらえるとします。

$ ip a
  : (snip)
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 0e:9a:02:d4:20:38 brd ff:ff:ff:ff:ff:ff

これを先ほど作成したコンテナ still-hamster に割り当てます。

$ lxc config device add still-hamster eth0 nic nictype=physical name=eth0 parent=eth1
Device eth0 added to still-hamster

これでコンテナ内に eth0 という名前で、ホスト上の eth1 が割り当たります。

$ lxc config show still-hamster
  : (snip)
devices:
  eth0:
    name: eth0
    nictype: physical
    parent: eth1
    type: nic
  : (snip)

コンテナを起動します。

$ lxc start still-hamster 
$ lxc list
+---------------+---------+--------------------+------+------------+-----------+
|     NAME      |  STATE  |        IPV4        | IPV6 |    TYPE    | SNAPSHOTS |
+---------------+---------+--------------------+------+------------+-----------+
| still-hamster | RUNNING | 10.7.11.252 (eth0) |      | PERSISTENT | 0         |
+---------------+---------+--------------------+------+------------+-----------+

起動してアドレスも割当たっています。ちなみに Ubuntu:18.04 イメージでは、DHCP でアドレスをもらえる設定がなされています。

$ lxc exec still-hamster -- cat /etc/netplan/50-cloud-init.yaml
  : (snip)
network:
    version: 2
    ethernets:
        eth0:
            dhcp4: true

コンテナ内でルーティングテーブルを見てみると次のようにちゃんと割当たっていることがわかります。

$ lxc exec still-hamster -- ip route show table main
default via 10.7.0.1 dev eth0 proto dhcp src 10.7.11.252 metric 100 
10.7.0.0/16 dev eth0 proto kernel scope link src 10.7.11.252 
10.7.0.1 dev eth0 proto dhcp scope link src 10.7.11.252 metric 100 

ちなみに、コンテナが起動した状態で eth1 を確認してみると、eth1 はコンテナの namespace に移動していますので、ホスト上からは見えません。

$ ip a | grep eth1
$ 

ここでは LXD での例を示しましたが、LXC でも設定ファイルにネットワークで物理インターフェースを指定することで同じことができます。