Setting-up LXC on Slackware Linux

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 cgroups and namespaces

TODO

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

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

vi /etc/lxc/default.conf

#lxc.network.type = empty
lxc.network.type = veth
lxc.network.flags = up
lxc.network.name = eth0

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

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

#lxcpath = /var/lib/lxc
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

# slocate was not there anyway - no need to remove it
# REMOVE openssh as we do not necessarily want a full-blown system there

hostname
pam
libtirpc
elogind
mlocate
less

note libtirpc missing for sshd and elogind for ps

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

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

eventually clean-up things and make the instance lighter

du -sh /data/instances/$instance/rootfs/
# vbatts + additions above = 258M

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

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

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 62.210.110.7;
            }
    }

vi /etc/hosts

10.9.9.1        moodle.nethence.com moodle
10.9.9.254      xc.os3.su xc

vi /etc/postfix/main.cf

mynetworks = ...

postfix reload

and configure the instance brutally

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...
            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 is it restarting rc.inet1?

further instance setup

not sure why hostname appeared on a slackware system. short name is enough

ls -lF /data/instances/$instance/rootfs/etc/HOSTNAME
ls -lF /data/instances/$instance/rootfs/etc/hostname
cat /data/instances/$instance/rootfs/etc/HOSTNAME
cat /data/instances/$instance/rootfs/etc/hostname
echo $instance > /data/instances/$instance/rootfs/etc/HOSTNAME
echo $instance > /data/instances/$instance/rootfs/etc/hostname

FQDN gets defined here instead

vi /data/instances/$instance/rootfs/etc/hosts

127.0.0.1       localhost
10.9.9.1        moodle.nethence.com moodle
10.9.9.254      xc.os3.su 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

nameserver 62.210.16.6
nameserver 62.210.16.7
#nameserver 208.67.222.222
#nameserver 208.67.220.220

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

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

further post-install in a CHROOT

draft

chroot /data/instances/$instance/rootfs/

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

which vi # noexist
which elvis
ln -s elvis /usr/bin/vi

slackpkg’s mirror was defined at install time

grep -v ^# /etc/slackpkg/mirrors
echo y | 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 when started in foreground, the instance crashes if you loose your ssh session. this is why we prefer to run it inside gnu/screen or tmux

screen -S lxc

instance=INSTANCE-NAME

echo $instance
lxc-start $instance -F

and in another window, get to the login prompt

lxc-ls -f
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

TODO

not sure the MIRROR stuff goes into default.conf or lxc.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.

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

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, it only worked as shell exports instead

# 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

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


GUIDES | LECTURES | BENCHMARKS | SMTP HEALTH