能書き
自宅サーバー構築譚:基本構想に基づく自宅サーバー構築、Ubuntu22.04LTSインストールその2の続きです。
先日インストールしたLXDでコンテナを作成する際にcloud-initを使ってみました。その手順を公開します。同じ内容の記事は大量にありますが、いずれも若干バージョンが古いようで、この記事は最新版に対応した内容です。と言っても大した差はありませんが。
目標
/etc
をSubversionでバージョン管理します。具体的には以前書いた記事の通りの仕込みです。
ついでにタイムゾーンとロケールも設定します。
参考文献
- cloud-initを使ったLinux OSの初期設定 - Qiita
- cloud-initを使用するには
- LXDとcloud-initを使ってコンテナインスタンスを自動作成する
- Quick-start tutorial with LXD
cloud-initを実験してみました
コンテナを作成
cloud-init実験用コンテナを作成します。launch
ではなくてinit
とします。
そしてイメージはubuntu/jammy
ではなくてubuntu/jammy/cloud
です。
コンテナ名はtest1
としましょう。折角なのでIPアドレスを192.168.0.3
で固定してみます。
lxc init images:ubuntu/jammy/cloud test1 --device eth0,ipv4.address=192.168.0.3
確認。
lxc ls
実行結果はこうなります。STATEがSTOPPEDです。
$ lxc ls
+-------+---------+------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+------+------+-----------+-----------+
| test1 | STOPPED | | | CONTAINER | 0 |
+-------+---------+------+------+-----------+-----------+
設定
新しいバージョンだとcloud-init.user-data
に設定するようです。設定方法は下記。
今回は実験として、/var/tmp/test.txt
に適当な文言を出力するだけの内容です。
lxc config set test1 cloud-init.user-data="$(cat <<___
#cloud-config
runcmd:
- echo "hello, world" >/var/tmp/test.txt
___
)"
設定した内容を確認。
lxc config show test1
確認結果は下記のようになります。
$ lxc config show test1
architecture: x86_64
config:
cloud-init.user-data: |-
#cloud-config
runcmd:
- echo "hello, world" >/var/tmp/test.txt
image.architecture: amd64
image.description: Ubuntu jammy amd64 (20230427_07:42)
image.os: Ubuntu
image.release: jammy
image.serial: "20230427_07:42"
image.type: squashfs
image.variant: cloud
volatile.apply_template: create
volatile.base_image: ef8308fae2cb4394f755363e108a8e59e4b1484a754f519e416557206fa6ca77
volatile.cloud-init.instance-id: c4d4282c-a884-49e3-b821-d682774affe6
volatile.eth0.hwaddr: 00:16:3e:69:f6:3d
volatile.idmap.base: "0"
volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
volatile.last_state.idmap: '[]'
volatile.uuid: 1f950763-ace2-4e86-8f9c-d8ae167d8f00
devices:
eth0:
ipv4.address: 192.168.0.3
name: eth0
network: lxdbr0
type: nic
ephemeral: false
profiles:
- default
stateful: false
description: ""
確認
ここでコンテナを起動します。
lxc start test1
起動しました。
$ lxc ls
+-------+---------+--------------------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+--------------------+------+-----------+-----------+
| test1 | RUNNING | 192.168.0.3 (eth0) | | CONTAINER | 0 |
+-------+---------+--------------------+------+-----------+-----------+
cloud-initが正しく動いたか確認します。
lxc file pull test1/var/tmp/test.txt -
hello, world
と表示されれば成功です。
$ lxc file pull test1/var/tmp/test.txt -
hello, world
初回だけ動く事を確認
作成されたファイルを削除します。
lxc file rm test1/var/tmp/test.txt
削除されました。
$ lxc exec test1 ls /var/tmp/test.txt
ls: cannot access '/var/tmp/test.txt': No such file or directory
コンテナを止めます。
lxc stop test1
lxc ls
止まればSTATEがSTOPPEDと表示されます。
$ lxc stop test1
$ lxc ls
+-------+---------+------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+------+------+-----------+-----------+
| test1 | STOPPED | | | CONTAINER | 0 |
+-------+---------+------+------+-----------+-----------+
コンテナを再開します。
lxc start test1
lxc ls
STATEがRUNNINGとなった事を確認。
$ lxc start test1
$ lxc ls
+-------+---------+------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+------+------+-----------+-----------+
| test1 | RUNNING | | | CONTAINER | 0 |
+-------+---------+------+------+-----------+-----------+
さて/var/tmp/test.txt
は如何に?
lxc exec test1 ls /var/tmp/test.txt
作成されないのが正しいです。
$ lxc exec test1 ls /var/tmp/test.txt
ls: cannot access '/var/tmp/test.txt': No such file or directory
ヨシ!
後始末
コンテナを止めて削除します。
lxc stop test1
lxc rm test1
lxc ls
cloud-initでいつもの初期設定を実現しました
作成と設定
下記の設定を実現してみます。
ついでにTimezoneとLocaleも設定しておきましょう。
lxc init images:ubuntu/jammy/cloud test2 --device eth0,ipv4.address=192.168.0.4
lxc config set test2 cloud-init.user-data="$(cat <<___
#cloud-config
timezone: Asia/Tokyo
locale: ja_JP.utf8
package_upgrade: true
packages:
- subversion
runcmd:
- [mkdir, /etc/.svn_repo]
- [svnadmin, create, /etc/.svn_repo/]
- [mkdir, /tmp/etc]
- [svn, import, /tmp/etc, file:///etc/.svn_repo/, -m, create project]
- [rmdir, /tmp/etc]
- [svn, co, file:///etc/.svn_repo/, /etc]
- rm -v /etc/ssl/certs/NetLock*
- [/bin/bash, -c, ls /etc/ssl/certs/*.0 | while read f; do echo -n \$f\$'\\t'; readlink \$f; done | grep NetLock | cut -f 1 | xargs -rt rm]
- [sed, -i, -e, /NetLock/d, /etc/ca-certificates.conf.dpkg-old, /etc/ca-certificates.conf]
- svn add /etc/*
- [/bin/bash, -c, ls /etc/*- | xargs -rt svn revert]
- [svn, ci, /etc, -m, first commit]
- [svn, up, /etc]
- /bin/bash -c "cd /etc; svn propset svn:ignore -F <(svn st | cut -b9-) ."
- [svn, ci, /etc, -m, set svn:ignore]
___
)"
lxc start test2
状態を確認するにはcloud-init status
を実行します。
lxc exec test2 cloud-init status
すぐに実行すると、まだ実行中かも知れません。
$ lxc exec test2 cloud-init status
status: running
--wait
オプションを付けると、完了するまで待ってくれます。
$ lxc exec test2 -- cloud-init status --wait
.............................................
status: done
結果を確認
まずはタイムゾーン。date
コマンドを実行します。
lxc exec test2 date
UTCではなくてJSTで表示されればOK。
$ lxc exec test2 date
Fri Apr 28 18:04:29 JST 2023
次にロケール。localectl
コマンドを実行します。
lxc exec test2 localectl
指定したLANG=ja_JP.utf8
となっていればOKです。
$ lxc exec test2 localectl
System Locale: LANG=ja_JP.utf8
VC Keymap: n/a
X11 Layout: us
X11 Model: pc105
/etc
のSubversion管理は、ログを確認してみましょう。
lxc exec test2 svn log /etc
成功していれば下記のようになります。
$ lxc exec test2 svn log /etc
------------------------------------------------------------------------
r2 | root | 2023-04-28 20:49:30 +0900 (Fri, 28 Apr 2023) | 1 line
"set svn:ignore"
------------------------------------------------------------------------
r1 | root | 2023-04-28 20:49:28 +0900 (Fri, 28 Apr 2023) | 1 line
"first commit"
------------------------------------------------------------------------
ログ
cloud-initのログは/var/log
に出力される模様。
-
cloud-init.log
。cloud-init自体のログです。 -
cloud-init-output.log
。cloud-init実行中の、標準出力と標準エラー出力が書き込まれるようです。
これらを見てデバッグする事になります。
$ lxc exec test2 -- /bin/bash -c "ls /var/log/cloud-init*.log"
/var/log/cloud-init-output.log /var/log/cloud-init.log
$ lxc exec test2 -- head -n5 /var/log/cloud-init.log
2023-04-29 02:04:57,689 - util.py[DEBUG]: Cloud-init v. 23.1.2-0ubuntu0~22.04.1 running 'init-local' at Sat, 29 Apr 2023 02:04:57 +0000. Up 1.35 seconds.
2023-04-29 02:04:57,689 - main.py[DEBUG]: No kernel command line url found.
2023-04-29 02:04:57,689 - main.py[DEBUG]: Closing stdin.
2023-04-29 02:04:57,697 - util.py[DEBUG]: Writing to /var/log/cloud-init.log - ab: [640] 0 bytes
2023-04-29 02:04:57,698 - util.py[DEBUG]: Changing the ownership of /var/log/cloud-init.log to 104:4
$ lxc exec test2 -- tail /var/log/cloud-init-output.log
Transmitting file data .................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................done
Committing transaction...
Committed revision 1.
Updating 'etc':
At revision 1.
property 'svn:ignore' set on '.'
Sending etc
Committing transaction...
Committed revision 2.
Cloud-init v. 23.1.2-0ubuntu0~22.04.1 finished at Sun, 21 May 2023 02:39:09 +0000. Datasource DataSourceLXD. Up 25.57 seconds
後始末
コンテナを止めて削除します。
lxc stop test2
lxc rm test2
仕舞い
cloud-initを使ってLXDコンテナの初期化をしました。私の手順に従って、タイムゾーンとロケールと、/etc
のバージョン管理を設定して、内容を確認できました。初期設定の自動化!やったね