I just finished setting up LXD on my Ubuntu 19.04 server, and I'm ready to create a container.
Installing the service into the container is a separate step - this is just setting up and configuring the container itself.
Creating a disposable container:
Actually, we did this already with our test container:
me@host:~$ lxc launch -p lanprofile ubuntu:disco test
Let's see if that container is still there:
me@host:~$ lxc list +----------------+---------+---------------------+-----------------------------------------------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +----------------+---------+---------------------+-----------------------------------------------+------------+-----------+ | test | RUNNING | 192.168.1.124 (eth0)| 2615:a000:141f:e267:215:3eef:fe2a:c55d (eth0) | PERSISTENT | 0 | +----------------+---------+---------------------+-----------------------------------------------+------------+-----------+
We can enter the container to run commands on it's shell. Note that root inside the container is not root (unprivileged) on the host. The container comes with a default "ubuntu" user, but we have root so we don't seem to need the user.
me@host:~$ lxc shell test mesg: ttyname failed: No such device // Ignore this message root@test:~# // Look, a root prompt within the container! root@test:~# exit logout me@host:~$ // Back to the host
We can stop and then restart containers. No sudo needed, these are unprivileged containers:
me@host:~$ lxc stop test me@host:~$ lxc stop test
And when we are done we can destroy the container:
me@host:~$ lxc stop test me@host:~$ lxc destroy test
Creating a long-term container:
Now I want to create a container for a long-term service. Now we add security: This means adding non-root users, independent ssh access, and package upgrades. This container can function like a lightweight VM, though with rather less overhead.
me@host:~$ lxc launch -p lanprofile ubuntu:disco test_2
We can login to our LAN router, and see the test_2 device on the network. This is a good opportunity to assign it a consistent IP address, so you can always find the container again. Stop and restart the container so it picks up the new IP address.
Let's create a user for me with ssh access
me@host:~$ lxc shell test_2 mesg: ttyname failed: No such device // Ignore this message root@test_2:~# adduser me // Includes creating a password root@test_2:~# adduser me sudo // Add me to the "sudo" group for easy remote administration via ssh root@test_2:~# nano /etc/ssh/sshd_config PasswordAuthentication yes // Temporary while we set up ssh keys root@test_2:~# systemctl restart sshd root@test_2:~# exit
Copy my key. Remember to do this from ALL systems you are going to SSH into this container from:
me@desktop:~$ ssh-copy-id me@192.168.1.124
Now I can ssh directly into the container using keys, so let's end password login.
me@test_2:~$ sudo nano /etc/ssh/sshd_config PermitRootLogin no PasswordAuthentication no me@test_2:~$ sudo systemctl restart sshd
Remove the default "ubuntu" user, since we won't be using it.
me@test_2:~$ sudo deluser ubuntu me@test_2:~$ sudo rm -r /home/ubuntu
Moving on to package management, simplify the apt sources so only -main and -universe are seen in -updates and -security. We only need what the installed service requires.
me@test_2:~$ sudo nano /etc/apt/sources.list deb http://archive.ubuntu.com/ubuntu disco main universe deb http://archive.ubuntu.com/ubuntu disco-updates main universe deb http://security.ubuntu.com/ubuntu disco-security main universe me@test_2:~$ sudo apt update // Since the sources have changed me@test_2:~$ sudo apt upgrade // Now is a good time
Finally, let's install unattended-upgrades and configure it to upgrade ALL packages from our limited apt sources. This means we are less likely to discover months of unapplied upgrades and security fixes. This is optional, merely my preference:
me@test_2:~$ sudo apt install unattended-upgrades me@test_2:~$ sudo nano /etc/apt/apt.conf.d/50unattended-upgrades // Uncomment the following two lines: "${distro_id}:${distro_codename}-security"; "${distro_id}:${distro_codename}-updates";
And there we have it - a long-term container that is easily (but securely) accessed via ssh for maintenance and automatically pulls package updates. Lightweight VM-like behavior with a consistent IP address. Note that "lxc shell" on the host will still give a root prompt, but recall that the purpose of a container is to keep the service from getting out, not to keep host from getting in. Also note that, due to macvlan networking, the container cannot communicate across the networkk with the host.
No comments:
Post a Comment