Setting-up LXC on Slackware Linux

this is draft because we should setup unprivileged instances by tuning cgroups and namespaces

Install

no need to run the init script unless you have instances configured already

slackpkg install lxc gnutls p11-kit nettle bridge-utils
ls -lF /etc/rc.d/rc.lxc*
chmod +x /etc/rc.d/rc.lxc

ldd /usr/bin/lxc-info
lxc-info --version

slackpkg install libcgroup sysvinit-functions
ls -lF /etc/rc.d/rc.cg*
chmod +x /etc/rc.d/rc.cgconfig /etc/rc.d/rc.cgred
/etc/rc.d/rc.cgconfig start
/etc/rc.d/rc.cgred start

lxc-checkconfig

you will also need debootstrap in case you plan to deploy Debian or Ubuntu. But then you will be stuck with SystemD issues anyhow. We’re proceeding with the deployment of a slackware instance in this guide.

Setup LXC

ls -lF /var/lib/lxc/
mv /var/lib/lxc/ /data/instances/
ln -s /data/instances /var/lib/lxc

define the defaults when creating instances

mv /etc/lxc/default.conf /etc/lxc/default.conf.dist
vi /etc/lxc/default.conf

this is v4

lxc.net.0.type = veth
lxc.net.0.flags = up
lxc.net.0.link = dummybr0
lxc.net.0.name = eth0

# internal bridge and self-defined MAC prefix, xx will expand
lxc.net.0.link = dummybr0
lxc.net.0.hwaddr = 00:00:00:xx:xx:xx

vi /etc/lxc/lxc.conf # new file

lxcpath = /data/instances

lxc-config -l

Create an instance

review available distributions

#lxc-create -t download -n dummy
#^C
#rm -rf /data/instances/dummy/

ehm… just review available template scripts instead

ls -lF /usr/share/lxc/templates/

fix the template scripts to be ready for current (got PAM and need moar pkgs)

cp -pi /usr/share/lxc/templates/lxc-slackware /usr/share/lxc/templates/lxc-slackware.dist
chmod -x /usr/share/lxc/templates/lxc-slackware.dist
vi /usr/share/lxc/templates/lxc-slackware

#echo "root:root" | chroot $rootfs chpasswd
#echo "Root default password is 'root', please change it!"
chroot $rootfs passwd --delete --unlock root

# REMOVE openssh as we do not necessarily want a full-blown system there
mlocate

diff -u /usr/share/lxc/templates/lxc-slackware.dist /usr/share/lxc/templates/lxc-slackware

now deploy your system of choice on the file-system

cd /data/instances/

export arch=x86_64
export release=current
export MIRROR=http://nephtys.lip6.fr/pub/linux/distributions/slackware/
cat /var/cache/lxc/slackware/slackpkg-conf/mirrors
echo $MIRROR > /var/cache/lxc/slackware/slackpkg-conf/mirrors

lxc-ls -f

instance=moodlenew
instance=meet
instance=slacklxc

rm -rf $instance/
# need to answer y about using current
time echo y | lxc-create -n $instance -t slackware 2>&1 > $instance.log && echo CREATED
# -f /etc/lxc/$instance.conf

# 1m53.229s on xc

cat /data/instances/$instance/config

eventually clean-up things and make the instance lighter

du -sh /data/instances/$instance/rootfs/
# vbatts + additions above = 258M
# the new script for v4 = 316M

ls -lhF /data/instances/$instance/rootfs/var/cache/lxc/slackware/cache-current-x86_64/slackware64/*/*.txz*
rm -rf /data/instances/$instance/rootfs/var/cache/lxc/slackware/cache-current-x86_64/

du -sh /data/instances/$instance/rootfs/
# now 214M
# now 261M

Network setup

full bridge

setup network on a full bridge on the Slackware host (yeah sorry for the bridge name, it does not matter, really)

    echo -n default bridge...
    brctl addbr xenbr0
    brctl addif xenbr0 eth0
    ifconfig eth0 up
    ifconfig xenbr0 HOST-IP-ADDRESS/24 up && echo done || echo FAIL

and configure the instance brutally, here some kind of failover IP

    echo $instance
    vi /data/instances/$instance/rootfs/etc/rc.d/rc.inet1

    #!/bin/bash

    echo rc.inet1 PATH is $PATH

    if [[ $1 = stop || $1 = down ]]; then
            route delete default
            ifconfig eth0 down
            ifconfig lo down
    else
            echo -n lo...
            ifconfig lo up && echo done || echo FAIL

    echo -n eth0...
    failover=INSTANCE-IP
    ifconfig eth0 $failover/32 up && echo done || echo FAIL
    #ifconfig eth0 $failover/32 pointopoint 62.210.0.1 up && echo done || echo FAIL
    unset failover

    echo -n custom route for non-subnet gateway...
    route add -host 62.210.0.1 dev eth0 && echo done || echo FAIL

    echo -n default route...
    route add default gw 62.210.0.1 && echo done || echo FAIL
    fi

    vi /data/instances/$instance/rootfs/etc/rc.d/rc.local # why the freak is it restarting rc.inet1?

–and/or– dummy bridge

setup network on a dummy bridge and SNAT on the Slackware host

vi /etc/rc.d/rc.inet1

echo -n dummy bridge...
brctl addbr dummybr0
ifconfig dummybr0 10.9.9.254/24 up && echo done

echo -n SNAT for 10.9.9.0/24...
    echo 1 > /proc/sys/net/ipv4/ip_forward
/usr/sbin/nft -f /etc/nftables.conf && echo done || echo FAIL

    vi /etc/nftables.conf

    flush ruleset

    table ip nat {
            chain postrouting {
                    type nat hook postrouting priority 100;
                    ip saddr 10.9.9.0/24 oif xenbr0 snat FACING-IP;
            }
    }

vi /etc/hosts

# LXC
10.9.9.1        slacklxc.nethence.com slacklxc
10.9.9.254      xc.nethence.com xc

vi /etc/postfix/main.cf

mynetworks = 127.0.0.1/32, 10.9.9.0/24

postfix reload

and setup network within the instance brutally

echo $instance
mv /data/instances/$instance/rootfs/etc/rc.d/rc.inet1 /data/instances/$instance/rootfs/etc/rc.d/rc.inet1.dist
chmod -x /data/instances/$instance/rootfs/etc/rc.d/rc.inet1.dist
vi /data/instances/$instance/rootfs/etc/rc.d/rc.inet1

    #!/bin/bash

    echo rc.inet1 PATH is $PATH

    if [[ $1 = stop || $1 = down ]]; then
            route delete default
            ifconfig eth0 down
            ifconfig lo down
    else
            echo -n lo...
            ifconfig lo up && echo done || echo FAIL

            echo -n eth0...
            ifconfig eth0 10.9.9.1/24 up && echo done || echo FAIL

            echo -n default route...
            route add default gw 10.9.9.254 && echo done || echo FAIL
    fi

    vi /data/instances/$instance/rootfs/etc/rc.d/rc.local

# why the freak was it restarting networking?
#/etc/rc.d/rc.inet1 restart

further instance setup

not sure why a debianish file appeared on a slackware system

ls -lF /data/instances/$instance/rootfs/etc/hostname
rm -f /data/instances/$instance/rootfs/etc/hostname

short name is enough

cat /data/instances/$instance/rootfs/etc/HOSTNAME
echo $instance > /data/instances/$instance/rootfs/etc/HOSTNAME

eventually define FQDNs here instead

mv /data/instances/$instance/rootfs/etc/hosts /data/instances/$instance/rootfs/etc/hosts.dist
vi /data/instances/$instance/rootfs/etc/hosts

127.0.0.1       localhost
10.9.9.1        slacklxc.nethence.com slacklxc
10.9.9.254      xc.nethence.com xc

–or–

127.0.0.1       localhost
INSTANCE-IP meet.nethence.com meet
62.210.0.1  gw

    vi /data/instances/$instance/rootfs/etc/resolv.conf

search nethence.com
nameserver 62.210.16.6
nameserver 62.210.16.7
#nameserver 208.67.222.222
#nameserver 208.67.220.220

further post-install in a CHROOT

vi /data/instances/$instance/rootfs/root/.bashrc

alias ll='ls -alhF --color=auto'

we did not add NVI hence Elvis is the only editor around

chroot /data/instances/$instance/rootfs/

which vi # no exist
ls -lF /usr/bin/vi
which elvis
ln -s elvis /usr/bin/vi

slackpkg’s mirror was defined at install time

grep -v ^# /etc/slackpkg/mirrors
slackpkg update gpg
slackpkg update

first shot of indexing

updatedb

exit the CHROOT

^D

and in case you need to change the MAC or something

vi /data/instances/$instance/config

# dedibox failover-ip with a manually defined MAC suffix
lxc.network.link = xenbr0
lxc.network.hwaddr = 00:16:3e:SUFFIX
lxc.start.auto = 1

The systemd situation

oh, you wanna run a systemd-capable instance on slackware?!

ls -ldF /sys/fs/cgroup/systemd # -> elogind/
rm /sys/fs/cgroup/systemd
mkdir -p /sys/fs/cgroup/systemd/

# mount -t cgroup -o none,name=systemd systemd /sys/fs/cgroup/systemd
vi /etc/fstab

systemd /sys/fs/cgroup/systemd cgroup rw,none,name=systemd 0 0

mount /sys/fs/cgroup/systemd/

here we go with buster to build a Jitsi Meet instance

instance=meetnew
export MIRROR=http://mirrors.online.net/debian/
export DOWNLOAD_KEYSERVER="keyring.debian.org"
lxc-create -n $instance -t debian -- template-options -r buster
#-t ubuntu -- template-options -r bionic

get rid of that unknown password the script defined

chroot /data/instances/$instance/rootfs/ passwd -d root

setup a few things brutally (this is recommended esp. as there’s no editor within the instance so far)

cat >> /data/instances/$instance/rootfs/etc/bash.bashrc <<-EOF
alias ll='ls -alhF --color=auto'
EOF

rmdir /data/instances/$instance/rootfs/etc/network/interfaces.d/
cat > /data/instances/$instance/rootfs/etc/network/interfaces <<EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 51.159.95.239/32
    post-up ip route add 62.210.0.1/32 dev eth0
    post-up ip route add default via 62.210.0.1
    dns-nameservers 62.210.16.6 62.210.16.7
    #dns-nameservers 208.67.222.222 208.67.220.220
    #dns-search example.local
EOF

and once the instance is up you may want to

apt update
apt full-upgrade
apt install inetutils-ping vim-tiny less
# iputils-ping

also there’s no need for ssh in the instance

apt purge openssh-server openssh-sftp-server openssh-client

Ready to go

start the instance on the foreground to see its console at startup. beware if you’re remote, when started in foreground, the instance crashes if you loose your ssh session. this is why it’s better run it inside gnu/screen or tmux

screen -S lxc

instance=INSTANCE-NAME

echo $instance
lxc-ls $instance --fancy
lxc-start $instance --foreground

and in another window, get to the login prompt

lxc-ls --fancy
lxc-attach $instance -- /bin/bash # TODO workdir

ps auxfww
ifconfig -a

TODO

Operations

system-wide

boot-time scripts take care of instances' startup and shutdown. enable an instance at boot-time

vi /data/instances/$instance/config

lxc.start.auto = 1

start

/etc/rc.d/rc.lxc stop

status

ps auxfww | grep lxc | grep -vE 'grep|tail'
ls -lF /data/instances/
    lxc-ls --fancy

stop

/etc/rc.d/rc.lxc stop

per-instance

start an instance

lxc-start $instance
# -f /etc/lxc/$instance.conf
# CONFIG=/etc/lxc/$instance.conf lxc-checkconfig
lxc-attach $instance

status an instance

lxc-ls --fancy -n $instance
lxc-info $instance

stop an instance

lxc-stop $instance
lxc-stop -n $instance -k

Upgrade to v4

lxc-update-config -c /etc/lxc/lxc.conf
lxc-update-config -c /etc/lxc/default.conf
lxc-update-config -c /data/instances/INSTANCE/INSTANCE.conf

TODO

Setup cgroups and namespaces

vi /etc/cgconfig.conf
vi /etc/cgred.conf

About lxc-start -F – are there other means of seeing the instance starting up?

How come the default route is already set in the instance?

default route...SIOCADDRT: File exists
FAIL

How come we see agetty tty1 tty2 running but no prompt anywhere?

Troubleshooting

on instance’s foreground

lxc-start: conf.c: remount_all_slave: 3126 Invalid argument - Failed to copy "/proc/self/mountinfo"
Failed to mount cgroup at /sys/fs/cgroup/systemd: Operation not permitted
[!!!!!!] Failed to mount API filesystems, freezing.
Freezing execution.

==> that only matters if you need to run a systemd-capable instance.

when trying lxc-stop from the host against an instance you get

lxc-stop: commands_utils.c: lxc_cmd_sock_rcv_state: 75 Failed to receive message: Resource temporarily unavailable

when trying poweroff or halt -p in the instance you get

System has not been booted with systemd as init system (PID 1). Can't operate.

==> did you notice there’s something missing when checking the state of the art on the host?

lxc-checkconfig

Cgroup v1 systemd controller: missing

this is probably sure why systemd does not work within the instance – TODO – I didnt found how to fix this yet - proceeding w/o it and be happy with -k

on instance’s foreground

lxc-start: conf.c: remount_all_slave: 3126 Invalid argument - Failed to copy "/proc/self/mountinfo"

==> TODO

Left-overs

not sure where to use those (default.conf vs lxc.conf), it only worked as shell exports

# Ubuntu mirror for FRANCE/SCW
#lxc.environment = MIRROR=http://mirrors.online.net/ubuntu/
#lxc.environment = DOWNLOAD_KEYSERVER="keyserver.ubuntu.com"

# Debian mirror for FRANCE
#lxc.environment = MIRROR=http://mirrors.online.net/debian/
#lxc.environment = DOWNLOAD_KEYSERVER="keyring.debian.org"

# Devuan
#lxc.environment = MIRROR=https://pkgmaster.devuan.org/devuan/
#lxc.environment = DOWNLOAD_KEYSERVER=...?

# Slackware mirror for FRANCE
#lxc.environment = MIRROR=http://nephtys.lip6.fr/pub/linux/distributions/slackware/

Resources

https://docs.slackware.com/howtos:misc:lxc

https://www.linuxquestions.org/questions/slackware-14/starting-lxc-container-in-slackware-14-2-a-4175614421/

https://linuxcontainers.org/lxc/getting-started/

https://keyring.debian.org/ https://pkgmaster.devuan.org/devuan/dists/

instance

http://www.panticz.de/LXC-create-Ubuntu-Bionic-container

tpl

https://discuss.linuxcontainers.org/t/what-are-the-ways-to-create-an-lxc-container/1746

https://unix.stackexchange.com/questions/407315/creating-a-custom-template-based-on-some-existing-lxc-template-after-running-th

https://cwiki.apache.org/confluence/display/CLOUDSTACK/LXC+Template+creation

https://wiki.gentoo.org/wiki/LXC

network

https://wiki.debian.org/LXC/SimpleBridge

https://lxd.readthedocs.io/en/latest/networks/

https://stackoverflow.com/questions/25042542/how-do-i-connect-a-lxc-container-to-an-ip-alias

http://tmartin.fr/articles/2015/ip-aliasing-for-lxc-containers/

https://serverfault.com/questions/802604/using-aliased-bond-interface-on-host-by-an-lxc-container

https://stackoverflow.com/questions/30848911/lxc-is-there-a-way-to-setup-nameserver-on-container-config

unpriv

LXC 1.0: Blog post series [0/10] https://stgraber.org/2013/12/20/lxc-1-0-blog-post-series/

LXC 1.0: Unprivileged containers [7/10] https://stgraber.org/2014/01/17/lxc-1-0-unprivileged-containers/

Configuring Unprivileged LXC containers in Debian Jessie https://blog.cadena-it.com/virtual-cloud/configuring-unprivileged-lxc-containers-in-debian-jessie/

Unprivileged containers in Slackware© https://www.chriswilling.com/lxc/setup-unpriv-slackware.html

moar

https://blog.simos.info/using-command-aliases-in-lxd-to-exec-a-shell/

https://discuss.linuxcontainers.org/t/dns-resolution-in-lxc-container/4662

https://linuxcontainers.org/lxc/manpages/man5/lxc.container.conf.5.html

https://github.com/lxc/lxc-templates

troubles

Bug 1802090 - Systemd: Couldn’t move remaining userspace processes, ignoring: Input/output error https://bugzilla.redhat.com/show_bug.cgi?id=1802090

Warning “Couldn’t move remaining userspace processes, ignoring: Input/output error” #14788 https://github.com/systemd/systemd/issues/14788

“Couldn’t move remaining userspace processes, ignoring: Input/output error” message on dmesg/journalctl on boot since Linux 5.5 upgrade #14682 https://github.com/systemd/systemd/issues/14682

LXC ubuntu container fails to start https://forum.turris.cz/t/lxc-ubuntu-container-fails-to-start/9805

Fails to work with cgroupv2 / unified hierarchy #3183 https://github.com/lxc/lxc/issues/3183

systemd

https://lxc-users.linuxcontainers.narkive.com/OGf4EeGC/unprivileged-container-with-systemd

https://gitlab.alpinelinux.org/alpine/aports/-/issues/7342

https://github.com/debops/ansible-lxc/issues/15

https://forum.turris.cz/t/lxc-ubuntu-container-fails-to-start/9805

Alpine Linux and Systemd Containers (Round 2) https://web.archive.org/web/20190524003509/https://j2h2.com/entry/alpine-linux-and-systemd-containers-round-2

upgrade to v4 — config syntax

LXC version 2 migration to version 3 issue : Failed to load config https://discuss.linuxcontainers.org/t/lxc-version-2-migration-to-version-3-issue-failed-to-load-config/3590

Parse.c errors after full system update of archlinux- failed to parse config https://discuss.linuxcontainers.org/t/parse-c-errors-after-full-system-update-of-archlinux-failed-to-parse-config/1664

Many syslog entries for some, but not all containers: Failed to load config for xxxx #4624 https://github.com/lxc/lxd/issues/4624

LXC config error after update https://www.akeyes.co.uk/blog/lxc_config_error_after_update

Upgrade from lxc2 to lxc3 https://eleni.blog/2018/12/25/upgrade-from-lxc2-to-lxc3/

cannot start

Container won’t start - lxc_rootfs_init - Bad file descriptor https://discuss.linuxcontainers.org/t/container-wont-start-lxc-rootfs-init-bad-file-descriptor/11024

Containers do not launch on Linux 5.12 https://discuss.linuxcontainers.org/t/containers-do-not-launch-on-linux-5-12/10995

lxc info –show-log local:wekan https://haste.rys.pw/raw/imulimizex

Newuidmap failed to write mapping “newuidmap: uid range [1000-1001) -> [1000-1001) not allowed” https://www.reddit.com/r/archlinux/comments/pl8hfn/newuidmap_failed_to_write_mapping_newuidmap_uid/

Unprivileged container failed to mount rootfs and start when cloning https://www.reddit.com/r/archlinux/comments/pgfv38/unprivileged_container_failed_to_mount_rootfs_and/

FS#70736 - LXD breaks on kernel 5.12 https://bugs.archlinux.org/task/70736

conf: handle kernels with CAP_SETFCAP #3827 https://github.com/lxc/lxc/pull/3827

Arch lxc start failed #7469 https://github.com/lxc/lxd/issues/7469

“File exists” error while starting container https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/1891903

Failed To Initialize Cpuset Cpus Issue 9114 Lxc Lxd Github https://news.susukambingetawagomars.com/

cannot start a container if has a device disk added from another blockdevice mount point https://www.gitmemory.com/issue/lxc/lxd/8713/825983764

Cannot start LXD container within LXD container https://discuss.linuxcontainers.org/t/cannot-start-lxd-container-within-lxd-container/10182

lxc https://w.atwiki.jp/hiroyuki12/pages/129.html

more issues

Can’t get LCX bridge to work https://serverfault.com/questions/1067244/cant-get-lcx-bridge-to-work

Unprvileged container: lxc-start not working if cpu-related cgroups are set #1205 https://github.com/lxc/lxc/issues/1205


GUIDES | LECTURES | BENCHMARKS | SMTP HEALTH