Work for this post was partly triggered by something I saw at work and partly because of a lightning talk I saw on Monday. There was a remark by a friend that even though we love and want to run latest and greatest supported versions, we cannot always upgrade in time. And as such, sometimes we end-up with unsupported OS versions for a significant time. Not unlike the law of welded systems.
But it got me thinking. Assuming, for example, that you have a number of Xenial systems that due to library dependencies you cannot upgrade, is there a middle ground that might be acceptable for a while until you push forward? Using a Xenial docker container and treating it as a lightweight VM somehow, could be a solution. But what if you need to run docker containers too? Maybe you need something more elaborate.
I fired up a VM running Ubuntu Focal and decided to figure out how to run a systemd-nspawn Xenial container.
Create the machine:
# debootstrap --arch=amd64 xenial /var/lib/machines/xenial1
Start the machine
# systemd-nspawn -D /var/lib/machines/xenial1 root@xenial1 # rm /etc/securetty root@xenial1 # passwd root root@xenial1 # apt-get update root@xenial1 # apt-get install dbus resolvconf root@xenial1 # systemctl enable systemd-resolved root@xenial1 # cat > /etc/resolvconf/resolv.conf.d/base nameserver 127.0.0.53 options edns0 trust-ad search home ctrl-D root@xenial1 #
Yes, I know that it is best to fix
securetty instead of removing it, but this is a PoC on my VM. You can now proceed to configure systemd to run the container:
# /etc/systemd/system/xenial1.service [Unit] Description=Xenial1 Container [Service] LimitNOFILE=100000 ExecStart=/usr/bin/systemd-nspawn --machine=xenial1 --directory=/var/lib/machines/xenial1/ --bind /var/run/docker.sock:/var/run/docker.sock --bind /mnt2:/mnt2 -b Restart=always [Install] Also=dbus.service
In your host system you can now:
root@focal # systemctl daemon-reload root@focal # systemctl start xenial1
You can of course log into the machine with
machinectl login xenial1. Notice above that the nspawn container mounts the docker socket, since we assume that you have docker installed in the Focal host and that you want to "run" docker containers from within the Xenial machine.
We only need to install the docker client in the Xenial container and as such:
root@xenial1 # cat > /etc/apt/sources.list.d/docker.list deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu xenial stable ctrl-D root@xenial1 # apt-get update root@xenial1 # apt-get install docker-ce-cli=5:18.09.7~3-0~ubuntu-xenial
Now you’re all set. The docker client inside Xenial, starts whatever container you want in Focal and does whatever you like.
Suppose that you want a non-root user like
ubuntu in the Xenial machine to be able to run docker commands; what do you do? You add the
/etc/group line for the
docker group from Focal in Xenial and in Xenial you simply
useradd -aG docker ubuntu.
ubuntu@xenial1 > docker run -d -p 8080:8080 bitnami/nginx : ubuntu@focal > curl http://127.0.0.1:8080/ : If you see this page, the nginx web server is successfully installed and working. Further configuration is required. :