LXD 使ってみた

内容

LXDの導入、bridge, macvlanのコンテナを作成するまで

LXDについて

LXD は次世代のシステムコンテナーおよび仮想マシンのマネージャーです。 コンテナーあるいは仮想マシンの内部で稼働する完全な Linux システムに対して統一されたユーザーエクスペリエンスを提供します。

いろいろな Linux ディストリビューション のあらかじめビルドされたイメージを使ったイメージベースのマネージャーであり、非常に強力でありながら、非常にシンプルに、REST API を使って構築されます。

はじめに - LXDドキュメント翻訳プロジェクト

導入は簡単だったが、VM/物理マシンでのネットワークの設定で戸惑った。。

環境

Ubuntu 20.04 LTS (物理マシン)

よさげLink

linuxcontainers.org

linuxcontainers.org

よく使うコマンドリスト(ページ下部)


install

linuxcontainers.org

snapでパッケージインストール

# snap install lxd

バイナリからインストールもできるよう。

起動、初期設定

/etc/sysctl.confnet.ipv4.ip_forward=1のコメントを外しておく。←いらないかも?

lxdグループに入っていたら、sudoなしでlxdlxcコマンドを利用できる。

# lxd init

今回は、すべてデフォルト設定にした。(lxd init --auto)

image

lxd-ja.readthedocs.io

OSimageは配布されているものを使う。それを基にしたオリジナルimageを使うことも可能。
配布imageにはUbuntuCentOSなどバージョンも多くの種類が用意されている。
Cloud-initが動作する/しないimage、vmバージョンのimageなど様々。

imageの検索

lxc image list [image_server]: [keyword] ..

# lxc image list images: amd64 gentoo

インスタンスの実行

lxc launch [image_server]:[image_alias] [name] [flags]

# lxc launch ubuntu:f uf1

[flags]--vmとすれば、VMが起動する。

今回使ったものは、ubuntu:f

インスタンスを操作

名前を指定してインスタンスにコマンドを実行させる。

名前はlxc listなどで確認する。

lxc exec [name] -- [command]

# lxc exec uf1 bash

--はなくてもいいが、オプションを渡す場合はこれをつけないとうまくいかない。

また、コンテナ側でリダイレクトを利用するときは、bash -c 'echo hoge > /tmp/hoge.txt'というようにまとめてから実行させないと、ホスト側にリダイレクトされるので注意。

ネットワークについて

ここまではGettingStartedをみればできるが、ネットワークの設定で躓いた。

lxd-ja.readthedocs.io

まず、インスタンスの設定項目にはnetworkprofileがある。

network

ip lで出てくるデバイスについて詳細を見る

# lxc network show lxdbr0

lxdbr0は、デフォルト設定でlxd initすれば作成されるデバイス
インスタンスを作成するとき、デフォルトではこれがbridgeとして使われる。

bridgeというのは、ネットワークタイプの設定で、ほかにはmacvlanovnなどがある。

bridgeは、ホストからインスタンスには通信可能だが、外部からインスタンスには通らない。(private)
macvlanは、ホストの有線nI/Fを使う(ブリッジする)必要がある(複数のMACアドレスを扱うため。無線は複数MACに対応していないらしい)。外部からインスタンスにアクセスできる(public)

macvlanを使う場合は、ブリッジするホストのデバイスDHCPをオンにしておく必要がある。今回は、/etc/netplan/のconfigからdhcp4: trueとなっているのを確認。

VM(VBox)では、インスタンスから外部に通信できないなどうまくできなかった。
物理マシンでは、アパート管理のDHCPサーバーを利用しているためか、ipの割り振りが時々されず。。
結局、安定しているbridgeを使うことにした。
外部からホストを中継してsshすればアクセスできる(後述)し、 bridgeなら、ホストマシンのlxddnsmasq(lxdのdnsmasqなので、マシンに入れていなくておkだしsystemd-resolvedとの競合もなさげ。)を使ってDHCP割り振りを行っているので管理しやすい。

profile

profileは、インスタンスの設定をテンプレにしたもので、何のprofileを適用するかlaunch時に指定できる。
デフォルトではdefaultというのが使われる。オリジナルのprofileを作るときはこれを基に書き換えるなどする。
defaultにはnetwork: lxdbr0とあるため、デフォルトインスタンスlxdbr0bridgeとなる。

# lxc profile show default

例えばmacvlanのインスタンスを作成するprofileを作成する場合

# lxc profile copy default mvlprof
# lxc profile edit mvlprof

とすることで、viを使って編集できる。

このように設定した。

config: {}
description: MACVLAN profile
devices:
  eth0:
    name: eth0
    nictype: macvlan
    parent: enp1s0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: mvlprof
used_by: []

parentの値は、ip lで出てくる有線デバイス

これを適用してlaunchすると、macvlanのインスタンスが作成される。

# lxc launch -p mvlprof ubuntu:f mvluf1
# lxc list

(launchしただけのときにparentの範囲のipが振られていない場合は、インスタンスを再起動する。)
# lxc restart mvluf1

外部からpingを通してみる

$ ping [instance_ip]

64 bytes from 192.168.12.16: icmp_seq=1 ttl=63 time=4.67 ms
...

ipの固定

作成
lxc network attach [network] [instance_name] [insatnce_new_I/F]
割り当て
lxc config device set [instance_name] [instance_new_I/F] ipv4.address [ip_address]

# lxc network attach lxdbr0 uf1 eth1
# lxc config device set uf1 eth1 ipv4.address 10.91.103.50
(反映させるためにインスタンスの再起動または dhclient を実行させる)
# lxc restart uf1
または
# lxc exec uf1 dhclient eth1

新しくインスタンス内のネットワークデバイスを作成して割り当てている。
だが、既存のデバイスを指定してもおk。
lxc config device set uf1 eth0 ipv4.address 10.91.103.50のようにすると、eth0に2つのipを割り当てることになる。


個人的に、"network"と"profile"の関係性を整理するのに少し躓いた。

networkip aで出るあのデバイス(正しくはlxc network listで出るやつ)のことで、
profileには、それらのどれを物理デバイスとして使うか、ソフト的にはbridgeやmacvlanなどどれを使うのか、を記述している。

…という認識。

/sbin/initが動くので、ansibleのテスト環境としてよさそうに思う。 imageの、cloud-init動作版やvm版との違いがまだわからないが、VMより軽快なのでansibleの簡易テスト環境として使ってみる所存。

よく使うコマンドリスト

状態確認

lxc network show lxdbr0
lxc network list
lxc profile show default
lxc profile list
lxc config device show default
lxc config device show uf1
lxc config device list uf1
lxc config show uf1 --expanded

// dnsmasq leases
cat /var/snap/lxd/common/lxd/networks/lxdbr0/dnsmasq.leases
lxc network list-leases

ネットワーク関連

networkデバイス新規作成
# lxc network create newbr0
defaultを流用してnetworkを作成
# lxc profile copy default ufnet
書き換え(bridgeなら lxdbr0 を ufnet に書き換えるだけ)
# lxc profile edit ufnet

profileの変更
# lxc profile assign uf1 ufnet
lxdbr0を利用してコンテナ内のeth1としてネットワークデバイスを作成
# lxc network attach lxdbr0 uf1 eth1
固定IPを設定(lxdbr0のsubnet範囲内)
# lxc config device set uf1 eth1 ipv4.address 10.91.103.50
コンテナに反映
# lxc exec f2 dhclient eth1

シェルスクリプト

引数に指定したコンテナのipアドレスを取得(CIDR表記)

#!/bin/bash
container=$1
echo $container
lxc exec $container -- ip a | awk '$1=="inet"{print $2}' | grep -v 127.0.0.1

全コンテナ名を取得

lxc list | awk 'NR>3{print $2}' | grep -v '^$'

全コンテナを削除

lxc delete `lxc list | awk 'NR>3{print $2}' | grep -v '^$'` --force

ブリッジに鍵登録

cat ~/.ssh/id_rsa.pub | xargs -i% lxc exec container -- bash -c 'echo % >> /root/.ssh/authorized_keys'

外部からlxdホストマシンを中継してコンテナに接続

ssh -t [lxd_host] ssh root@[container_ip]

公式のほかで参考にしたサイト様たち

gihyo.jp

gihyo.jp

www.waguri-soft.com

qiita.com

qiita.com

qiita.com

qiita.com