Container setup
LXC
This section documents the processes of configuring LXC on distros supported by Gel.
Installation
- Alpine:
apk add lxc lxcfs lxc-download lxc-bridge
- Debian:
apt install lxc
- openSUSE:
zypper in lxc
- Rocky Linux/AlmaLinux:
dnf install lxc lxcfs lxc-templates
- Photon: N/A
Config files
- Container config files:
/var/lib/lxc/<name>/config
Container creation from official templates
When creating containers from official templates, you'll be presented with a list of available distros, alongwith release names and CPU architectures. Visit for the full list.
To select a source image directly without the selection prompt, use the following command.
lxc-create -t download -n "<name>" -- --dist <distro> --release <release> --arch <arch>
Assign static IPs
From Setup network bridge in lxc-net.
Create /etc/lxc/dhcp.conf
. The definitions go in dhcp-host=<containerName>,<ip>
format. Example below.
dhcp-host=deerHorny,10.0.3.114
dhcp-host=polakCute,10.0.3.115
If /etc/default/lxc-net
exists, have the following line inside to tell lxc-net
use the DHCP config before restarting the lxc-net
service.
LXC_DHCP_CONFILE=/etc/lxc/dhcp.conf
Enable autostart
In the container config, have the following lines.
# Enable autostart
lxc.start.order = <startOrder> # Lower is earlier
lxc.start.auto = 1
lxc.start.delay = 4 # In seconds
Enable nested containerization
In the container config, have the following lines.
# Allow nested containerization
lxc.include = /usr/share/lxc/config/nesting.conf
Enable FUSE
In the container config, have the following lines.
# Enable FUSE
lxc.mount.entry = /dev/fuse dev/fuse none bind,create=file,rw 0 0
Enable TUN
In the container config, have the following lines.
# Enable TUN
lxc.mount.entry = /dev/net dev/net none bind,create=dir
lxc.cgroup2.devices.allow = c 10:200 rwm
Limit container network access
From How to restrict network access of LXC container.
Limit CPU and RAM usage
From Memory Controller ă»cgroup2.
In the container config, follow the example provided below.
# Limit CPU and RAM
lxc.cgroup2.memory.min = 268435456
lxc.cgroup2.memory.max = 536870912
lxc.cgroup2.cpu.max = 500000 1000000
This sets the container to...
- Use at most 512 MiB of RAM (hard limit), with 256 MiB guaranteed (hard limit).
- Allows using half of a core's worth of computing power.
Raise limits on opened files
From Proxmox ulimit hell: how to really increase open files ?
In /etc/sysctl.conf
, make sure the following lines are present. Feel free to adjust the values to your needs.
fs.inotify.max_queued_events = 1048576
fs.inotify.max_user_instances = 1048576
fs.inotify.max_user_watches = 1048576
vm.max_map_count = 262144
In /etc/security/limits.conf
, have the following lines. Feel free to adjust the values to your needs.
* soft nofile 1048576 unset
* hard nofile 1048576 unset
root soft nofile 1048576 unset
root hard nofile 1048576 unset
* soft memlock 1048576 unset
* hard memlock 1048576 unset
In the container config, have the following lines. Feel free to adjust the values to your needs.
# Raise limits on opened files
lxc.prlimit.nofile = 1048576
Inside the container, have the following lines in /etc/security/limits.conf
. Feel free to adjust the values to your needs.
* soft nofile 1048576 unset
* hard nofile 1048576 unset
root soft nofile 1048576 unset
root hard nofile 1048576 unset
* soft memlock 1048576 unset
* hard memlock 1048576 unset
Reboot the host and the container(s) to apply the changes.
Manual unprivileged container setup
Extended from this blog post.
The containers configured these way are unprivileged, however they are owned by root
, this is due to the problems surrounding unprivileged containers when owned by unprevileged users.
You can create the container before or after assigning subordinate IDs manually, but it must be done before modifying the container's configuration file. All commands in this section assume root
privilege unless told explicitly otherwise.
Select and map subordinate IDs
Subordinate IDs permit mapping a range of IDs to a user, allowing the container to run unprivileged without the typical downsides. To avoid conflicts, it's advised to reserve a relatively large gap between different unprivileged containers in multiples of 65536
, the minimum required amount of subordinate IDs for running unprivileged containers of any kind.
You'll be editing /etc/subuid
for user IDs, and /etc/subgid
for group IDs. Both files follow the same scheme: <username>:<startID>:<idCount>
. For example, hornydeer:2097152:65536
maps IDs from 2097152
to 2162687
to user hornydeer
, 65536 IDs in total. Comments are not allowed there.
As an example, we're setting the start UID and start GID to 1148576, and allocate 65536 IDs for use by the container. If you intend to have an LXC container act as a container host, you may need to scale up the count of IDs. Write the following line to both /etc/subuid
and /etc/subgid
.
root:1148576:65536
If you're going to run unprivileged containers inside the target unprivileged LXC, below is an example reserving enough subordinate IDs for use.
root:1148576:262144
Apply mapped IDs in configuration
To apply the mapped IDs, head to /var/lib/lxc/<containerName>
and modify the config
file. According to the containerized distro chosen, there may be seperate user namespace profiles, so switch to those if you encounter problems.
# Remapped user and group IDs
lxc.include = /usr/share/lxc/config/userns.conf
lxc.idmap = u 0 1148576 65536
lxc.idmap = g 0 1148576 65536
If you've chosen to use the larger ID space for unprivileged containers above, below is the corresponding example.
# Remapped user and group IDs
lxc.include = /usr/share/lxc/config/userns.conf
lxc.idmap = u 0 1148576 262144
lxc.idmap = g 0 1148576 262144
Change owner of the container root
Before the LXC container could be started, the owner of its root folder must be set as the beginning subordinate ID, 1148576
in the case of the example. Run the following command.
chown -R 1148576:1148576 /var/lib/lxc/<containerName>/rootfs
Also ensuring the container itself can access its own filesystem for good measure.
chmod 755 /var/lib/lxc # Most distros already has this as default
chmod 755 /var/lib/lxc/<containerName>
chmod 755 /var/lib/lxc/<containerName>/rootfs
chmod 640 /var/lib/lxc/<containerName>/config
Podman
This section documents the processes of setting up Podman on distros supported by Gel. To get Podman functioning, fuse
and tun
support has to be present.
If you're running Podman inside an (unprivileged) LXC container, make sure the steps listed below have all been applied to the host LXC container, all of which could be found above.
- Assign a larger ID space
- Enable FUSE
- Enable nested containerization
- Enable TUN
- Raise limits on opened files
Installation
Warning
- Certain distros (e.g. Debian) may not have a functioning version of
crun
. Installcrun
from Nixpkgs when such errors are encountered.- A few distros like Photon do not have
podman-compose
bundled.- If you encounter warnings regarding
/
not being shared, fix temporarily withmount --make-rshared /
. Read Alpine Wiki for further info.
- Alpine:
apk add podman podman-compose
- Debian:
apt install podman podman-compose
- openSUSE:
zypper in podman podman-compose
- Rocky Linux/AlmaLinux:
dnf install podman podman-compose
- Photon:
tdnf install podman
After installation, run a "Hello World" container to ensure everything works correctly.
podman run --rm hello-world
If problems occur, below is an example command for debugging.
podman run --security-opt="seccomp=unconfined" --log-level=debug --rm hello-world
Manual subordinate ID assign
Note Distros may already have this section configured automatically. Only follow this section when you encounter problems.
Explanations about subordinate IDs are available in previous sections. If you encounter Podman complaining about IDs, below is an example inside unprivileged LXC containers to apply in both /etc/subuid
and /etc/subgid
.
<username>:65536:131072
Run podman system migrate
whenever the assigned subordinate ID space changes.