2022/06/17
systemd-run
is needed to run lxc.systemd-networkd
systemd
to start the container.export TERM=xterm-256color
to fix it.user@host ~> cat /proc/self/cgroup 1
0::/user.slice/user-1000.slice/session-1.scope
user@host ~> systemd-run --user --scope --collect --shell 1
Running scope as unit: run-r7f23525aef1e46c0aa667f4b2b2a5705.scope
user@host ~> cat /proc/self/cgroup
0::/user.slice/user-1000.slice/user@1000.service/app.slice/run-r7f23525aef1e46c0aa667f4b2b2a5705.scope
user@host ~> lxc-create -t download -n penguin -- --dist debian --release bullseye --arch amd64
Using image from local cache
Unpacking the rootfs
---
You just created a Debian bullseye amd64 (20220603_05:24) container.
To enable SSH, run: apt install openssh-server
No default root or user password are set by LXC.
user@host ~> lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
firefox STOPPED 0 - - - true
spyder STOPPED 0 - - - true
penguin STOPPED 0 - - - true
user@host ~> lxc-start penguin
user@host ~> lxc-attach penguin --clear-env
root@penguin:/# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
[...]
user@host ~> lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
firefox STOPPED 0 - - - true
spyder STOPPED 0 - - - true
penguin RUNNING 0 - - - true
user@host ~> lxc-stop penguin
user@host ~> lxc-destroy penguin
user@host ~> lxc-ls --fancy
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
firefox STOPPED 0 - - - true
spyder STOPPED 0 - - - true
If you do not execute systemd-run
you will get an error like the following:
user@host ~> lxc-start firefox -F
Failed to mount cgroup at /sys/fs/cgroup/systemd: Operation not permitted
[!!!!!!] Failed to mount API filesystems.
Exiting PID 1...
--logfile|-o
Output to an alternate log FILE.--logpriority|-l
Set log priority to LEVEL. FATAL, ALERT, CRIT, WARN, ERROR (def), NOTICE, INFO, DEBUG, TRACE.--lxcpath|-P
Use an alternate container path.lxc-ls [-1] [--active] [--frozen] [--running] [--stopped] [--defined] [-f] [-F format] [-g groups] [--nesting=NUM] [--filter=regex]
lxc-ls --fancy
---
NAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED
firefox STOPPED 0 - - - true
gui STOPPED 0 - - - true
lxc-start {-n name} [-f config_file] [-c console_device] [-L console_logfile] [-d] [-F] [-p pid_file] [-s KEY=VAL] [-C]
[--share-[net|ipc|uts] name|pid] [command]
lxc-start --foreground --name firefox --logfile=/tmp/test/log --logpriority=DEBUG
--foreground|-F
Run the container in the foreground. Shows errors and console output.--name|-n
(optional) Name of the container.--daemon|-d
Run the container as a daemon without a TTY. It does not show errors.lxc-attach {-n, --name name} [-f, --rcfile config_file] [-a, --arch arch] [-e, --elevated-privileges privileges]
[-s, --namespaces namespaces] [-R, --remount-sys-proc] [--keep-env] [--clear-env]
[-v, --set-var variable] [--keep-var variable] [-u, --uid uid] [-g, --gid gid] [-- command]
lxc-attach -n firefox --clear-env
lxc-attach -n firefox --clear-env --uid 1000 -- firefox
--uid|-u
Executes the command with user ID uid inside the container.--gid|--g
Executes the command with group ID gid inside the container.--clear-env
lxc-create {-n name} [-f config_file] {-t template} [-B backingstore] [-- template-options]
lxc-create penguin -t download
lxc-create -t download -n firefox -- --dist debian --release bullseye --arch amd64
lxc-create -t download -- --list
/usr/share/lxc/templates
.lxc-console {-n name} [-e escape character] [-t ttynum]
lxc-console -n test
Ctrl+a q
to exit.
lxc-info {-n name} [-c KEY] [-s] [-p] [-i] [-S] [-H]
lxc-info firefox
lxc-stop {-n name} [-W] [-r] [-t timeout] [-k] [--nokill] [--nolock]
lxc-stop firefox
--reboot|-r
Request a reboot of the container.--kill|-k
Rather than requesting a clean shutdown of the container, explicitly kill all tasks in the container.--nokill
Only request a clean shutdown, do not kill the container tasks if the clean shutdown fails.lxc-destroy {-n name} [-f] [-s]
lxc-destroy -n test
lxc-checkconfig
Check the current kernel for lxc support
This indicates there is not support for cgroups v1.
[...]
Cgroup v1 systemd controller: missing
Cgroup v1 freezer controller: missing
Cgroup ns_cgroup: required
[...]
lxc-checkpoint {-n name} {-D PATH} [-r] [-s] [-v] [-d] [-F]
systemd-run
systemd-run --user --scope --collect --shell
systemd-run --user --scope --collect lxc-start container
systemd-run --unit=myshell --user --scope -p "Delegate=yes" lxc-start --name penguin --foreground
systemd-run --unit=myshell1 --user --property=AllowedCPUs=0,1 -p TasksMax=100 -p Delegate=yes lxc-start -n penguin
--user
Talk to the service manager of the calling user, rather than the service manager of the system.--unit
Use this unit name instead of an automatically generated one.--scope
Create a transient .scope unit instead of the default transient .service unit--collect|-G
Unload the transient unit after it completed, even if it failed.--shell
requests an interactive shell in the current working directory--property|-p
Sets a property on the scope or service unit that is created."Delegate=yes"
allow delegation of everything"Delegate=cpu cpuset io memory pids"
allow delegation of cpu, cpuset, io, memory and pids.For more info check man systemd-run
and man systemd.resource-control
.
Show current systemd scope.
cat /proc/self/cgroup
---
0::/user.slice/user-1000.slice/user@1000.service/app.slice/run-r463d33efe17540179ac04d01f657faaa.scope
Defaults
~/.config/lxc/defaults.conf
---
Network
/etc/lxc/lxc-usernet
---
By default, a non-root user can only get memory controller and pids controller to be delegated.
See the currently allowed delegations.
cat /sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/cgroup.controllers
---
memory pids
To allow delegation of other controllers such as cpu, cpuset, and io, run the following commands:
sudo mkdir -p /etc/systemd/system/user@.service.d
cat <<EOF | sudo tee /etc/systemd/system/user@.service.d/delegate.conf
[Service]
Delegate=cpu cpuset io memory pids
EOF
sudo systemctl daemon-reload
Delegating cpuset is recommended as well as cpu. Delegating cpuset requires systemd 244 or later.
After changing the systemd configuration, you need to re-login or reboot the host. Rebooting the host is recommended.
UID 0
inside the container is UID 0
outside the container.
Authorize your UIDs to map ranges of UIDs from its namespace into child namespaces.
You can write only user:100000:100000
but I wanted to do it differently as I have a different setup.
/etc/subuid
---
root:1000000:65536
lxd:1065536:65536
user:1131072:65536
/etc/subgid
---
root:1000000:65536
lxd:1065536:65536
user:1131072:65536
user:1131072:65536
means that user users
can map 65536
UIDs from 1131072
, so from 1131072
to 1196608
.
You need to reboot to apply the changes.
Some people only map 65530
but that will brake the system as user nobody
uses 65534
and it is needed.
Allow user user to create up to 30 veth (virtual ethernet) devices connected to the virbr2 network bridge.
/etc/lxc/lxc-usernet
---
yu veth virbr2 30
~/.config/lxc/default.conf
---
lxc.net.0.type = veth
lxc.net.0.link = virbr2
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx
lxc.idmap = u 0 1131072 65536
lxc.idmap = g 0 1131072 65536
Configure pulseaudio to create a socket at /run/user/1000/pulse-socket
/etc/pulse/default.pa
load-module module-native-protocol-unix auth-anonymous=1 socket=/run/user/1000/pulse-socket
Restart pulseaudio.
rm -rf /tmp/pulse* /run/user/1000/pulse* ~/.pulse* ~/.config/pulse
pulseaudio -k
pulseaudio --start
Nothing, it already creates the socket at /run/user/1000/wayland-1
.
Get the character
ls -la /dev/dri/ 1
---
drwxr-xr-x 3 root root 100 Jun 17 11:21 .
drwxr-xr-x 20 root root 4460 Jun 17 15:37 ..
drwxr-xr-x 2 root root 80 Jun 17 11:21 by-path
crw-rw----+ 1 root video 226, 0 Jun 17 11:21 card0
crw-rw-rw- 1 root render 226, 128 Jun 17 11:21 renderD128
card0
and rederD128
only do 3D acceleration, they do not output video. card1
does output video but I do not have it.
Allow the UID 1131072
(0
inside the container) access to mount (--x
) /run/user/1000
and UID 1132072
(1000
inside the container) to write (rwx
) to wayland and pulseaudio.
setfacl -m u:1131072:--x /run/user/1000
setfacl -m u:1132072:rwx /run/user/1000/wayland-1
setfacl -m u:1132072:rwx /run/user/1000/pulse-socket
Create the container
lxc-create -t download -n firefox -- --dist debian --release bullseye --arch amd64
Map the required sockets into the container. The last three lines are only needed for 3D rendering.
~/.local/share/lxc/firefox/config
---
lxc.mount.entry = /run/user/1000/pulse-socket home/user/1000/pulse-socket none bind,create=file,rw 0 0
lxc.mount.entry = /run/user/1000/wayland-1 home/user/1000/wayland-1 none bind,create=file,rw 0 0
lxc.mount.entry = /dev/dri/renderD128 dev/dri/renderD128 none bind,create=file,rw 0 0
lxc.cgroup2.devices.allow = c 226:128 rwm
lxc.cgroup2.devices.allow = c 226:0 rwm
Start the container and attach
lxc-start firefox
lxc-attach firefox --clear-env
Fix the terminal.
export TERM=xterm-256color
Install dependencies.
apt update
apt install -y xwayland weston x11-apps mesa-utils pulseaudio firefox-esr
Configure pulseaudio.
/etc/pulse/client.conf
---
default-server = unix:/home/user/1000/pulse-socket
Create new user.
useradd -u 1000 -m user
echo "user:user" | chpasswd
passwd -u user
As the folder /home/user
already exists no new files are created so copy the skel
directory into the user’s home.
cp /etc/skel/.bash_logout /home/user/.bash_logout
cp /etc/skel/.bashrc /home/user/.bashrc
cp /etc/skel/.profile /home/user/.profile
Configure required environment variables.
/home/user/.bashrc
---
export TERM=xterm-256color
export XDG_RUNTIME_DIR=/home/user/1000
export WAYLAND_DISPLAY=wayland-1
export QT_QPA_PLATFORM=wayland
export DISPLAY=:0
export MOZ_ENABLE_WAYLAND=1
Make sure all files are owned by the user.
chown user:user /home/user
chmod 0750 /home/user
chown user:user /home/user/1000
Start the GUI app.
su user -l -c firefox