Ubuntu 22.04LTSでLXCコンテナを使う
KVM で仮想サーバ を作成して個人でも業務でも便利に運用しています。 一方、Raspberry Pi ではCPUやメモリが潤沢ではないため KVM でサーバを実用的に運用することはできません。 システムコンテナとして LXC を試したところ、Raspberry Piでも楽に実用できると思われるので自分の備忘録として解説を書きました (2022-11-30)。
Raspberry Pi 4Bと10インチのLCDディズプレイモジュールを工具箱に詰め込んで、All in One PC にしてみました。 USBで接続した 500GB の SSD に 64bit の Ubunttu 22.04LTSをインストールして、Linuxコンテナ (LXC) を使ってみます。 Snap も必要となる LXD は使用しません。 私は LXC を直接使う方がシンプルに使えると思っています。
コンピュータシステムのライフサイクル全体では、システムの設計、開発、運用、修正、バージョンアップ、故障時の対応、機器の更新などに対応する必要があります。
システムによるサービスを停止することなくスムーズに進めるためには、システムが1台のサーバで構成されていたとしても、本番機、予備機、検証機、開発機と多くのサーバを準備する必要があります。 物理的なコンピュータの台数を増やすと設置場所、電力、費用、保守の負荷など多くの問題が発生します。 システムの仮想化技術を利用することで、物理的なコンピュータの台数にあまり制限されることなく、必要な数のサーバを準備することができるようになります。
Linux コンテナ(LXC) は、コンテナ仮想化技術の一種で、アプリケーションコンテナと呼ばれる Docker (www.docker.com/) や Snap (snapcraft.io/about) と同様に Linuxカーネルより上の階層を仮想化する技術です。 Docker と Snap がアプリケーションレベルで隔離する方法であるのに対して、LXC はホストOSのカーネルを使用するものの、Linuxディストリビューションのレベルで仮想化する方法です。
下の図のゲストOSも、ホストから見ると単なる普通のプロセスの一つですが、ゲスト側から見ると、ホスト側のプロセスや別のゲストOSのプロセスはカーネルの持つ名前空間という仕組みで見えません。ファイルシステムもホスト側のファイルシステムの一部を使用しますが、ゲスト側からは自分の管理する範囲しか見ることができなくなっています。 ホストシステムと同じく、システムコール呼び出しやファイル操作にオーバーヘッドがなく、ハードウェアのエミュレーションの必要がないため、Qemu-KVMを使った仮想マシンに比べて高速に動作します。
一方で、サーバ仮想化技術の Qemu-KVM (www.linux-kvm.org/page/Main_Page) は、CPU自身が持つ仮想化機能を使ってハードウェア側で効率的に、仮想的なハードウェアをエミュレーションする技術です。 サーバ仮想化では、ゲスト側では OS を含むソフトウェアからはハードウェア(実際はエミュレーションしたもの)だけが見えるため、Windows や Linux といった異なるOSでも1つのハードウェア上に併存させることが可能です。
サーバ仮想化技術を使った Qemu-KVM は2007年、コンテナ仮想化技術の LXC、Docker、Snap は 2014年に現れ、すでに十分な実績があります。
システムの仮想化技術としては、サーバ仮想化が最も自由度があり、ホストOSやゲストOS間の独立性が高いことがメリットです。 一方、CPUやメモリ、ストレージといったホストマシンの持つリソースの配分を注意深く設計する必要があり、起動や停止、バックアップなどでKVM は運用の負荷が高くなりがち です。 Raspberry Pi では、CPUコアの数やメモリの搭載量が多くないため、事前にリソースを配分する必要のないコンテナ技術が向いています。
Raspberry Pi 4BにUbuntu 22.04LTSをインストール
SDカードを使わずに、USBに接続した 500GB の SSD に直接書き込みます。
Raspberry Pi Imager のインストール
Raspberry Pi の公式サイト から[Raspberry Pi Imager|https://www.raspberrypi.com/software/]] をダウンロードします。 今回のバージョンは imager_1.7.3.exe でした。
64ビット版のUbuntu Desktop 22.04.1 LTS の書き込み
インストールするイメージは Ubuntu Desktop 22.04.1 LTS とします。 イメージファイルは ubuntu-22.04.1-preinstalled-desktop-arm64+raspi.img.xz (2.047GB) です。
Ubuntu の場合は「Other ...」を選びます。
Ubuntu を選択します。
今回は 64ビット版のデスクトップとしました。
書き込み先のデバイスを選択します。
USB接続した 500GB の SSD を選択します。
書き込みボタンを押します。
書き込み先のデバイスのデータはすべて消去されます。
書き込みは終了です。 SDカードではないのにSDカード用のメッセージが表示されますね。
Ubuntu 22.04 LTS の起動
Raspberry Pi にSSDを接続 (SDカードは挿入しません) して、電源を入れます。最初に起動するまでには、しばらく時間がかかります。
このマシンはサーバとして運用する予定ですが、サーバ環境はLXCを使ったシステムコンテナ内に隔離する予定なので、あえてデスクトップ版をインストールしました。
ディスプレイを表示している時は13ワット程度の消費電力ですが、ディスプレイの電源を切れば 7ワット弱です。
ディスクの使用状況を確認します。
jun@Rpi4B:~$ df
Filesystem 1K-blocks Used Available Use% Mounted on
tmpfs 387984 3796 384188 1% /run
/dev/sda2 480346264 6125036 454604280 2% /
tmpfs 1939920 0 1939920 0% /dev/shm
tmpfs 5120 8 5112 1% /run/lock
/dev/sda1 258095 145311 112785 57% /boot/firmware
tmpfs 387984 2472 385512 1% /run/user/1000
IPアドレスを確認。 DHCPで与えられたIPアドレスになっています。
jun@Rpi4B:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000 link/ether aa:bb:cc:dd:ee:6b brd ff:ff:ff:ff:ff:ff 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether aa:bb:cc:dd:ee:6c brd ff:ff:ff:ff:ff:ff inet 172.18.21.20/24 brd 172.18.21.255 scope global dynamic noprefixroute wlan0 valid_lft 172299sec preferred_lft 172299sec inet6 fe80::c41b:764e:3e7f:f113/64 scope link noprefixroute valid_lft forever preferred_lft forever
CPU温度、電圧、クロックを確認
jun@Rpi4B:~$ sudo vcgencmd measure_temp temp=57.4'C jun@Rpi4B:~$ sudo vcgencmd measure_voltsolt=0.8563V volt=0.8563V jun@Rpi4B:~$ sudo vcgencmd measure_clock armrequency(48)=1500345728 frequency(48)=1500345728
パッケージの更新
色々インストールする前にインストール済みのパッケージを更新しておきます。
$ sudo apt update $ sudo apt upgrade
OpenSSH server のインストール
jun@Rpi4B:~$ sudo apt install openssh-server [sudo] password for jun: パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています... 完了 状態情報を読み取っています... 完了 以下の追加パッケージがインストールされます: ncurses-term openssh-sftp-server ssh-import-id 提案パッケージ: molly-guard monkeysphere ssh-askpass 以下のパッケージが新たにインストールされます: ncurses-term openssh-server openssh-sftp-server ssh-import-id アップグレード: 0 個、新規インストール: 4 個、削除: 0 個、保留: 0 個。 728 kB のアーカイブを取得する必要があります。 この操作後に追加で 5,976 kB のディスク容量が消費されます。 続行しますか? [Y/n] y : 略 :
Raspberry Pi 4B で LXC を使う
LXC のインストール
まず、lxc パッケージをインストールします。
jun@Rpi4B:~$ sudo apt install lxc
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
bridge-utils libfuse2 liblxc-common liblxc1 libpam-cgfs lxc-utils lxcfs
uidmap
提案パッケージ:
ifupdown btrfs-tools lvm2 lxc-templates lxctl
以下のパッケージが新たにインストールされます:
bridge-utils libfuse2 liblxc-common liblxc1 libpam-cgfs lxc lxc-utils lxcfs
uidmap
アップグレード: 0 個、新規インストール: 9 個、削除: 0 個、保留: 5 個。
1,375 kB のアーカイブを取得する必要があります。
この操作後に追加で 5,022 kB のディスク容量が消費されます。
続行しますか? [Y/n]
:
略
:
lxc のコマンドの種類
インストールされるコマンドには、起動、停止、作成、削除、コピー、リストなど、使う可能性が高いコマンドとして以下のものがあります。 コマンド名から機能が予想できます。 基本的に 「-n コンテナ名」とコンテナを指定する使い方になります。他のオプションの詳細は 「man コマンド名」で確認できます。
LXC はシステムコンテナなので、コンテナ=仮想マシン(VM)という理解で大丈夫です。
コマンド | 機能 |
---|---|
lxc-create | コンテナの作成 |
lxc-destroy | コンテナの削除 |
lxc-ls | コンテナのリスト |
lxc-info | コンテナの情報表示 |
lxc-start | コンテナの起動 |
lxc-stop | コンテナの停止 |
lxc-console | コンソールをコンテナに接続 |
lxc-execute | コンテナ内でコマンドを実行 |
lxc-copy | コンテナをコピー |
lxc-snapshot | コンテナのスナップショットを作成 |
他にも以下のようなコマンドがインストールされます。 lxc-attach、lxc-autostart、lxc-cgroup、lxc-checkconfig、lxc-checkpoint、lxc-config、lxc-device、lxc-freeze、lxc-monitor、lxc-top、lxc-unfreeze、lxc-unshare、lxc-update-config、lxc-usernsexec、lxc-wait です。
ホストのカーネルの機能の確認
Linux カーネルが必要な機能を持っているかどうかをチェックする「lxc-checkconfig」コマンドを実行してみます。
jun@Rpi4B:~$ lxc-checkconfig
LXC version 5.0.0~git2209-g5a7b9ce67
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-5.15.0-1018-raspi
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
--- Control groups ---
Cgroups: enabled
Cgroup namespace: enabled
Cgroup v1 mount points:
Cgroup v2 mount points:
/sys/fs/cgroup
Cgroup v1 systemd controller: missing
Cgroup v1 freezer controller: missing
Cgroup ns_cgroup: required
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled, not loaded
Macvlan: enabled, not loaded
Vlan: enabled, not loaded
Bridges: enabled, loaded
Advanced netfilter: enabled, loaded
CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, not loaded
CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded
FUSE (for use with lxcfs): enabled, not loaded
--- Checkpoint/Restore ---
checkpoint restore: enabled
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: enabled
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: enabled
CONFIG_NETLINK_DIAG: enabled
File capabilities:
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
ホストのネットワークの確認
lxc をインストールすると、lxc用の内部ブリッジとしてクラスAのプライベートアドレスを使うlxcbr0 が追加されます。
jun@Rpi4B:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000 link/ether aa:bb:cc:dd:ee:6b brd ff:ff:ff:ff:ff:ff 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether aa:bb:cc:dd:ee:6c brd ff:ff:ff:ff:ff:ff inet 172.18.21.20/24 brd 172.18.21.255 scope global dynamic noprefixroute wlan0 valid_lft 172317sec preferred_lft 172317sec inet6 fe80::c41b:764e:3e7f:f113/64 scope link noprefixroute valid_lft forever preferred_lft forever 4: lxcbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 00:16:3e:00:00:00 brd ff:ff:ff:ff:ff:ff inet 10.0.3.1/24 brd 10.0.3.255 scope global lxcbr0 valid_lft forever preferred_lft forever
ubuntu コンテナの作成(ダウンロード)
主要ディストリビューションの初期コンテナイメージは公開されていて、リストから選択してダウンロードできます。 その後、必要なパッケージをインストールして、カスタマイズして使うことになります。
ここではコンテナの初期イメージも Ubuntu 22.04LTS である「ubuntu jammy arm64」を選択します。
リストから選択
リストから選択して初期コンテナイメージをダウンロードしている。
jun@Rpi4B:~$ sudo lxc-create -t download -n u01 [sudo] password for jun: Downloading the image index --- DIST RELEASE ARCH VARIANT BUILD --- almalinux 8 amd64 default 20221121_05:29 almalinux 8 arm64 default 20221118_23:08 almalinux 8 ppc64el default 20221121_06:11 almalinux 9 amd64 default 20221121_05:10 almalinux 9 arm64 default 20221118_23:08 almalinux 9 ppc64el default 20221121_05:15 alpine 3.13 amd64 default 20221116_15:40 alpine 3.13 arm64 default 20221116_16:09 alpine 3.13 armhf default 20221115_13:01 alpine 3.13 i386 default 20221116_15:25 alpine 3.13 ppc64el default 20221116_18:29 alpine 3.13 s390x default 20221116_15:49 alpine 3.14 amd64 default 20221121_06:01 alpine 3.14 arm64 default 20221119_13:32 alpine 3.14 armhf default 20221121_19:02 alpine 3.14 i386 default 20221121_05:53 alpine 3.14 ppc64el default 20221121_08:03 alpine 3.14 s390x default 20221121_06:06 alpine 3.15 amd64 default 20221121_05:44 alpine 3.15 arm64 default 20221119_13:32 alpine 3.15 armhf default 20221121_18:34 alpine 3.15 i386 default 20221121_05:32 alpine 3.15 ppc64el default 20221121_07:38 alpine 3.15 s390x default 20221121_06:05 alpine 3.16 amd64 default 20221121_06:01 alpine 3.16 arm64 default 20221119_13:32 alpine 3.16 armhf default 20221121_18:52 alpine 3.16 i386 default 20221121_05:48 alpine 3.16 ppc64el default 20221121_08:22 alpine 3.16 s390x default 20221121_05:17 alpine edge amd64 default 20221121_05:47 alpine edge arm64 default 20221121_18:45 alpine edge armhf default 20221118_13:01 alpine edge i386 default 20221121_06:05 alpine edge ppc64el default 20221121_06:40 alpine edge s390x default 20221121_06:37 alt Sisyphus amd64 default 20221121_05:20 alt Sisyphus arm64 default 20221119_01:17 alt Sisyphus armhf default 20221121_18:10 alt Sisyphus ppc64el default 20221121_05:12 alt p10 amd64 default 20221121_05:51 alt p10 arm64 default 20221119_01:17 alt p10 armhf default 20221119_01:18 alt p10 ppc64el default 20221121_07:25 alt p9 amd64 default 20221121_05:46 alt p9 arm64 default 20221121_18:18 alt p9 armhf default 20221119_01:56 alt p9 ppc64el default 20221121_07:39 amazonlinux current amd64 default 20221121_05:10 amazonlinux current arm64 default 20221119_05:09 apertis v2020 amd64 default 20221121_05:11 apertis v2020 arm64 default 20221121_18:11 apertis v2020 armhf default 20221121_18:13 apertis v2021 amd64 default 20221121_05:13 apertis v2021 arm64 default 20221119_10:53 apertis v2021 armhf default 20221119_10:53 archlinux current amd64 default 20221121_05:10 archlinux current arm64 default 20221119_04:18 archlinux current armhf default 20221119_04:18 busybox 1.34.1 amd64 default 20221121_05:10 busybox 1.34.1 arm64 default 20221119_06:00 centos 7 amd64 default 20221121_05:33 centos 7 arm64 default 20221119_07:08 centos 7 armhf default 20221119_09:00 centos 7 i386 default 20221121_05:26 centos 7 ppc64el default 20221121_06:01 centos 8-Stream amd64 default 20221121_05:46 centos 8-Stream arm64 default 20221119_09:40 centos 8-Stream ppc64el default 20221121_05:27 centos 9-Stream amd64 default 20221121_05:48 centos 9-Stream arm64 default 20221121_18:22 centos 9-Stream ppc64el default 20221121_06:58 debian bookworm amd64 default 20221121_06:08 debian bookworm arm64 default 20221119_05:59 debian bookworm armel default 20221119_06:51 debian bookworm armhf default 20221119_05:24 debian bookworm i386 default 20221121_06:04 debian bookworm ppc64el default 20221121_08:14 debian bookworm s390x default 20221121_06:37 debian bullseye amd64 default 20221121_05:13 debian bullseye arm64 default 20221119_05:24 debian bullseye armel default 20221119_05:24 debian bullseye armhf default 20221119_05:25 debian bullseye i386 default 20221121_05:29 debian bullseye ppc64el default 20221121_08:23 debian bullseye s390x default 20221121_06:45 debian buster amd64 default 20221121_05:50 debian buster arm64 default 20221119_05:24 debian buster armel default 20221119_05:24 debian buster armhf default 20221119_05:25 debian buster i386 default 20221121_05:53 debian buster ppc64el default 20221121_06:31 debian buster s390x default 20221121_06:31 debian sid amd64 default 20221121_06:05 debian sid arm64 default 20221119_05:59 debian sid armel default 20221119_05:25 debian sid armhf default 20221121_18:14 debian sid i386 default 20221121_05:48 debian sid ppc64el default 20221121_08:25 debian sid s390x default 20221121_06:19 devuan ascii amd64 default 20221121_05:52 devuan ascii arm64 default 20221119_11:51 devuan ascii armel default 20221119_12:23 devuan ascii armhf default 20221121_18:31 devuan ascii i386 default 20221121_05:34 devuan beowulf amd64 default 20221121_05:55 devuan beowulf arm64 default 20221119_11:50 devuan beowulf armel default 20221121_18:23 devuan beowulf armhf default 20221118_11:51 devuan beowulf i386 default 20221121_05:45 devuan beowulf ppc64el default 20221121_06:41 devuan chimaera amd64 default 20221121_05:19 devuan chimaera arm64 default 20221118_11:51 devuan chimaera armel default 20221121_18:13 devuan chimaera armhf default 20221118_11:51 devuan chimaera i386 default 20221121_05:53 devuan chimaera ppc64el default 20221121_08:09 fedora 35 amd64 default 20221121_05:43 fedora 35 arm64 default 20221118_21:34 fedora 35 ppc64el default 20221121_06:06 fedora 35 s390x default 20221121_06:20 fedora 36 amd64 default 20221121_05:48 fedora 36 arm64 default 20221121_18:08 fedora 36 armhf default 20221118_21:34 fedora 36 ppc64el default 20221121_08:07 fedora 36 s390x default 20221121_06:05 fedora 37 amd64 default 20221121_05:51 fedora 37 arm64 default 20221121_18:09 fedora 37 ppc64el default 20221121_05:49 fedora 37 s390x default 20221121_06:07 funtoo 1.4 amd64 default 20221119_16:46 funtoo 1.4 armhf default 20221118_17:05 kali current amd64 default 20221121_05:13 kali current arm64 default 20221121_18:13 kali current armel default 20221118_17:15 kali current armhf default 20221118_17:15 mint tara amd64 default 20221121_08:51 mint tessa amd64 default 20221121_08:51 mint tina amd64 default 20221121_08:51 mint tricia amd64 default 20221121_08:51 mint ulyana amd64 default 20221121_08:51 mint ulyssa amd64 default 20221121_08:51 mint uma amd64 default 20221121_08:51 mint una amd64 default 20221121_08:53 mint vanessa amd64 default 20221121_08:51 opensuse 15.3 amd64 default 20221121_05:36 opensuse 15.3 arm64 default 20221119_04:21 opensuse 15.3 ppc64el default 20221121_06:14 opensuse 15.3 s390x default 20221121_05:27 opensuse 15.4 amd64 default 20221121_05:35 opensuse 15.4 arm64 default 20221119_04:21 opensuse 15.4 ppc64el default 20221121_06:22 opensuse 15.4 s390x default 20221121_05:23 opensuse tumbleweed amd64 default 20221121_05:35 opensuse tumbleweed arm64 default 20221119_04:21 opensuse tumbleweed ppc64el default 20221121_06:18 opensuse tumbleweed s390x default 20221121_05:18 openwrt 21.02 amd64 default 20221121_05:30 openwrt 21.02 arm64 default 20221119_11:58 openwrt 21.02 armhf default 20221121_18:13 openwrt 22.03 amd64 default 20221121_05:10 openwrt 22.03 arm64 default 20221119_12:02 openwrt 22.03 armhf default 20221118_12:00 openwrt snapshot amd64 default 20221121_05:33 openwrt snapshot arm64 default 20221121_18:16 openwrt snapshot armhf default 20221119_12:25 oracle 7 amd64 default 20221121_05:26 oracle 7 arm64 default 20221119_08:39 oracle 8 amd64 default 20221121_05:29 oracle 8 arm64 default 20221119_08:24 oracle 9 amd64 default 20221121_05:43 oracle 9 arm64 default 20221121_18:19 plamo 6.x amd64 default 20221121_05:11 plamo 7.x amd64 default 20221121_05:10 pld current amd64 default 20221121_05:10 rockylinux 8 amd64 default 20221121_05:21 rockylinux 8 arm64 default 20221119_02:06 rockylinux 9 amd64 default 20221121_05:34 rockylinux 9 arm64 default 20221119_02:06 rockylinux 9 ppc64el default 20221121_06:31 springdalelinux 7 amd64 default 20221121_06:39 springdalelinux 7 i386 default 20221121_06:38 springdalelinux 8 amd64 default 20221121_06:38 springdalelinux 9 amd64 default 20221121_07:19 ubuntu bionic amd64 default 20221121_05:30 ubuntu bionic arm64 default 20221119_09:12 ubuntu bionic armhf default 20221119_07:43 ubuntu bionic i386 default 20221121_05:58 ubuntu bionic ppc64el default 20221121_06:57 ubuntu bionic s390x default 20221121_06:57 ubuntu focal amd64 default 20221121_06:02 ubuntu focal arm64 default 20221119_07:42 ubuntu focal armhf default 20221119_07:43 ubuntu focal ppc64el default 20221121_08:32 ubuntu focal s390x default 20221121_06:30 ubuntu jammy amd64 default 20221121_05:19 ubuntu jammy arm64 default 20221119_07:42 ubuntu jammy armhf default 20221119_07:43 ubuntu jammy ppc64el default 20221121_07:59 ubuntu jammy s390x default 20221121_06:33 ubuntu kinetic amd64 default 20221121_05:56 ubuntu kinetic arm64 default 20221119_07:43 ubuntu kinetic armhf default 20221119_07:43 ubuntu kinetic ppc64el default 20221121_08:25 ubuntu kinetic s390x default 20221121_06:22 ubuntu xenial amd64 default 20221121_05:43 ubuntu xenial arm64 default 20221119_07:43 ubuntu xenial armhf default 20221119_07:43 ubuntu xenial i386 default 20221121_05:50 ubuntu xenial ppc64el default 20221121_07:13 ubuntu xenial s390x default 20221121_06:05 voidlinux current amd64 default 20221121_05:11 voidlinux current arm64 default 20221118_17:10 voidlinux current armhf default 20221118_17:11 --- Distribution: ubuntu Release: jammy Architecture: arm64 Downloading the image index Downloading the rootfs Downloading the metadata The image cache is now ready Unpacking the rootfs --- You just created an Ubuntu jammy arm64 (20221119_07:42) container. To enable SSH, run: apt install openssh-server No default root or user password are set by LXC.
直接イメージを指定
コンテナ名を「x01」とします。 ディストリビューション名(-d ubuntu)、リリース名(-r jammy)、アーキテクチャ名(-a arm64)を指定します。
$ sudo lxc-create -t download -n x01 -- -d ubuntu -r jammy -a arm64
イメージがローカルにキャッシュされている場合はそれが使われます。
jun@Rpi4B:~$ sudo lxc-create -t download -n x01 -- -d ubuntu -r jammy -a arm64
[sudo] password for jun:
Using image from local cache
Unpacking the rootfs
---
You just created an Ubuntu jammy arm64 (20221119_07:42) container.
To enable SSH, run: apt install openssh-server
No default root or user password are set by LXC.
コンテナのリスト
jun@Rpi4B:~$ sudo lxc-ls u01
コンテナの情報表示
jun@Rpi4B:~$ sudo lxc-info u01 Name: u01 State: STOPPED
コンテナの格納場所とサイズ
コンテナは /var/lib/lxc/u01 に格納されます。ダウンロードされた初期イメージを確認します。
jun@Rpi4B:~$ sudo su root@Rpi4B:/home/jun# cd /var/lib/lxc/u01/rootfs/ root@Rpi4B:/var/lib/lxc/u01/rootfs# du . --max-depth=1 4 ./srv 4 ./proc 4 ./media 20 ./home 2148 ./etc 148820 ./var 4 ./opt 24 ./tmp 12 ./root 4 ./sys 346252 ./usr 8 ./dev 4 ./boot 4 ./mnt 4 ./run 497320 .
コンテナのユーザID確認
コンテナを起動しても、コンテナ内のシステムにログインできなければ利用できません。 コンテナイメージに存在するユーザIDを確認するために、コンテナ内の /etc/passwd ファイルを確認する。 管理者権限でホスト側から /var/lib/lxc/u01/rootfs/etc/passwd にアクセスしてシステムに存在するユーザIDを確認します。
root@Rpi4B:/var/lib/lxc/u01/rootfs# cat etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:102:105::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:103:106:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
syslog:x:104:111::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
ubuntu:x:1000:1000::/home/ubuntu:/bin/bash
ubuntu のコンテナイメージにはユーザとして ubuntu が存在していますが、パスワードは分かりません。 いったんパスワードを無効にしてログインできるようにします。
パスワードの無効化
/var/lib/lxc/u01/rootfs/etc/passwd の ubuntu ユーザのパスワード欄の「x」を削除することでパスワードを無効化できます。
# vi /var/lib/lxc/u01/rootfs/etc/passwd
「ubuntu:」の後ろの「x」を削除します。
ubuntu::1000:1000::/home/ubuntu:/bin/bash
コンテナ内でシェルを実行する
上記の方法はホスト側からコンテナ内のファイル(/etc/passwd)を直接編集していますが、lxc-execute コマンドを使用して起動していないコンテナ内でコマンドを実行することができます。
$ sudo lxc-execute -n u01 bash
コンテナを起動していませんが、コンテナの状態は「RUNNING」になります。
jun@Rpi4B:~$ sudo lxc-ls -f NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED u01 RUNNING 0 - - - false x01 STOPPED 0 - - - false y01 STOPPED 0 - - - false z01 STOPPED 0 - - - false
コンテナ内でプロセスを確認すると、init と bash のみが存在しています。
root@u01:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4608 2648 ? Ss 06:57 0:00 init
root 21 0.0 0.0 4136 3312 pts/0 Ss 06:57 0:00 bash
root 28 0.0 0.0 6408 1588 pts/0 R+ 06:57 0:00 ps aux
ホスト側からプロセスを見ると、コンテナ内で動作する init と bash が確認できます。
jun@Rpi4B:~$ ps aux
略
root 61036 0.5 0.0 4608 2808 pts/1 S+ 15:59 0:00 lxc-execute -n u01 bash
root 61037 0.2 0.0 4608 2648 ? Ss 15:59 0:00 init
root 61072 0.0 0.0 4136 3316 pts/0 Ss+ 15:59 0:00 bash
lxc-execute で bash を指定して実行すると、init を経由して bash がコンテナ内で動作します。 したがって、ログインする必要もなく、コンテナ内のコマンド実行が自由に行えるようになります。 その状態で「passwd」コマンドを実行してパスワードを再設定できます。
jun@Rpi4B:~$ sudo lxc-execute -n u01 bash root@u01:/# passwd ubuntu New password: Retype new password: passwd: password updated successfully
コマンドが終了するとコンテナも終了します。
root@u01:/# exit
exit
jun@Rpi4B:~$
コンテナの状態は「STOPPED」に変わりました。
jun@Rpi4B:~$ sudo lxc-ls -f NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED u01 STOPPED 0 - - - false x01 STOPPED 0 - - - false y01 STOPPED 0 - - - false z01 STOPPED 0 - - - false
コンテナの起動
コンテナは「lxc-start」コマンドにコンテナ名を渡して起動します。 デフォルトではデーモンモードでバックグラウンドで起動するため、まずは「-F」でフォアグラウンドを指定して実行します。 Raspberry Pi 4Bでは 1 - 2秒で起動します。
jun@Rpi4B:~$ sudo lxc-start -F -n u01
[sudo] password for jun:
systemd 249.11-0ubuntu3.6 running in system mode (+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY -P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified)
Detected virtualization lxc.
Detected architecture arm64.
Welcome to Ubuntu 22.04.1 LTS!
Queued start job for default target Graphical Interface.
[ OK ] Created slice Slice /system/container-getty.
[ OK ] Created slice Slice /system/modprobe.
[ OK ] Created slice User and Session Slice.
[ OK ] Started Dispatch Password Requests to Console Directory Watch.
[ OK ] Started Forward Password Requests to Wall Directory Watch.
[ OK ] Reached target Local Encrypted Volumes.
[ OK ] Reached target Path Units.
[ OK ] Reached target Remote File Systems.
[ OK ] Reached target Slice Units.
[ OK ] Reached target Swaps.
[ OK ] Reached target Local Verity Protected Volumes.
[ OK ] Listening on Syslog Socket.
[ OK ] Listening on initctl Compatibility Named Pipe.
[ OK ] Listening on Journal Socket (/dev/log).
[ OK ] Listening on Journal Socket.
[ OK ] Listening on Network Service Netlink Socket.
[ OK ] Reached target Socket Units.
Mounting POSIX Message Queue File System...
Starting Journal Service...
Starting Set the console keyboard layout...
Starting Generate network units from Kernel command line...
Starting Remount Root and Kernel File Systems...
Starting Apply Kernel Variables...
[ OK ] Mounted POSIX Message Queue File System.
[ OK ] Finished Generate network units from Kernel command line.
[ OK ] Reached target Preparation for Network.
[ OK ] Finished Remount Root and Kernel File Systems.
Starting Create System Users...
[ OK ] Finished Apply Kernel Variables.
[ OK ] Started Journal Service.
Starting Flush Journal to Persistent Storage...
[ OK ] Finished Create System Users.
[ OK ] Finished Set the console keyboard layout.
[ OK ] Reached target System Time Set.
Starting Create Static Device Nodes in /dev...
[ OK ] Finished Flush Journal to Persistent Storage.
[ OK ] Finished Create Static Device Nodes in /dev.
[ OK ] Reached target Preparation for Local File Systems.
[ OK ] Reached target Local File Systems.
Starting Set console font and keymap...
Starting Create Volatile Files and Directories...
Starting Network Configuration...
[ OK ] Finished Set console font and keymap.
[ OK ] Finished Create Volatile Files and Directories.
Starting Record System Boot/Shutdown in UTMP...
[ OK ] Finished Record System Boot/Shutdown in UTMP.
[ OK ] Reached target System Initialization.
[ OK ] Started Daily apt download activities.
[ OK ] Started Daily apt upgrade and clean activities.
[ OK ] Started Daily dpkg database backup timer.
[ OK ] Started Periodic ext4 Online Metadata Check for All Filesystems.
[ OK ] Started Daily rotation of log files.
[ OK ] Started Message of the Day.
[ OK ] Started Daily Cleanup of Temporary Directories.
[ OK ] Started Ubuntu Advantage Timer for running repeated jobs.
[ OK ] Reached target Basic System.
[ OK ] Reached target Timer Units.
[ OK ] Listening on D-Bus System Message Bus Socket.
[ OK ] Started Regular background program processing daemon.
[ OK ] Started D-Bus System Message Bus.
[ OK ] Started Save initial kernel messages after boot.
Starting Dispatcher daemon for systemd-networkd...
Starting System Logging Service...
Starting User Login Management...
[ OK ] Started Network Configuration.
Starting Network Name Resolution...
[ OK ] Started System Logging Service.
[ OK ] Started User Login Management.
[ OK ] Started Network Name Resolution.
[ OK ] Reached target Network.
[ OK ] Reached target Host and Network Name Lookups.
Starting Permit User Sessions...
[ OK ] Finished Permit User Sessions.
[ OK ] Started Console Getty.
[ OK ] Started Container Getty on /dev/pts/1.
[ OK ] Started Container Getty on /dev/pts/2.
[ OK ] Started Container Getty on /dev/pts/3.
[ OK ] Started Container Getty on /dev/pts/4.
[ OK ] Created slice Slice /system/getty.
[ OK ] Reached target Login Prompts.
[ OK ] Started Dispatcher daemon for systemd-networkd.
[ OK ] Reached target Multi-User System.
[ OK ] Reached target Graphical Interface.
Starting Record Runlevel Change in UTMP...
[ OK ] Finished Record Runlevel Change in UTMP.
Ubuntu 22.04.1 LTS u01 console
u01 login:
普通の Linux と同じように起動しました。 ホストのカーネルを使うため、ハードウェア関連の処理が走らないため、高速に起動します。
コンテナにログイン
ユーザアカウントを「ubuntu」としてログインします。 パスワードを無効にしているため、パスワードの入力は不要です。
u01 login: ubuntu
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1018-raspi aarch64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
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.
パスワードの再設定
シャドウパスワードを使うように /etc/passwd を戻します。
ubuntu:x:1000:1000::/home/ubuntu:/bin/bash
sudo で passwd コマンドを使うと、現パスワードは不要。新たにパスワードを設定します。 ここではパスワードを「ubuntu」とした例を示します。
ubuntu@u01:~$ sudo passwd New password: ubuntu Retype new password: ubuntu passwd: password updated successfully ubuntu@u01:~$
コンテナに openssh-server をインストール
コンテナをデフォルトのデーモンモードで起動した場合に、外部からログインするために ssh サーバをインストールします。
ubuntu@u01:~$ sudo apt install openssh-server Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: libpsl5 libwrap0 ncurses-term openssh-sftp-server publicsuffix python3-distro ssh-import-id wget Suggested packages: molly-guard monkeysphere ssh-askpass ufw The following NEW packages will be installed: libpsl5 libwrap0 ncurses-term openssh-server openssh-sftp-server publicsuffix python3-distro ssh-import-id wget 0 upgraded, 9 newly installed, 0 to remove and 0 not upgraded. Need to get 1,344 kB of archives. After this operation, 7,572 kB of additional disk space will be used. Do you want to continue? [Y/n] : 略 :
起動中のコンテナの情報表示
コンテナが起動している時にホスト側から「lxc-info」コマンドを実行するとホスト側でのプロセスIDやIPアドレスが表示されます。
jun@Rpi4B:~$ sudo lxc-info u01
Name: u01
State: RUNNING
PID: 3525
IP: 10.0.3.210
Link: vethuqhm2B
TX bytes: 1.56 KiB
RX bytes: 3.70 KiB
Total bytes: 5.25 KiB
コンテナの停止
起動しているコンテナをホスト側から停止するには「lxc-stop」を使用します。
コンテナ内でshutdown
コンテナ内で「shutdown -h now」を実行してもコンテナは停止します。
ubuntu@u01:~$ sudo shutdown -h now
Stopping Session 5 of User ubuntu...
[ OK ] Removed slice Slice /system/getty.
[ OK ] Removed slice Slice /system/modprobe.
[ OK ] Stopped target Graphical Interface.
[ OK ] Stopped target Multi-User System.
[ OK ] Stopped target Login Prompts.
[ OK ] Stopped target Host and Network Name Lookups.
[ OK ] Stopped target Timer Units.
[ OK ] Stopped Daily apt upgrade and clean activities.
[ OK ] Stopped Daily apt download activities.
[ OK ] Stopped Daily dpkg database backup timer.
[ OK ] Stopped Periodic ext4 Online Metadata Check for All Filesystems.
[ OK ] Stopped Daily rotation of log files.
[ OK ] Stopped Message of the Day.
[ OK ] Stopped Daily Cleanup of Temporary Directories.
[ OK ] Stopped Ubuntu Advantage Timer for running repeated jobs.
[ OK ] Stopped target System Time Set.
Stopping Console Getty...
Stopping Container Getty on /dev/pts/1...
Stopping Container Getty on /dev/pts/2...
Stopping Container Getty on /dev/pts/3...
Stopping Container Getty on /dev/pts/4...
Stopping Regular background program processing daemon...
Stopping Dispatcher daemon for systemd-networkd...
Stopping System Logging Service...
Stopping OpenBSD Secure Shell server...
[ OK ] Stopped Regular background program processing daemon.
[ OK ] Stopped Dispatcher daemon for systemd-networkd.
[ OK ] Stopped System Logging Service.
[ OK ] Stopped Console Getty.
[ OK ] Stopped Container Getty on /dev/pts/1.
[ OK ] Stopped Container Getty on /dev/pts/2.
[ OK ] Stopped Container Getty on /dev/pts/3.
[ OK ] Stopped Container Getty on /dev/pts/4.
[ OK ] Stopped OpenBSD Secure Shell server.
[ OK ] Stopped Session 5 of User ubuntu.
[ OK ] Removed slice Slice /system/container-getty.
Stopping User Login Management...
Stopping User Manager for UID 1000...
[ OK ] Stopped User Login Management.
[ OK ] Stopped User Manager for UID 1000.
Stopping User Runtime Directory /run/user/1000...
[ OK ] Unmounted /run/user/1000.
[ OK ] Stopped User Runtime Directory /run/user/1000.
[ OK ] Removed slice User Slice of UID 1000.
[ OK ] Reached target Unmount All Filesystems.
Stopping Permit User Sessions...
[ OK ] Stopped Permit User Sessions.
[ OK ] Stopped target Basic System.
[ OK ] Stopped target Network.
[ OK ] Stopped target Path Units.
[ OK ] Stopped target Remote File Systems.
[ OK ] Stopped target Slice Units.
[ OK ] Removed slice User and Session Slice.
[ OK ] Stopped target Socket Units.
[ OK ] Stopped target System Initialization.
[ OK ] Stopped target Local Encrypted Volumes.
[ OK ] Stopped Dispatch Password Requests to Console Directory Watch.
[ OK ] Stopped Forward Password Requests to Wall Directory Watch.
[ OK ] Stopped target Swaps.
[ OK ] Stopped target Local Verity Protected Volumes.
[ OK ] Closed Syslog Socket.
Stopping Network Name Resolution...
Stopping Record System Boot/Shutdown in UTMP...
[ OK ] Stopped Network Name Resolution.
Stopping Network Configuration...
[ OK ] Stopped Record System Boot/Shutdown in UTMP.
[ OK ] Stopped Create Volatile Files and Directories.
[ OK ] Stopped target Local File Systems.
[ OK ] Stopped target Preparation for Local File Systems.
[ OK ] Stopped Create Static Device Nodes in /dev.
[ OK ] Stopped Network Configuration.
[ OK ] Stopped target Preparation for Network.
[ OK ] Closed Network Service Netlink Socket.
[ OK ] Stopped Apply Kernel Variables.
[ OK ] Stopped Create System Users.
[ OK ] Stopped Remount Root and Kernel File Systems.
[ OK ] Reached target System Shutdown.
[ OK ] Reached target Late Shutdown Services.
[ OK ] Finished System Power Off.
[ OK ] Reached target System Power Off.
Sending SIGTERM to remaining processes...
Sending SIGKILL to remaining processes...
All filesystems, swaps, loop devices, MD devices and DM devices detached.
Powering off.
ホスト側からコンテナを停止
ホスト側で「lxc-stop」を実行してもコンテナは停止します。
jun@Rpi4B:~$ sudo lxc-stop -n u01''-)
コンテナのネットワークをブリッジでホスト外に公開する設定
デフォルトのLXCの設定では、コンテナ側に設置されるブリッジを使った NAT を介してネットワークに繋がるため、コンテナ側から外部にアクセスはできますが、外部からコンテナ内のアプリケーションに接続することはできません。 ホスト側にブリッジを設定して、コンテナ内のシステムはホスト側のブリッジに接続することで、コンテナ内でサーバを運用する事ができます。
ホストの有線ネットワークをブリッジ設定に変更
Netplan の設定ファイルとして /etc/netplan/90-lxc.yaml を作成して、ホストのネットワークをブリッジを使う設定に変更します。 有線(172.18.21.220)と無線(172.18.21.221)を固定アドレスとして設定。
network: version: 2 renderer: networkd ethernets: eth0: dhcp4: no optional: true wifis: wlan0: dhcp4: no dhcp6: false addresses: [172.18.21.221/24] routes: - to: default via: 172.18.21.1 access-points: SSID: password: "password" bridges: br0: interfaces: - eth0 dhcp4: no addresses: [172.18.21.220/24] routes: - to: default via: 172.18.21.1 metric: 100 on-link: true nameservers: addresses: [172.18.21.1]
ホストのIP アドレスを確認
「sudo netplan apply」を実行するかリブートしてホスト側のIPアドレスを確認。
jun@Rpi4B:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000 link/ether 00:16:3e:00:00:6b brd ff:ff:ff:ff:ff:ff 3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000 link/ether 00:16:3e:00:00:6c brd ff:ff:ff:ff:ff:ff inet 172.18.21.221/24 brd 172.18.21.255 scope global wlan0 valid_lft forever preferred_lft forever inet6 fe80::dea6:32ff:fe71:616c/64 scope link valid_lft forever preferred_lft forever 4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:00:00:91 brd ff:ff:ff:ff:ff:ff inet 172.18.21.220/24 brd 172.18.21.255 scope global br0 valid_lft forever preferred_lft forever inet6 fe80::1c36:c0ff:fe05:9c91/64 scope link valid_lft forever preferred_lft forever 5: lxcbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 00:16:3e:00:00:00 brd ff:ff:ff:ff:ff:ff inet 10.0.3.1/24 brd 10.0.3.255 scope global lxcbr0 valid_lft forever preferred_lft forever
コンテナのネットワーク接続先の設定
コンテナの設定ファイル(/var/lib/lxc/u01/config)を修正して、ブリッジに接続します。
root@Rpi4B:~# cat /var/lib/lxc/u01/config # Template used to create this container: /usr/share/lxc/templates/lxc-download # Parameters passed to the template: # For additional config options, please look at lxc.container.conf(5) # Uncomment the following line to support nesting containers: #lxc.include = /usr/share/lxc/config/nesting.conf # (Be aware this has security implications) # Distribution configuration lxc.include = /usr/share/lxc/config/common.conf lxc.arch = linux64 # Container specific configuration lxc.rootfs.path = dir:/var/lib/lxc/u01/rootfs lxc.uts.name = u01 # Network configuration lxc.net.0.type = veth lxc.net.0.link = lxcbr0 lxc.net.0.flags = up lxc.net.0.hwaddr = 00:16:3e:8c:e6:83
以下のように変更する。
lxc.net.0.link = br0
コンテナを起動して確認
コンテナのネットワーク設定は DHCP のままのため、外側のDHCPに接続してIPアドレスを取得している。
ubuntu@u01:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:8c:e6:83 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.21.14/24 metric 100 brd 172.18.21.255 scope global dynamic eth0 valid_lft 172772sec preferred_lft 172772sec inet6 fe80::216:3eff:fe8c:e683/64 scope link valid_lft forever preferred_lft forever
コンテナを固定IPに変更
コンテナのネットワーク設定は /etc/netplan/10-lxc.yaml に設定されています。 デフォルトの設定では、IPアドレスや DNS のアドレスを DHCP で取得する設定になっています。
ubuntu@u01:~$ cat /etc/netplan/10-lxc.yaml
network:
version: 2
ethernets:
eth0:
dhcp4: true
dhcp-identifier: mac
有線を固定アドレス(172.18.21.222)として設定する。 コンテナ側の /etc/netplan/10-lxc.yaml を上書きするために /etc/netplan/20-lxc.yaml を作成する。
ubuntu@u01:~$ cat /etc/netplan/20-lxc.yaml network: version: 2 ethernets: eth0: dhcp4: no addresses: [172.18.21.222/24] routes: - to: default via: 172.18.21.1 nameservers: addresses: - 172.18.21.1
ubuntu@u01:~$ sudo netplan apply
ubuntu@u01:~$ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:8c:e6:83 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.21.222/24 brd 172.18.21.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fe8c:e683/64 scope link
valid_lft forever preferred_lft forever
windows11 のコマンドプロンプトから接続確認
外部からコンテナに接続します。
C:\Users\jun>ssh 172.18.21.222 -l ubuntu [email protected]'s password: Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1018-raspi aarch64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Last login: Thu Nov 24 11:25:54 2022 from 172.18.21.38 ubuntu@u01:~$
コンテナのスナップショットに関する操作
コンテナは、ホスト側の /var/lib/lxc/ 以下にディレクトリとして格納されます。 /var/lib/lxc/ のアクセスには管理者権限が必要なため、スナップショットの動作を確認するため、「sudo bash」を実行して、管理者権限で操作します。
コンテナのスナップショットの作成
root@Rpi4B:/var/lib/lxc/u01# ls -l
-rw-r----- 1 root root 669 11月 24 18:59 config
drwxr-xr-x 17 root root 4096 11月 24 20:12 rootfs
コンテナが起動した状態でスナップショットを作成する「lxc-snapshot」コマンドを実行します。 ls -
root@Rpi4B:/var/lib/lxc/u01# lxc-snapshot -n u01 root@Rpi4B:/var/lib/lxc/u01# ls -F config rootfs/ snaps/ root@Rpi4B:/var/lib/lxc/u01# ls -l snaps total 0
コンテナのディレクトリ (/var/lib/lxc/u01) 内に snaps ディレクトリは作成されましたが、中身はありません。
コンテナを停止します。
root@Rpi4B:/var/lib/lxc/u01# lxc-stop -n u01 root@Rpi4B:/var/lib/lxc/u01# lxc-info -n u01 Name: u01 State: STOPPED
スナップショットを作成します。
root@Rpi4B:/var/lib/lxc/u01# lxc-snapshot -n u01 root@Rpi4B:/var/lib/lxc/u01# ls -l snaps drwxrwx--- 3 root root 4096 11月 24 21:36 snap0
snap0 というディレクトリができて、スナップショットが作成されました。
もう1回スナップショットを作成してみます。今回は時間を測ってみます。
root@Rpi4B:/var/lib/lxc/u01# time lxc-snapshot -n u01
real 0m17.606s
user 0m2.955s
sys 0m20.147s
スナップショットはrootfs以下をすべてコピーするため、18秒ほどかかりました。 snap1 という新しいディレクトリができて、スナップショットが作成されたことが確認できます。 スナップショットのサイズは次のように600MB弱です。
root@Rpi4B:/var/lib/lxc/u01# cd snaps root@Rpi4B:/var/lib/lxc/u01/snaps# du . --max-depth=1 586888 ./snap1 586884 ./snap0 1173776 .
コンテナのスナップショットの一覧
「lxc-snapshot」コマンドに「-L」オプションを付けると、コンテナのスナップショットのリストが表示されます。
root@Rpi4B:~# lxc-snapshot -n u01 -L
snap1 (/var/lib/lxc/u01/snaps) 2022:11:24 23:00:09
snap0 (/var/lib/lxc/u01/snaps) 2022:11:24 21:36:54
コンテナのスナップショットの削除
コンテナの特定のスナップショットを削除するには、コンテナ名(-n)とスナップショット名(-d)を指定して「lxc-snapshot」を実行します。
root@Rpi4B:/var/lib/lxc# lxc-snapshot -n u01 -d snap1 root@Rpi4B:/var/lib/lxc# ls -l u01/snaps/ drwxrwx--- 3 root root 4096 11月 24 21:36 snap0
コンテナのスナップショットの復帰
スナップショットをコンテナに戻すには「-r」にスナップショット名を指定します。
root@Rpi4B:~# lxc-snapshot -n u01 -r snap0
コンテナのコピー
「-n コピー元コンテナ名」「-N コピー先コンテナ名」を指定して「lxc-copy」コマンドを実行することで、コンテナはコピーできます。 コピー先のコンテナ名はホスト名として使われます。 lxc-copy のソース(lxc_copy.c)を見ると、ホスト名等の書き換えや各種のエラーチェックの後に 「rsync -aHXS --delete src dest」を実行しているようです。
root@Rpi4B:~# lxc-copy -n u01 -N x01 root@Rpi4B:~# lxc-start -n x01 -F
コピーされたコンテナのネットワークカードのMACアドレスもランダムに設定されます。 コピー元の「u01」はIPアドレスを固定していたので、コピー先の「x01」コンテナも同じIPアドレスになってしまいます。そのまま同時に起動すると問題になります。 起動前に /var/lib/lxc/x01/rootfs/etc/netplan/20-lxc.yaml を修正すれば同時に起動できます。
Ubuntu 22.04.1 LTS x01 console x01 login: ubuntu Password: Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1018-raspi aarch64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Last login: Thu Nov 24 11:26:09 UTC 2022 from 172.18.21.38 on pts/5 ubuntu@x01:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:c3:8e:4c brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.21.222/24 brd 172.18.21.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::216:3eff:fec3:8e4c/64 scope link valid_lft forever preferred_lft forever
コンテナ「x01」をDHCP でIPアドレスを取得するように変更します。
ubuntu@x01:~$ sudo vi /etc/netplan/20-lxc.yaml
network:
version: 2
ethernets:
eth0:
dhcp4: yes
設定を反映してIPアドレスを確認します。
ubuntu@x01:~$ sudo netplan applybuntu@x01:~$ ip address ubuntu@x01:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:c3:8e:4c brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.21.14/24 metric 100 brd 172.18.21.255 scope global dynamic eth0 valid_lft 172800sec preferred_lft 172800sec inet6 fe80::216:3eff:fec3:8e4c/64 scope link valid_lft forever preferred_lft forever
コンテナが起動中にコピー
コンテナが起動中には、コピーできません。
jun@Rpi4B:~$ sudo lxc-copy -n x01 -N y01 jun@Rpi4B:~$ sudo lxc-ls u01 x01
「-a」オプションを付けると起動中にもコピー可能です。
jun@Rpi4B:~$ sudo lxc-copy -a -n x01 -N y01 jun@Rpi4B:~$ sudo lxc-ls u01 x01 y01
コピー先を起動してIPアドレスを確認
jun@Rpi4B:~$ sudo lxc-start -n y01 -F
「lxc-copy」コマンドでコピーするとホスト名、MACアドレスが変更され、DHCPでIPアドレスを取得すると、別のIPアドレスが割り振られてそのまま起動できます。
Ubuntu 22.04.1 LTS y01 console
y01 login: ubuntu
Password:
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1018-raspi aarch64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Last login: Thu Nov 24 14:08:52 UTC 2022 on console
ubuntu@y01:~$ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:16:3e:1a:c2:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.21.16/24 metric 100 brd 172.18.21.255 scope global dynamic eth0
valid_lft 172790sec preferred_lft 172790sec
inet6 fe80::216:3eff:fe1a:c204/64 scope link
valid_lft forever preferred_lft forever
コンテナの運用
コンテナの固定IPアドレスの変更用スクリプト
ホスト側で管理者権限で実行すると、固定IPアドレス用の /var/lib/xlc/コンテナ名/etc/netplan/20-lxc.yaml を書き込むスクリプト。
手動で十分可能な範囲の作業ではあるが、何度も実行するためには合ってもいいかな? あまり凝りすぎるとLXCを直接使うメリットが薄くなってしまう。
$ cat lxc_setip.sh
#!/bin/sh
# usage: sudo ./lxc_setip.sh 192.168.0.123 container_name
# or ./lxc_setip.sh 192.168.0.123
# 2022-11-27
IP=$1
CONTAINER_NAME=$2
CONTAINER_PATH=/var/lib/lxc/$CONTAINER_NAME/rootfs
NETPLAN_PATH=/etc/netplan/
NNAME=20-lxc.yaml
IP24=`echo $IP |awk -F. '{print $1 "." $2 "." $3}'`
GW=1
DNS=1
NETCONF=$(cat << EOF
network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses: [$IP/24]
routes:
- to: default
via: $IP24.$GW
nameservers:
addresses:
- $IP24.$DNS
EOF
)
if [ $# = 0 ]; then
echo usage: sudo ./lxc_setip.sh 192.168.0.123 container_name
echo or ./lxc_setip.sh 192.168.0.123
exit 1
fi
if [ $# = 1 ]; then
CONTAINER_PATH=/var/lib/lxc/CONTAINER_NAME/rootfs
echo $CONTAINER_PATH$NETPLAN_PATH$NNAME
echo "$NETCONF"
exit 1
fi
if [ $# = 2 ]; then
if [ -e $CONTAINER_PATH ]; then
echo "$NETCONF" > $CONTAINER_PATH$NETPLAN_PATH$NNAME
else
echo ERROR: Container not exist.
exit 1
fi
fi
コンテナ名を指定しないとファイルに書き込む内容を表示するだけ。
$ ~/lxc_setip.sh 192.168.0.12
network:
version: 2
ethernets:
eth0:
dhcp4: no
addresses: [192.168.0.12/24]
routes:
- to: default
via: 192.168.0.1
さて、これまでの操作で3つのコンテナができています。 コンテナの状況を確認すると停止している状態です。
jun@Rpi4B:~$ sudo lxc-ls u01 x01 y01 jun@Rpi4B:~$ sudo lxc-info u01 Name: u01 State: STOPPED jun@Rpi4B:~$ sudo lxc-info x01 Name: x01 State: STOPPED jun@Rpi4B:~$ sudo lxc-info y01 Name: y01 State: STOPPED
上のスクリプトを使って、以下のような固定IPアドレスに設定します。
コンテナ名 | IPアドレス | 固定IPアドレス |
---|---|---|
u01 | 172.18.21.222 | <-- |
x01 | DHCP | 172.18.21.223 |
y01 | DHCP | 172.18.21.224 |
jun@Rpi4B:~$ sudo ./lxc_setip.sh 172.18.21.223 x01 jun@Rpi4B:~$ sudo lxc-start x01 jun@Rpi4B:~$ sudo lxc-info x01 Name: x01 State: RUNNING PID: 8189 IP: 172.18.21.223 Link: vethMMFG71 TX bytes: 766 bytes RX bytes: 2.98 KiB Total bytes: 3.73 KiB
jun@Rpi4B:~$ sudo ./lxc_setip.sh 172.18.21.224 y01 jun@Rpi4B:~$ sudo lxc-start y01 jun@Rpi4B:~$ sudo lxc-info y01 Name: y01 State: RUNNING PID: 8340 IP: 172.18.21.224 Link: vethAxLEti TX bytes: 696 bytes RX bytes: 2.26 KiB Total bytes: 2.94 KiB
コンテナの名前の変更
jun@Rpi4B:~$ sudo lxc-copy -R -n y01 -N z01 jun@Rpi4B:~$ sudo lxc-ls u01 x01 y01
jun@Rpi4B:~$ sudo lxc-stop -n y01 jun@Rpi4B:~$ sudo lxc-copy -R -n y01 -N z01 jun@Rpi4B:~$ sudo lxc-ls u01 x01 z01
実行して確認します。 今回はデーモンモードで起動して、lxc-console でコンソールに接続しています。
jun@Rpi4B:~$ sudo lxc-start z01 jun@Rpi4B:~$ sudo lxc-console z01 Connected to tty 1 Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself Ubuntu 22.04.1 LTS z01 pts/1 z01 login: ubuntu Password: Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1018-raspi aarch64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Last login: Sun Nov 27 09:11:27 UTC 2022 on pts/1 ubuntu@z01:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:e1:7a:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.21.224/24 brd 172.18.21.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::216:3eff:fee1:7af6/64 scope link valid_lft forever preferred_lft forever
ログインした状態で抜けた場合は、lxc-consoleで再接続するとログインした状態になっています。
jun@Rpi4B:~$ sudo lxc-console z01
Connected to tty 1
Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself
ubuntu@z01:~$
コンテナをWebサーバに
apache2 のインストール
ubuntu@z01:~$ sudo apt update ubuntu@z01:~$ sudo apt upgrade
ubuntu@z01:~$ sudo apt install apache2 Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: apache2-bin apache2-data apache2-utils bzip2 file libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libbrotli1 libcurl4 libgdbm-compat4 libgdbm6 libjansson4 libldap-2.5-0 libldap-common liblua5.3-0 libmagic-mgc libmagic1 libnghttp2-14 libperl5.34 librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libssh-4 mailcap mime-support perl perl-modules-5.34 ssl-cert xz-utils Suggested packages: apache2-doc apache2-suexec-pristine | apache2-suexec-custom www-browser ufw bzip2-doc gdbm-l10n libsasl2-modules-gssapi-mit | libsasl2-modules-gssapi-heimdal libsasl2-modules-ldap libsasl2-modules-otp libsasl2-modules-sql perl-doc libterm-readline-gnu-perl | libterm-readline-perl-perl make libtap-harness-archive-perl The following NEW packages will be installed: apache2 apache2-bin apache2-data apache2-utils bzip2 file libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libbrotli1 libcurl4 libgdbm-compat4 libgdbm6 libjansson4 libldap-2.5-0 libldap-common liblua5.3-0 libmagic-mgc libmagic1 libnghttp2-14 libperl5.34 librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db libssh-4 mailcap mime-support perl perl-modules-5.34 ssl-cert xz-utils 0 upgraded, 33 newly installed, 0 to remove and 0 not upgraded. Need to get 11.8 MB of archives. After this operation, 67.0 MB of additional disk space will be used. Do you want to continue? [Y/n]
Webサーバを追加
コンテナの名前を「y01」として、「z01」をコピーして、固定IPアドレスを設定します。
jun@Rpi4B:~$ sudo lxc-copy -n z01 -N y01 jun@Rpi4B:~$ sudo ./lxc_setip.sh 172.18.21.225 y01
jun@Rpi4B:~$ sudo lxc-start -n y01
curl をインストール
ubuntu@z01:~$ sudo apt install curl Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: curl 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 190 kB of archives. After this operation, 436 kB of additional disk space will be used. Get:1 http://ports.ubuntu.com/ubuntu-portsjammy-updates/main arm64 curl arm64 7.81.0-1ubuntu1.6 [190 kB] Fetched 190 kB in 2s (89.5 kB/s) Selecting previously unselected package curl. (Reading database ... 21984 files and directories currently installed.) Preparing to unpack .../curl_7.81.0-1ubuntu1.6_arm64.deb ... Unpacking curl (7.81.0-1ubuntu1.6) ... Setting up curl (7.81.0-1ubuntu1.6) ...
rvtl64 をインストール
ubuntu@z01:~$ curl https://www.mztn.org/rvtl/rvtl-arm64_4.01b.tar.gz >rvtl-arm64_4.01b.tar.gz
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 146k 100 146k 0 0 410k 0 --:--:-- --:--:-- --:--:-- 411k
ubuntu@z01:~$ ls -lt
-rw-rw-r-- 1 ubuntu ubuntu 149606 Nov 27 14:57 rvtl-arm64_4.01b.tar.gz
ubuntu@z01:~$ tar zxf rvtl-arm64_4.01b.tar.gz ubuntu@z01:~$ cd rvtl-arm64 ubuntu@z01:~/rvtl-arm64$ sudo cp rvtl64 /usr/bin ubuntu@z01:~/rvtl-arm64$ cd /usr/bin ubuntu@z01:/usr/bin$ sudo ln -s rvtl64 rvtlw ubuntu@z01:/usr/bin$ cd
ubuntu@z01:~$ rvtl64 RVTL64 Arm64 v.4.01b 2019/06/27,(C)2019 Jun Mizutani RVTL may be copied under the terms of the GNU General Public License. <0156> 10 "A=" A=? / <0156> 20 "B=" B=? / <0156> 30 "A+B=" ?=A+B / <0156> 40 "A-B=" ?=A-B / <0156> 50 "A*B=" ?=A*B / <0156> 60 "A/B=" ?=A/B / <0156> 70 "Hit Any Key (q:quit) :" C=$ / <0156> 80 ;=(C='q')|(C='Q') #=-1 <0156> 90 #=10 <0156> 0 10 "A=" A=? / 20 "B=" B=? / 30 "A+B=" ?=A+B / 40 "A-B=" ?=A-B / 50 "A*B=" ?=A*B / 60 "A/B=" ?=A/B / 70 "Hit Any Key (q:quit) :" C=$ / 80 ;=(C='q')|(C='Q') #=-1 90 #=10 <0156> #=1 A=1234567890 B=34562346 A+B=1269130236 A-B=1200005544 A*B=42669562574669940 A/B=35 Hit Any Key (q:quit) :q <0156>
build-essential のインストール
C や C++ の開発環境をインストールしてみます。
ubuntu@z01:~$ sudo apt install build-essential
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
binutils binutils-aarch64-linux-gnu binutils-common cpp cpp-11 dirmngr
dpkg-dev fakeroot fontconfig-config fonts-dejavu-core g++ g++-11 gcc gcc-11
gcc-11-base gnupg gnupg-l10n gnupg-utils gpg gpg-agent gpg-wks-client
gpg-wks-server gpgconf gpgsm libalgorithm-diff-perl
libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan6 libassuan0
libatomic1 libbinutils libc-dev-bin libc-devtools libc6-dev libcc1-0
libcrypt-dev libctf-nobfd0 libctf0 libdeflate0 libdpkg-perl libfakeroot
libfile-fcntllock-perl libfontconfig1 libfreetype6 libgcc-11-dev libgd3
libgomp1 libhwasan0 libisl23 libitm1 libjbig0 libjpeg-turbo8 libjpeg8
libksba8 liblsan0 libmpc3 libmpfr6 libnpth0 libnsl-dev libpng16-16
libstdc++-11-dev libtiff5 libtirpc-dev libtsan0 libubsan1 libwebp7 libxpm4
linux-libc-dev lto-disabled-list make manpages manpages-dev patch
pinentry-curses rpcsvc-proto
Suggested packages:
binutils-doc cpp-doc gcc-11-locales dbus-user-session pinentry-gnome3 tor
debian-keyring gcc-11-doc gcc-multilib autoconf automake libtool flex bison
gdb gcc-doc parcimonie xloadimage scdaemon glibc-doc git bzr libgd-tools
libstdc++-11-doc make-doc man-browser ed diffutils-doc pinentry-doc
The following NEW packages will be installed:
binutils binutils-aarch64-linux-gnu binutils-common build-essential cpp
cpp-11 dirmngr dpkg-dev fakeroot fontconfig-config fonts-dejavu-core g++
g++-11 gcc gcc-11 gcc-11-base gnupg gnupg-l10n gnupg-utils gpg gpg-agent
gpg-wks-client gpg-wks-server gpgconf gpgsm libalgorithm-diff-perl
libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan6 libassuan0
libatomic1 libbinutils libc-dev-bin libc-devtools libc6-dev libcc1-0
libcrypt-dev libctf-nobfd0 libctf0 libdeflate0 libdpkg-perl libfakeroot
libfile-fcntllock-perl libfontconfig1 libfreetype6 libgcc-11-dev libgd3
libgomp1 libhwasan0 libisl23 libitm1 libjbig0 libjpeg-turbo8 libjpeg8
libksba8 liblsan0 libmpc3 libmpfr6 libnpth0 libnsl-dev libpng16-16
libstdc++-11-dev libtiff5 libtirpc-dev libtsan0 libubsan1 libwebp7 libxpm4
linux-libc-dev lto-disabled-list make manpages manpages-dev patch
pinentry-curses rpcsvc-proto
0 upgraded, 76 newly installed, 0 to remove and 0 not upgraded.
Need to get 70.3 MB of archives.
After this operation, 222 MB of additional disk space will be used.
Do you want to continue? [Y/n]
git のインストール
ubuntu@z01:~$ sudo apt install git Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: git-man libcurl3-gnutls liberror-perl Suggested packages: gettext-base git-daemon-run | git-daemon-sysvinit git-doc git-email git-gui gitk gitweb git-cvs git-mediawiki git-svn The following NEW packages will be installed: git git-man libcurl3-gnutls liberror-perl 0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded. Need to get 4,426 kB of archives. After this operation, 21.1 MB of additional disk space will be used. Do you want to continue? [Y/n]
コンテナのバックアップとリストア
コンテナのバックアップ
root@Rpi4B:/var/lib/lxc# time tar zcf z01.tar.gz z01
real 1m59.082s
user 1m54.932s
sys 0m10.781s
root@Rpi4B:/var/lib/lxc# ls -l
drwxrwx--- 4 root root 4096 11月 24 22:58 u01
drwxrwx--- 3 root root 4096 11月 27 20:00 x01
drwxrwx--- 3 root root 4096 11月 27 23:44 y01
drwxrwx--- 3 root root 4096 11月 27 21:27 z01
-rw-r--r-- 1 root root 300376640 11月 28 00:55 z01.tar.gz
コンテナの削除
root@Rpi4B:/var/lib/lxc# lxc-destroy -n z01 root@Rpi4B:/var/lib/lxc# lxc-ls u01 x01 y01
lxc-destroy を実行するとコンテナのディレクトリが削除されます。
root@Rpi4B:/var/lib/lxc# ls -l drwxrwx--- 4 root root 4096 11月 24 22:58 u01 drwxrwx--- 3 root root 4096 11月 27 20:00 x01 drwxrwx--- 3 root root 4096 11月 27 23:44 y01 -rw-r--r-- 1 root root 300376640 11月 28 00:55 z01.tar.gz
コンテナのリストア
root@Rpi4B:/var/lib/lxc# tar zxf z01.tar.gz
root@Rpi4B:/var/lib/lxc# lxc-ls
u01 x01 y01 z01
コンテナの動作確認
root@Rpi4B:/var/lib/lxc# lxc-start z01 root@Rpi4B:/var/lib/lxc# lxc-console z01 Connected to tty 1 Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself Ubuntu 22.04.1 LTS z01 pts/1 z01 login: ubuntu Password: Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1018-raspi aarch64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Last login: Sun Nov 27 14:52:56 UTC 2022 on pts/1 ubuntu@z01:~$ git --version git version 2.34.1 ubuntu@z01:~$ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 00:16:3e:e1:7a:f6 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.18.21.224/24 brd 172.18.21.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::216:3eff:fee1:7af6/64 scope link valid_lft forever preferred_lft forever
Webサーバも動作していることが確認できました。
コンテナを4台稼働
コンテナを4台稼働した状態で、ホスト側から見えるプロセスを確認します。
root@Rpi4B:~# lxc-info u01 Name: u01 State: RUNNING PID: 12652 IP: 172.18.21.222 Link: vetheoMg4R TX bytes: 696 bytes RX bytes: 2.20 KiB Total bytes: 2.87 KiB root@Rpi4B:~# lxc-info x01 Name: x01 State: RUNNING PID: 8189 IP: 172.18.21.223 Link: vethMMFG71 TX bytes: 1.57 KiB RX bytes: 2.35 MiB Total bytes: 2.35 MiB root@Rpi4B:~# lxc-info z01 Name: z01 State: RUNNING PID: 12383 IP: 172.18.21.224 Link: veth3MgAiQ TX bytes: 9.00 KiB RX bytes: 106.43 KiB Total bytes: 115.43 KiB root@Rpi4B:~# lxc-info y01 Name: y01 State: RUNNING PID: 10520 IP: 172.18.21.225 Link: vethKuHEKf TX bytes: 9.73 KiB RX bytes: 849.50 KiB Total bytes: 859.23 KiB
ホスト側から見たプロセスの状態は、lxc-start で始まり systemd につながる通常のプロセスとして見えます。
jun@Rpi4B:~$ pstree -A
|-lxc-monitord
|-2*[lxc-start---systemd-+-5*[agetty]]
| |-cron]
| |-dbus-daemon]
| |-networkd-dispat]
| |-rsyslogd---3*[{rsyslogd}]]
| |-sshd]
| |-systemd-journal]
| |-systemd-logind]
| |-systemd-network]
| `-systemd-resolve]
|-lxc-start---systemd-+-5*[agetty]
| |-apache2---2*[apache2---26*[{apache2}]]
| |-cron
| |-dbus-daemon
| |-networkd-dispat
| |-rsyslogd---3*[{rsyslogd}]
| |-sshd
| |-systemd-journal
| |-systemd-logind
| |-systemd-network
| `-systemd-resolve
|-lxc-start---systemd-+-4*[agetty]
| |-apache2---2*[apache2---26*[{apache2}]]
| |-cron
| |-dbus-daemon
| |-login---bash
| |-networkd-dispat
| |-rsyslogd---3*[{rsyslogd}]
| |-sshd
| |-systemd---(sd-pam)
| |-systemd-journal
| |-systemd-logind
| |-systemd-network
| `-systemd-resolve
|-lxcfs---3*[{lxcfs}]
コンテナの運用まとめ
コンテナを運用する上で必要となる可能性が高い操作をまとめました。
どのようなコンテナがホスト上に存在しているか
コンテナのリストは「lxc-ls」でリストできます。
jun@Rpi4B:~$ sudo lxc-ls
u01 x01 y01 z01
各コンテナの稼働状況のチェック
どのコンテナが動作しているかは「lxc-info」で調べられます。
jun@Rpi4B:~$ sudo lxc-info u01'''me: u01 Name: u01 State: STOPPED jun@Rpi4B:~$ sudo lxc-info x01'''me: x01 Name: x01 State: STOPPED jun@Rpi4B:~$ sudo lxc-info y01'''me: y01 Name: y01 State: STOPPED jun@Rpi4B:~$ sudo lxc-info z01'''me: z01 Name: z01 State: STOPPED
コンテナの起動
完成したコンテナを起動するには「sudo lxc-start [-n] コンテナ名」を実行します。
デーモンモード
コンテナがバックグラウンドで動作するモード。 起動したコンソールを閉じてもコンテナの動作し続けます。
jun@Rpi4B:~$ sudo lxc-start -n u01 jun@Rpi4B:~$ sudo lxc-info u01 Name: u01 State: RUNNING PID: 17079 IP: 172.18.21.222 Link: vethRs5RI5 TX bytes: 976 bytes RX bytes: 13.79 KiB Total bytes: 14.75 KiB
デーモンモードのコンテナにコンソール接続
デーモンモードで起動中のコンテナで SSHD が動作している場合は、ssh で接続できるが、 ネットワークの設定に問題がある場合などコンソールに接続する方法が用意されています。 デーモンモードで起動中のコンテナのコンソールに接続するには、ホスト側で lxc-console を実行します。
jun@Rpi4B:~$ sudo lxc-console -n u01 Connected to tty 1 Type <Ctrl+a q> to exit the console, <Ctrl+a Ctrl+a> to enter Ctrl+a itself Ubuntu 22.04.1 LTS u01 pts/1 u01 login:
コンテナをフォアグラウンドで実行
「lxc-start」のオプションとして「-F」を付加すると、使用中のコンソールでコンテナが起動されます。 起動したコンソールを閉じてもコンテナの動作し続けます。 起動したコンソールを閉じるとコンテナは停止します。
jun@Rpi4B:~$ sudo lxc-start -F -n u01 systemd 249.11-0ubuntu3.6 running in system mode (+PAM +AUDIT +SELINUX +APPARMOR +IMA +SMACK +SECCOMP +GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBFDISK +PCRE2 -PWQUALITY -P11KIT -QRENCODE +BZIP2 +LZ4 +XZ +ZLIB +ZSTD -XKBCOMMON +UTMP +SYSVINIT default-hierarchy=unified) Detected virtualization lxc. Detected architecture arm64. Welcome to Ubuntu 22.04.1 LTS! Queued start job for default target Graphical Interface. [ OK ] Created slice Slice /system/container-getty. [ OK ] Created slice Slice /system/modprobe. : 略 : [ OK ] Finished Record Runlevel Change in UTMP. Ubuntu 22.04.1 LTS u01 console u01 login:
コンソールは現在使用中のtty に割り当てられるため、ホスト側から起動中のコンテナを操作するには別にコンソールを開いてコンテナを操作する必要があります。 コンテナのコンソール内で shutdown するとコンテナは終了します。
コンテナの更新、構成変更
コンテナで構成されたシステムは、コンテナ側の仕組みで自動的に更新されることはありません。 通常の Linux と同じように「apt update、apt upgrade」でパッケージの更新を行います。 一旦コンテナが作成され、ネットワーク構成は決まった後は、コンテナを意識した特別な作業はなく、通常の Linuxと同じように操作するだけです。
コンテナの停止
ホスト側からの停止は「sudo lxc-stop -n コンテナ名」を実行します。 コンテナ側から停止する場合は 「sudo shutdown -h now:を実行します。
新規サーバ(コンテナ)の作成
構成が大きく変わらない限り新規のコンテナを作成(lxc-create)はなく、既存のコンテナのコピーを作成(lxc-copy)して、IPアドレスの変更などから始めるのが楽です。
コンテナのバックアップ
コンテナのバックアップは、コンテナを停止した状態でスナップショットの作成(lxc-snapshot)で行います。 スナップショットは snap0 から次々と作成されるため、(lxc-snapshot -n コンテナ名 -d スナップショット名)で削除することができます。
コンテナのオフラインバックアップ
コンテナをオフラインでバックアップするには、コンテナのディレクトリ(/var/lib/lxc/コンテナ名)を tar で固めたファイルを保管します。 復帰するにはコンテナを固めた tar.gz ファイルを /var/lib/lxc/ で展開します。
ホストマシンの変更
新旧のホストマシン間で rsync でコピーするか、オフラインバックアップ用のコンテナを固めた tar.gz ファイルをLXCをインストールした新規ホストの /var/lib/lxc/ で展開します。 ホストマシンでブリッジで設定されていれば、ゲスト側(コンテナ側)のIPアドレスを変更する必要はありません。 ただし、CPUの種類が異なる(amd64 から arm64 など)システムへの移行はできません(動作しません)。