Making lxc unprivilaged container as systemd services

I have a config file created for an unprivilaged container

lxc.idmap = u 0 231072 1002
lxc.idmap = g 0 231072 1003
lxc.idmap = u 1002 1002 1
lxc.idmap = g 1003 1003 1
lxc idmap = u 1004 232075 64533
lxc.idmap = g 1005 232076 64532

The container starts when i login with the user of the above uid and gid mapping and then i call lxc-starts.
Now i want to start this container as systemd service. Im facing some problems in that. so it would be helpful if i get the below clarifications

My questions are:

  1. Is it possible to start the unprivilaged container without logging in as the unprivilaged user?

  2. Where do i have to keep the systemd service file for the container. is it in /etc/systemd/system or /lib/systemd/system?

  3. this config file is placed now placed in some folder inside the unprivilaged user login. if i have to start the container as systemd service, where should i place the config file

I used
lxc-start -n app -f config command to start the container after logging in as unprivilaged user, which is working fine

if i give ExecStart = /usr/bin/lxc-start -n app -f config, i dont think the container config and container name will be resolved

Could you please guide me on how to do this

Hi @brauner @stgraber ,

Could you please provide your feedback.

For those kind of setups, I’d just put the containers in /var/lib/lxc and use the normal systemd units that come with LXC. The containers will be started by the root user but will run inside a user namespace so it doesn’t really matter.

Hi @stgraber ,
Got the below error
Loaded: loaded (/etc/systemd/system/lxc_app.service; static; vendor preset: enabled)
Active: failed (Result: exit-code) since Wed 2021-08-11 21:57:43 CEST; 21ms ago
Process: 21947 ExecStart=/usr/local/bin/lxc-start -n app -f /var/lib/lxc/app/config -l DEBUG -o /tmp/appLog.txt (code=exited, status=1/FAILURE)
Main PID: 21947 (code=exited, status=1/FAILURE)

Aug 11 21:57:43 topas-dev systemd[1]: Started Service file to start container named app…
Aug 11 21:57:43 topas-dev lxc-start[21947]: lxc-start: app: lxccontainer.c: wait_on_daemonized_start: 825 No such file or directory - Failed to receive the container state
Aug 11 21:57:43 topas-dev lxc-start[21947]: The container failed to start.
Aug 11 21:57:43 topas-dev lxc-start[21947]: To get more details, run the container in foreground mode.
Aug 11 21:57:43 topas-dev lxc-start[21947]: Additional information can be obtained by setting the --logfile and --logpriority options.
Aug 11 21:57:43 topas-dev systemd[1]: lxc_app.service: Main process exited, code=exited, status=1/FAILURE
Aug 11 21:57:43 topas-dev systemd[1]: lxc_app.service: Failed with result ‘exit-code’.
lxc-start app 20210811195743.308 INFO lxc_confile - confile.c:set_config_idmaps:1666 - Read uid map: type u nsid 0 hostid 231072 range 1002
lxc-start app 20210811195743.308 INFO lxc_confile - confile.c:set_config_idmaps:1666 - Read uid map: type g nsid 0 hostid 231072 range 1003
lxc-start app 20210811195743.308 INFO lxc_confile - confile.c:set_config_idmaps:1666 - Read uid map: type u nsid 1002 hostid 1002 range 1
lxc-start app 20210811195743.308 INFO lxc_confile - confile.c:set_config_idmaps:1666 - Read uid map: type g nsid 1003 hostid 1003 range 1
lxc-start app 20210811195743.308 INFO lxc_confile - confile.c:set_config_idmaps:1666 - Read uid map: type g nsid 1005 hostid 232076 range 64532
lxc-start app 20210811195743.308 INFO lxc_container - lxccontainer.c:do_lxcapi_start:948 - Attempting to set proc title to [lxc monitor] /home/appfw/.local/share/lxc app
lxc-start app 20210811195743.308 INFO lxc_lsm - lsm/lsm.c:lsm_init:46 - LSM security driver nop
lxc-start app 20210811195743.309 INFO terminal - terminal.c:lxc_terminal_setup:902 - No terminal requested
lxc-start app 20210811195743.309 ERROR lxc_cgfsng - cgroups/cgfsng.c:all_controllers_found:695 - No freezer controller mountpoint found
lxc-start app 20210811195743.309 ERROR lxc_cgroup - cgroups/cgroup.c:cgroup_init:43 - Failed to initialize cgroup driver
lxc-start app 20210811195743.309 ERROR lxc_start - start.c:lxc_init:853 - Failed to initialize cgroup driver
lxc-start app 20210811195743.309 ERROR lxc_start - start.c:__lxc_start:1853 - Failed to initialize container “app”
lxc-start app 20210811195743.309 DEBUG lxc_container - lxccontainer.c:wait_on_daemonized_start:822 - First child 21948 exited
lxc-start app 20210811195743.309 ERROR lxc_container - lxccontainer.c:wait_on_daemonized_start:825 - No such file or directory - Failed to receive the container state

service file used is,
[Unit]
Description =start container .

[Service]
User=appfw
Group=appfw
Delegate=yes
ExecStart = /usr/local/bin/lxc-start -n app -f /var/lib/lxc/app/config -l DEBUG -o /tmp/appLog.txt

ls /sys/fs/cgroup/
blkio cpu cpuacct cpu,cpuacct cpuset devices freezer hugetlb memory net_cls net_cls,net_prio net_prio perf_event pids rdma systemd unified

When i login as unprivilaged user, i can start the container normally without any errors. and also i can see below within started container.
cat /proc/self/cgroup
12:blkio:/user.slice
11:freezer:/user/appfw/0
10:devices:/user/appfw/0
9:hugetlb:/
8:cpuset:/user/appfw/0
7:pids:/user.slice/user-1001.slice/session-3.scope
6:rdma:/
5:cpu,cpuacct:/user/appfw/0
4:net_cls,net_prio:/
3:perf_event:/
2:memory:/user/appfw/0
1:name=systemd:/user/appfw/0
0::/user.slice/user-1001.slice/session-3.scope

Problem is only when i start the container with systemd service file.

appfw@topas-dev:/var/lib/lxc/app$ findmnt | grep cgroup
│ ├─/sys/fs/cgroup tmpfs tmpfs rw,nosuid,nodev,noexec,mode=755
│ │ ├─/sys/fs/cgroup/unified cgroup cgroup2 rw,nosuid,nodev,noexec,relatime
│ │ ├─/sys/fs/cgroup/systemd cgroup cgroup rw,nosuid,nodev,noexec,relatime,xattr,name=systemd
│ │ ├─/sys/fs/cgroup/memory cgroup cgroup rw,nosuid,nodev,noexec,relatime,memory
│ │ ├─/sys/fs/cgroup/perf_event cgroup cgroup rw,nosuid,nodev,noexec,relatime,perf_event
│ │ ├─/sys/fs/cgroup/net_cls,net_prio cgroup cgroup rw,nosuid,nodev,noexec,relatime,net_cls,net_prio
│ │ ├─/sys/fs/cgroup/cpu,cpuacct cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpu,cpuacct
│ │ ├─/sys/fs/cgroup/rdma cgroup cgroup rw,nosuid,nodev,noexec,relatime,rdma
│ │ ├─/sys/fs/cgroup/pids cgroup cgroup rw,nosuid,nodev,noexec,relatime,pids
│ │ ├─/sys/fs/cgroup/cpuset cgroup cgroup rw,nosuid,nodev,noexec,relatime,cpuset,clone_children
│ │ ├─/sys/fs/cgroup/hugetlb cgroup cgroup rw,nosuid,nodev,noexec,relatime,hugetlb
│ │ ├─/sys/fs/cgroup/devices cgroup cgroup rw,nosuid,nodev,noexec,relatime,devices
│ │ ├─/sys/fs/cgroup/freezer cgroup cgroup rw,nosuid,nodev,noexec,relatime,freezer
│ │ └─/sys/fs/cgroup/blkio cgroup cgroup rw,nosuid,nodev,noexec,relatime,blkio

My system has both cgrup and cgroup2 available . will it have any ambuguity
grep cgroup /proc/filesystems
nodev cgroup
nodev cgroup2

Everything works fine when i login as user and execute lxc-start. Looks like inside the user login cgroupv1 is used and with systemd cgroupv2 is used

@brauner @stgraber
Your feedback would help for me to know on lxc further

Any suggestions on this?

I gave you a recommendation above (root owned unprivileged containers) but you chose not to follow it, I don’t have any experience in doing what you’re trying to do here.

Sorry if i confused you. Im trying to use your suggestion ,but i am not getting the right way to do it.

I have my container in /var/lib/lxc.

I am not sure about “normal systemd units that come with LXC” which you mentioned in your comment. Is the service file already available in the locally built lxc

I tried to use available lxc@.service and lxc.service but got the below error
sudo systemctl status lxc@app.service  :gear:
● lxc@app.service - LXC Container: app
Loaded: loaded (/etc/systemd/system/lxc@.service; disabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Thu 2021-08-12 18:20:06 CEST; 3s ago
Docs: man:lxc-start
man:lxc
Process: 32040 ExecStart=/usr/local/bin/lxc-start -F -n app -f /var/lib/lxc/app/config -l trace -o /tmp/appLog.txt (code=exited, status=1/FAILURE)
Main PID: 32040 (code=exited, status=1/FAILURE)

Aug 12 18:20:05 topas-dev systemd[1]: Started LXC Container: app.
Aug 12 18:20:05 topas-dev lxc-start[32040]: lxc-start: app: conf.c: lxc_map_ids: 2919 newuidmap failed to write mapping “newuidmap: uid range [0-1002) → [231072-232074) not allowed”: newuidmap 32042 0 23
Aug 12 18:20:05 topas-dev lxc-start[32040]: lxc-start: app: start.c: lxc_spawn: 1661 Failed to set up id mapping.
Aug 12 18:20:05 topas-dev lxc-start[32040]: lxc-start: app: start.c: __lxc_start: 1887 Failed to spawn container “app”
Aug 12 18:20:05 topas-dev lxc-start[32040]: lxc-start: app: conf.c: lxc_map_ids: 2919 newuidmap failed to write mapping “newuidmap: uid range [0-1002) → [231072-232074) not allowed”: newuidmap 32052 0 23
Aug 12 18:20:05 topas-dev lxc-start[32040]: lxc-start: app: conf.c: userns_exec_1: 4222 Error setting up {g,u}id mappings for child process “32052”
Aug 12 18:20:06 topas-dev lxc-start[32040]: The container failed to start.
Aug 12 18:20:06 topas-dev lxc-start[32040]: Additional information can be obtained by setting the --logfile and --logpriority options.
Aug 12 18:20:06 topas-dev systemd[1]: lxc@app.service: Main process exited, code=exited, status=1/FAILURE
Aug 12 18:20:06 topas-dev systemd[1]: lxc@app.service: Failed with result ‘exit-code’.

As your container is now being started by the root user, you must make sure your /etc/subuid and /etc/subgid entries match that user.

Since systemctl commands are run on host, If i change /etc/subuid /etc/subgid to the root user then it becomes privileged container right?

Now i am able to start the unprivilaged container with systemd using systemd lingering option in the service file.

Since in config file there are unprivilaged user mappings present, i can confirm that container started using sudo systemctl command runs in my unprivilaged user namespace. When i login as unprivilaged user, i am able to attach to the container started by systemctl command on host

We can close this topic. Thank you for assisting on the topic

No, a privileged container would be a container started by root and with no idmap.
A container started by root where root in the container isn’t mapped to root on the host, is still an unprivileged container (and that’s what LXD for example does for its unprivileged containers).