Previous Post | Top | Next Post |
TOC
Here is a series of memos of me trying to use LXC/LXD on Debian 12 (bookworm
).
Default LXD Debian image issues
Let me simply use the default LXD Debian image to launch d0
instance with:
$ lxd launch images:debian/12/cloud d0
Then, the resulting d0
image has a few glitches to my taste:
- The primary user in the container is always
debian
having UID=1000, GID=1001 - The
netdev
group is generated as GID=1000 (this is system group and should have GID somewhere between 100 and 999.)
Here are my efforts to get a sane instance generated.
./lxcinit
: local fixed-up image generation command
I first created local image with primary user name set to osamu
and without
netdev
in groups-list as deb-12
-image:
$ lxc init images:debian/12/cloud d0
$ lxc file edit d0/etc/cloud/cloud.cfg
$ lxc publish d0 --alias deb-12
Please note that the “write_files:” part in “user.user-data:” portion of YAML
data is implemented by cloud-config
in rather later part of its process. So
trick to use this functionality to update /etc/cloud/cloud.cfg
doesn’t work.
Later, in order to automate this, I created a script to fix its image:
lxcinit. This
removes netdev
group and optionally changes the primary user to osamu
for
cloud-init.
$ lxcinit -h
=============================================================================
NAME:
lxcinit -- download lxd Debian cloud image and make local fixed image
"deb-<name>"
SYNOPSIS:
lxcinit [-b|-d|-h|-p|-u|--] [<name>]
DESCRIPTION:
lxcinit creates a local un-previlidged LXD image "deb-<name>" just like
the following but with some fix-ups on /etc/cloud/cloud.cfg:
$ lxc init images:debian/<name>/cloud deb-<name>
$ lxc publish deb-<name> --alias=deb-<name>
The default <name> is "sid". The <name> consists of the codename or the
release version:
- "sid", "trixie", "bookworm", "bullseye", "buster", 12, 11, 10
You can't have an existing instance name such as deb-<name> for this
command to function.
OPTIONS: (only the first character matters)
-base BASE set base name as BASE ("deb-")
-delete delete unmodified instance deb-<name>
-help print this help message and exit
-primary match primary user name in container with the current user
-update update the local image deb-<name> after removing it first.
=============================================================================
This was an interesting practice for me to get familiar with lxc publish ...
.
But TBH, this is a bit cumbersome to use. So I don’t use this much.
Configuration of LXD instance
Instead of fixing the image itself, I tried to generate properly configured instance with the existing configuration to minimize overhead.
We can launch a LXD instance in 2 ways using YAML data user.yaml
.
- Configure directly with YAML
- merge strategy
lxc launch images:debian/12/cloud d0 <user.yaml
user.yaml
is merged with thedefault
profile
- merge strategy
- Configure indirectly with profile
- merge strategy
- create profile
user
withlxc profile create user
- edit profile
user
withlxc profile edit user < user.yaml
lxc launch images:debian/12/cloud d0 --profile default --profile user
- the
user
profile is merged to thedefault
profile
- the
- create profile
- replace strategy
- create profile
user
withlxc profile create user
- edit profile
user
withlxc profile edit user < user.yaml
lxc launch images:debian/12/cloud d0 --profile user
- the
user
profile replaces thedefault
profile
- the
- create profile
- merge strategy
The latter style using profile provides me with an organized working environment.
Overriding default_user
of cloud-init with profile
The root cause of issue is default_user
data provided as the default cloud-init setting and cloud-init automatically creates normal group if it finds missing group name in groups
list. These can be seen in /etc/cloud/cloud.cfg
as:
...
default_user:
name: debian
lock_passwd: True
gecos: Debian
groups: [adm, audio, cdrom, dialout, dip, floppy, netdev, plugdev, sudo, video]
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
shell: /bin/bash
I found out this feature is the intended feature, I needed to find an easy way to override this default setting.
I eventually found “Users and Groups” on cloud-init reference document. The “Summary” explanation was confusing for me. So I tried “Examples” to see how thisfeature can be used.
Test script users.sh
I created a simple shell script users.sh
to test configuration.
#!/bin/sh -e
lxc stop d0 >/dev/null 2>&1 || true
lxc delete d0 >/dev/null 2>&1 || true
lxc ls -f compact | grep d0 || true
echo "I: ===== YAML data $1 ==========="
cat $1
echo "I: ===== launch d0 =============="
lxc launch images:debian/12/cloud d0 <$1
echo "I: ===== wait 3 sec ==="
sleep 3
echo "I: ===== check home directory ==="
lxc exec d0 -- ls -la /home
echo "I: ===== check /etc/passwd ======"
lxc exec d0 -- tail -n5 /etc/passwd
echo "I: ===== check /etc/group ======="
lxc exec d0 -- egrep -e "(adm|plugdev|netdev|osamu|debian)" /etc/group
NOTE: Instead of waiting for 3 seconds with sleep 3
and hoping for the start
up process is finished, lxc exec d0 -- cloud-init status --wait
may address
this requirement better.
Override default_user
settings (1)
The following simply sets users:
to an empty list overrides default_user
settings.
$ ./users.sh users0.yaml
I: ===== YAML data users0.yaml ===========
config:
user.user-data: |
#cloud-config
users: []
I: ===== launch d0 ==============
Creating d0
Starting d0
I: ===== wait 3 sec ===
I: ===== check home directory ===
total 0
drwxr-xr-x 1 root root 0 Sep 29 20:04 .
drwxr-xr-x 1 root root 154 Nov 18 05:29 ..
I: ===== check /etc/passwd ======
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-resolve:x:997:997:systemd Resolver:/:/usr/sbin/nologin
I: ===== check /etc/group =======
adm:x:4:
plugdev:x:46:
This can avoid setting netdev
to GID=1000 but can’t have the primary user.
Override default_user
settings (2)
The following sets users:
to a list with updated name:
and groups:
list
overrides default_user
settings.
$ ./users.sh users1.yaml
I: ===== YAML data users1.yaml ===========
config:
user.user-data: |
#cloud-config
users:
- name: osamu
groups: [adm, mail]
I: ===== launch d0 ==============
Creating d0
Starting d0
I: ===== wait 3 sec ===
I: ===== check home directory ===
total 0
drwxr-xr-x 1 root root 10 Nov 19 03:32 .
drwxr-xr-x 1 root root 154 Nov 18 05:29 ..
drwxr-xr-x 1 osamu osamu 62 Nov 19 03:33 osamu
I: ===== check /etc/passwd ======
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
messagebus:x:100:101::/nonexistent:/usr/sbin/nologin
systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin
systemd-resolve:x:997:997:systemd Resolver:/:/usr/sbin/nologin
osamu:x:1000:1000::/home/osamu:/bin/sh
I: ===== check /etc/group =======
adm:x:4:osamu
mail:x:8:osamu
plugdev:x:46:
osamu:x:1000:
This can avoid setting netdev
to GID=1000 and sets the primary user to
osamu
with reasonable UID/GID..
In order this to add “osamu” to all groups (excluding netdev
) as the initial
list, groups: [adm, audio, cdrom, dialout, dip, floppy, plugdev, sudo, video]
should be used in user0.yaml
instead.
Previous Post | Top | Next Post |