2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

自宅サーバー構築譚:LXD

Last updated at Posted at 2023-04-16

能書き

自宅サーバー構築譚:基本構想に基づく自宅サーバー構築、Ubuntu22.04LTSインストールその2の続きです。

少々考えている事がありまして、このタイミングでコンテナを構築します。それもLXDとDockerを両方という贅沢仕様。意味が無い!と周囲に一蹴されたのですが、私なりに必然性を持った計画なのです。

ただ、Dockerとの同時インストールはLXDの公式も否定的であるので、もしかすると試行錯誤の末に諦めるかも知れません。

なお「LXD」の正しい読み方は「レクスディー」のようです。

目標

  • LXDでシステムコンテナを起動
  • コンテナのネットワークをブリッジ接続して、外部からアクセス
  • ネットワークのIPアドレスは固定

参考文献

スナップショット

後述の通り、LXDはsnapというパッケージ管理システムでインストールされています。これは関連するディレクトリが普通とは別になっているので、それを理解する必要があります。

参考文献:snapパッケージの関連ディレクトリ - 第714回 Firefoxを含むsnapパッケージとの付き合い方 - gihyo.jp

スナップショットを撮ります。

sudo zfs snapshot tank/ROOT/ubuntu@$(date +%Y%m%d_%H%M%S)_before_LXD
sudo zfs snapshot tank/ROOT/ubuntu/snap@$(date +%Y%m%d_%H%M%S)_before_LXD
sudo zfs snapshot tank/ROOT/ubuntu/var/snap@$(date +%Y%m%d_%H%M%S)_before_LXD
sudo zfs snapshot tank/ROOT/ubuntu/var/lib/snapd@$(date +%Y%m%d_%H%M%S)_before_LXD

ロールバックする場合の注意

ここまでロールバックする事などまず無いと思いますが。もしもロールバックする場合、4つのスナップショットの他に、ZFSストレージプールを破棄する必要があります。そして少々面倒臭い手順が必要です。

まず全コンテナを停止して削除します。

lxc list -c n -f csv | xargs -rt lxc stop
lxc list -c n -f csv | xargs -rt lxc delete

ZFSストレージプールを削除します。
後述しますが、ZFSストレージプール名としてデフォルト値を選んだ場合(紛らわしいですがこの場合はdefaultという名前になります)次のコマンドを実行します。

sudo zpool destroy default

そしてZFSスナップショットまでロールバックします。

zfs list -t snapshot -o name -H | grep before_LXD | xargs -rtL 1 sudo zfs rollback

ここまでやってからマシン再起動で、ロールバックを反映します。

sudo reboot

インストール

毎度おなじみのapt update

sudo apt update

Ubuntuには最初からsnapdがインストールされている、との事…だったんですが、Ubuntuサーバーにはインストールされていないようです。そこでまずはsnapdのインストールから。
インストール済ならばこの手順は不要です。

sudo apt install -y snapd

これでsnapコマンドを使えます。

snap --version

LXDについて。

snap info lxd

現在のLTS版は5.0です。これをインストールします。

sudo snap install lxd --channel=5.0/stable

インストールを確認。

lxd --version

初期化

コンテナ構築前にlxdの初期化が必要です。対話式の設定は色々と解説記事もあるようですので、ここでは非対話式で設定してみます。

ほぼ全てデフォルトですが、3箇所だけ。

  • ネットワークブリッジのIPv4アドレスは固定で192.168.0.1/24とします。
  • IPv6はnoneにしました。一般論ですが、トラブルの元になる場合が散見されるので。きちんと理解していれば良いんですが、私はまだIPv6を理解していないのです。
  • イメージの自動更新はしません。安定稼働していたサーバがある日突然停止した、という事故が怖いので。

参考文献:LXDを初期化するには - LXDを使い始めるには

lxd init --preseed <<___
config:
  images.auto_update_interval: "0"
networks:
- config:
    ipv4.address: 192.168.0.1/24
    ipv4.nat: "true"
    ipv6.address: none
  description: ""
  name: lxdbr0
  type: ""
  project: default
storage_pools:
- config:
    size: 30GiB
  description: ""
  name: default
  driver: zfs
profiles:
- config: {}
  description: ""
  devices:
    eth0:
      name: eth0
      network: lxdbr0
      type: nic
    root:
      path: /
      pool: default
      type: disk
  name: default
projects: []
cluster: null
___

コンテナ構築

利用可能なイメージを探す

利用可能なイメージを探します。今回はUbuntuの最新版である22.04通称jammyにします。

参考文献:利用可能なイメージをフィルタする - 利用可能なイメージを一覧表示する - イメージを管理するには

lxc image list images: ubuntu jammy architecture=x86_64 type=container

出力例。

$ lxc image list images: ubuntu jammy architecture=x86_64 type=container
To start your first container, try: lxc launch ubuntu:22.04
Or for a virtual machine: lxc launch ubuntu:22.04 --vm

+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+
|            ALIAS            | FINGERPRINT  | PUBLIC |             DESCRIPTION             | ARCHITECTURE |   TYPE    |   SIZE   |          UPLOAD DATE          |
+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+
| ubuntu/jammy (7 more)       | 633d8a9878c2 | yes    | Ubuntu jammy amd64 (20230415_07:42) | x86_64       | CONTAINER | 116.44MB | Apr 15, 2023 at 12:00am (UTC) |
+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+
| ubuntu/jammy/cloud (3 more) | 6c1ee3154ef0 | yes    | Ubuntu jammy amd64 (20230415_07:43) | x86_64       | CONTAINER | 133.32MB | Apr 15, 2023 at 12:00am (UTC) |
+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+

因みに、jammyではなくて22.04と指定しても同じ結果になりました。

$ lxc image list images: ubuntu 22.04 architecture=x86_64 type=container
+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+
|            ALIAS            | FINGERPRINT  | PUBLIC |             DESCRIPTION             | ARCHITECTURE |   TYPE    |   SIZE   |          UPLOAD DATE          |
+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+
| ubuntu/jammy (7 more)       | 633d8a9878c2 | yes    | Ubuntu jammy amd64 (20230415_07:42) | x86_64       | CONTAINER | 116.44MB | Apr 15, 2023 at 12:00am (UTC) |
+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+
| ubuntu/jammy/cloud (3 more) | 6c1ee3154ef0 | yes    | Ubuntu jammy amd64 (20230415_07:43) | x86_64       | CONTAINER | 133.32MB | Apr 15, 2023 at 12:00am (UTC) |
+-----------------------------+--------------+--------+-------------------------------------+--------------+-----------+----------+-------------------------------+

コンテナ作成

コンテナを作成します。IPv4アドレスを固定で192.168.0.2にします。

参考文献:インスタンスを作成するには

lxc init images:ubuntu/22.04 container-name --device eth0,ipv4.address=192.168.0.2

コンテナを作成しましたが停止状態です。

$ lxc list
+----------------+---------+------+------+-----------+-----------+
|      NAME      |  STATE  | IPV4 | IPV6 |   TYPE    | SNAPSHOTS |
+----------------+---------+------+------+-----------+-----------+
| container-name | STOPPED |      |      | CONTAINER | 0         |
+----------------+---------+------+------+-----------+-----------+

開始コマンドは下記です。

lxc start container-name

確認はlistコマンドで。

$ lxc list
+----------------+---------+--------------------+------+-----------+-----------+
|      NAME      |  STATE  |        IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+----------------+---------+--------------------+------+-----------+-----------+
| container-name | RUNNING | 192.168.0.2 (eth0) |      | CONTAINER | 0         |
+----------------+---------+--------------------+------+-----------+-----------+

listコマンドのオプションも色々あります。lxc list --helpで調べてみて下さい。
例えばコンテナ名とIPv4アドレスを取得してCSVで出力する場合は下記になります。

$ lxc list -c n4 -f csv
container-name,192.168.0.2 (eth0)

また、initstartを同時に実行するのがlaunchです。

$ lxc launch images:ubuntu/jammy container-name2 --device eth0,ipv4.address=192.168.0.3
Creating container-name2
Starting container-name2
$ lxc list
+-----------------+---------+--------------------+------+-----------+-----------+
|      NAME       |  STATE  |        IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+-----------------+---------+--------------------+------+-----------+-----------+
| container-name  | RUNNING | 192.168.0.2 (eth0) |      | CONTAINER | 0         |
+-----------------+---------+--------------------+------+-----------+-----------+
| container-name2 | RUNNING | 192.168.0.3 (eth0) |      | CONTAINER | 0         |
+-----------------+---------+--------------------+------+-----------+-----------+

コンテナの停止はstopです。

$ lxc stop container-name container-name2
$ lxc list
+-----------------+---------+------+------+-----------+-----------+
|      NAME       |  STATE  | IPV4 | IPV6 |   TYPE    | SNAPSHOTS |
+-----------------+---------+------+------+-----------+-----------+
| container-name  | STOPPED |      |      | CONTAINER | 0         |
+-----------------+---------+------+------+-----------+-----------+
| container-name2 | STOPPED |      |      | CONTAINER | 0         |
+-----------------+---------+------+------+-----------+-----------+

コンテナの削除はdeleteです。

$ lxc delete container-name2
$ lxc list
+----------------+---------+------+------+-----------+-----------+
|      NAME      |  STATE  | IPV4 | IPV6 |   TYPE    | SNAPSHOTS |
+----------------+---------+------+------+-----------+-----------+
| container-name | STOPPED |      |      | CONTAINER | 0         |
+----------------+---------+------+------+-----------+-----------+

なお稼働状態だと削除できません。

$ lxc start container-name
$ lxc list
+----------------+---------+--------------------+------+-----------+-----------+
|      NAME      |  STATE  |        IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+----------------+---------+--------------------+------+-----------+-----------+
| container-name | RUNNING | 192.168.0.2 (eth0) |      | CONTAINER | 0         |
+----------------+---------+--------------------+------+-----------+-----------+
$ lxc delete container-name
Error: The instance is currently running, stop it first or pass --force

コンテナ内ファイルへのアクセス

ファイルのpushとpull

参考文献:インスタンス内のファイルにアクセスするには

テストに使用するファイルを用意します。中身は何でもいいのですが。

cat <<___ >/tmp/twinkle.txt
Twinkle, twindle, little star,
How I wonder what you are!
___

コンテナの中へ送付します。後述しますが、Ubuntuのコンテナにはデフォルトの一般ユーザーとしてubuntuが用意されていましたので、そのホームディレクトリに置いてみます。

lxc file push /tmp/twinkle.txt container-name/home/ubuntu/littlestar.txt

今度はコンテナ内から取得。

lxc file pull container-name/home/ubuntu/littlestar.txt /tmp

2つのファイルが一致する事を確認します。

$ diff -s /tmp/twinkle.txt /tmp/littlestar.txt
Files /tmp/twinkle.txt and /tmp/littlestar.txt are identical

因みにファイルパスとしてハイフン-を指定すると、標準入出力になるそうです。
コンテナ内に送付する場合のコマンド例:

lxc file push - container-name/home/ubuntu/up.txt <<___
Up above the world so high,
Like a diamond in the sky.
___

コンテナから取得する場合の実行結果例:

$ lxc file pull container-name/home/ubuntu/up.txt -
Up above the world so high,
Like a diamond in the sky.

直接編集

コンテナ内のファイルを直接編集する事も可能です。エディタはデフォルトでnanoのようです。私にとって使い慣れたviを指定する場合は、環境変数EDITORで指定します。

EDITOR=vi lxc file edit container-name/home/ubuntu/littlestar.txt

削除

コンテナ内のファイルを直接削除する事も可能です。

lxc file delete container-name/home/ubuntu/up.txt

コンテナ内でコマンド実行

コマンドの実行

execサブコマンドを指定します。オプションを指定する場合は--で区切ります。

参考文献:インスタンス内でコマンドを実行するには

例えば:

lxc exec container-name -- ls -l /home/ubuntu

Ubuntuコンテナでは最初からubuntuユーザーが用意されていました。そう言ったコンテナ内ユーザーとしてコンテナに入る為には下記コマンドを実行します。

lxc exec container-name -- su --login ubuntu

ところで、このubuntuユーザのパスワードはubuntuという記事を見かけましたが、実際に入力するとどうも違うようです。

$ passwd
Changing password for ubuntu.
Current password:
passwd: Authentication token manipulation error
passwd: password unchanged
exit

仕方が無いので、rootでubuntuユーザのパスワードを設定しておきましょう。

lxc exec container-name passwd ubuntu <<___
ubuntu
ubuntu
___

コンソールに接続

コンソールに接続してみます。

参考文献:コンソールにアクセスするには

lxc console container-name

これでコンソールに接続します。わかりにくいですが、ログインの要求が始まっています。

$ lxc console container-name
To detach from the console, press: <ctrl>+a q
ubuntu
Password:
Welcome to Ubuntu 22.04.2 LTS (GNU/Linux 5.15.0-69-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

 * Introducing Expanded Security Maintenance for Applications.
   Receive updates to over 25,000 software packages with your
   Ubuntu Pro subscription. Free for personal use.

     https://ubuntu.com/pro

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

ubuntu@container-name:~$ exit
logout

Ubuntu 22.04.2 LTS container-name console

container-name login:

このコンソールから抜けるには Ctrl-a の後に q を入力します。

ネットワーク

コンテナ内から外部へ

デフォルトで、コンテナ内から外部へアクセスできます。名前解決も出来ています。

lxc exec container-name -- ping -c2 example.com

実行結果。

$ lxc exec container-name -- ping -c2 example.com
PING example.com (93.184.216.34) 56(84) bytes of data.
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=52 time=119 ms
64 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=52 time=119 ms

--- example.com ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 118.755/118.767/118.779/0.012 ms

外部からコンテナ内へ

まずは動作確認に備えて、openssh-serverをインストールしておきます。

lxc exec container-name -- apt install -y openssh-server

外部からコンテナ内へのアクセスについては、ポートフォワーディングを設定するのが最も理解し易いようです。
ただ、参考文献に載っていた方法は、少々癖があってわかりにくい。

参考文献:ネットワークフォワードを設定するには

まず「ネットワークフォワード」と呼ばれる構造を作成します。

  • lxdbr0は最初の初期化時に作られたネットワークの名前
  • 172.16.1.3はホストのIPアドレス(0.0.0.0では上手くいかないようです)
lxc network forward create lxdbr0 172.16.1.3

それから、この「ネットワークフォワード」に、ポートの割り当てを追加します。

  • 192.168.0.2はコンテナのIPアドレス(上述の通り、コンテナ作成時に指定したIPv4アドレス)
lxc network forward port add lxdbr0 172.16.1.3 tcp 10022 192.168.0.2 22

これで外部からコンテナへ接続が可能になります。

ssh -p 10022 ubuntu@172.16.1.3

少し異なる設定方法として、下記のコマンドを実行すると、一発で設定できる模様。

参考文献:外部からコンテナへの通信について - LXDにおけるネットワーク通信について - LXDを使用して瞬時にサーバを量産する(Ubuntu18.04)

lxc config device add container-name sshForward proxy listen=tcp:172.16.1.3:20022 connect=tcp:192.168.0.2:22 bind=host

接続確認。

ssh -p 20022 ubuntu@172.16.1.3

仕舞い

一通り設定できた所で、例によって/etcをコミットします。

sudo svn st /etc

今回の実行結果。

$ sudo svn st /etc
M       /etc/cups/subscriptions.conf
M       /etc/cups/subscriptions.conf.O
M       /etc/passwd
M       /etc/shadow
?       /etc/systemd/system/multi-user.target.wants/snap-core20-1852.mount
?       /etc/systemd/system/multi-user.target.wants/snap-lxd-24322.mount
?       /etc/systemd/system/multi-user.target.wants/snap-snapd-18596.mount
?       /etc/systemd/system/multi-user.target.wants/snap.lxd.activate.service
?       /etc/systemd/system/snap-core20-1852.mount
?       /etc/systemd/system/snap-lxd-24322.mount
?       /etc/systemd/system/snap-snapd-18596.mount
?       /etc/systemd/system/snap.lxd.activate.service
?       /etc/systemd/system/snap.lxd.daemon.service
?       /etc/systemd/system/snap.lxd.daemon.unix.socket
?       /etc/systemd/system/snap.lxd.user-daemon.service
?       /etc/systemd/system/snap.lxd.user-daemon.unix.socket
?       /etc/systemd/system/snapd.mounts.target.wants
?       /etc/systemd/system/sockets.target.wants/snap.lxd.daemon.unix.socket
?       /etc/systemd/system/sockets.target.wants/snap.lxd.user-daemon.unix.socket
?       /etc/udev/rules.d/70-snap.snapd.rules
M       /etc/zfs/zfs-list.cache/tank
M       /etc/zfs/zpool.cache
sudo svn st /etc | grep "^?" | cut -b9- | xargs -I{} sudo find {} -type f -or -type d -or -type l | xargs -t sudo svn add
sudo svn ci /etc -m"LXD setting"

残りの操作としてcloud-initを使いたいとかありますが、それはまた後日にします。
それを除けば、これでLXDを一通り操作できました。やったね:thumbsup_tone1:

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?