Introduction
In this article, we will learn the basics of lxc containerization technology and launch our first lxc container on a Centos 8 machine.
What is lxc?
LXC (Linux Containers) is an OS-level virtualization technology that allows the creation and running of multiple isolated Linux virtual environments (VE) on a single control host. These isolation levels or containers can be used to either sandbox specific applications, or to emulate an entirely new host.
Now let's gor through the steps of installing lxc on our Centos 8 machine.
Step 1: Enable the EPEL repo
[root@sa-lxc ~]# yum install epel-release
Last metadata expiration check: 0:32:41 ago on Sat 26 Sep 2020 07:40:13 PM IST.
Dependencies resolved.
==========================================================================
Package Arch Version Repository Size
==========================================================================
Installing:
epel-release noarch 8-8.el8 extras 23 k
Transaction Summary
==========================================================================
Install 1 Package
Total download size: 23 k
Installed size: 32 k
Is this ok [y/N]: y
Downloading Packages:
epel-release-8-8.el8.noarch.rpm 19 kB/s | 23 kB 00:01
-----------------------------------------------------------------------------------------------------------------------
Total 9.3 kB/s | 23 kB 00:02
warning: /var/cache/dnf/extras-2770d521ba03e231/packages/epel-release-8-8.el8.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS-8 - Extras 1.3 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Is this ok [y/N]: y
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : epel-release-8-8.el8.noarch 1/1
Running scriptlet: epel-release-8-8.el8.noarch 1/1
Verifying : epel-release-8-8.el8.noarch 1/1
Installed:
epel-release-8-8.el8.noarch
Complete!
Step 2: Enable and increase user namespaces
To do so, we will need to modify the grub bootloader options and this will also entail a system reboot.
[root@sa-lxc ~]# grubby --args="namespace.unpriv_enable=1" --update-kernel="$(grubby --default-kernel)"
[root@sa-lxc ~]# echo "user.max_user_namespaces=2277484249" >> /etc/sysctl.d/99-userns.conf
Now reboot the system.
Step 3: Install snappy
The latest version of lxc is made available via the Snappy package manager. Snappy is a modern, cross-distribution, transactional package manager designed for working with self-contained, immutable packages. In order to install lxc we need to have the snappy package manager installed on the system and the corresponding services to be running.
[root@sa-lxc ~]# yum install snapd -y
Extra Packages for Enterprise Linux Modular 8 - x86_64 34 kB/s | 132 kB 00:03
Extra Packages for Enterprise Linux 8 - x86_64 2.0 MB/s | 8.0 MB 00:03
Dependencies resolved.
==========================================================================
Package Arch Version Repository Size
=========================================================================
Installing:
snapd x86_64 2.45.3.1-1.el8 epel 18 M
Upgrading:
libselinux x86_64 2.9-3.el8 BaseOS 166 k
libselinux-utils x86_64 2.9-3.el8 BaseOS 244 k
libsemanage x86_64 2.9-2.el8 BaseOS 165 k
libsepol x86_64 2.9-1.el8 BaseOS 340 k
policycoreutils x86_64 2.9-9.el8 BaseOS 377 k
policycoreutils-python-utils noarch 2.9-9.el8 BaseOS 251 k
python3-libselinux x86_64 2.9-3.el8 BaseOS 283 k
python3-libsemanage x86_64 2.9-2.el8 BaseOS 127 k
python3-policycoreutils noarch 2.9-9.el8 BaseOS 2.2 M
selinux-policy noarch 3.14.3-41.el8_2.6 BaseOS 615 k
selinux-policy-targeted noarch 3.14.3-41.el8_2.6 BaseOS 15 M
Installing dependencies:
snap-confine x86_64 2.45.3.1-1.el8 epel 3.3 M
snapd-selinux noarch 2.45.3.1-1.el8 epel 326 k
Transaction Summary
==========================================================================
Install 3 Packages
Upgrade 11 Packages
Total download size: 42 M
Downloading Packages:
(1/14): snapd-selinux-2.45.3.1-1.el8.noarch.rpm 231 kB/s | 326 kB 00:01
(2/14): snap-confine-2.45.3.1-1.el8.x86_64.rpm 2.1 MB/s | 3.3 MB 00:01
(3/14): snapd-2.45.3.1-1.el8.x86_64.rpm 9.6 MB/s | 18 MB 00:01
(4/14): libselinux-utils-2.9-3.el8.x86_64.rpm 549 kB/s | 244 kB 00:00
(5/14): libselinux-2.9-3.el8.x86_64.rpm 247 kB/s | 166 kB 00:00
(6/14): libsemanage-2.9-2.el8.x86_64.rpm 442 kB/s | 165 kB 00:00
(7/14): libsepol-2.9-1.el8.x86_64.rpm 1.1 MB/s | 340 kB 00:00
(8/14): policycoreutils-2.9-9.el8.x86_64.rpm 1.4 MB/s | 377 kB 00:00
(9/14): policycoreutils-python-utils-2.9-9.el8.noarch.rpm 1.9 MB/s | 251 kB 00:00
(10/14): python3-libsemanage-2.9-2.el8.x86_64.rpm 1.7 MB/s | 127 kB 00:00
(11/14): python3-libselinux-2.9-3.el8.x86_64.rpm 1.8 MB/s | 283 kB 00:00
(12/14): selinux-policy-3.14.3-41.el8_2.6.noarch.rpm 3.0 MB/s | 615 kB 00:00
(13/14): python3-policycoreutils-2.9-9.el8.noarch.rpm 8.1 MB/s | 2.2 MB 00:00
(14/14): selinux-policy-targeted-3.14.3-41.el8_2.6.noarch.rpm 17 MB/s | 15 MB 00:00
-----------------------------------------------------------------------------------------------------------------------
Total 7.2 MB/s | 42 MB 00:05
warning: /var/cache/dnf/epel-6519ee669354a484/packages/snap-confine-2.45.3.1-1.el8.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID 2f86d6a1: NOKEY
Extra Packages for Enterprise Linux 8 - x86_64 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x2F86D6A1:
Userid : "Fedora EPEL (8) <epel@fedoraproject.org>"
Fingerprint: 94E2 79EB 8D8F 25B2 1810 ADF1 21EA 45AB 2F86 D6A1
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Running scriptlet: libsepol-2.9-1.el8.x86_64 1/1
Upgrading : libsepol-2.9-1.el8.x86_64 1/25
Running scriptlet: libsepol-2.9-1.el8.x86_64 1/25
Upgrading : libselinux-2.9-3.el8.x86_64 2/25
Running scriptlet: libselinux-2.9-3.el8.x86_64 2/25
Upgrading : libselinux-utils-2.9-3.el8.x86_64 3/25
Upgrading : libsemanage-2.9-2.el8.x86_64 4/25
Upgrading : policycoreutils-2.9-9.el8.x86_64 5/25
Running scriptlet: policycoreutils-2.9-9.el8.x86_64 5/25
Upgrading : python3-libselinux-2.9-3.el8.x86_64 6/25
Upgrading : python3-libsemanage-2.9-2.el8.x86_64 7/25
Upgrading : python3-policycoreutils-2.9-9.el8.noarch 8/25
Upgrading : policycoreutils-python-utils-2.9-9.el8.noarch 9/25
Upgrading : selinux-policy-3.14.3-41.el8_2.6.noarch 10/25
Running scriptlet: selinux-policy-3.14.3-41.el8_2.6.noarch 10/25
Running scriptlet: selinux-policy-targeted-3.14.3-41.el8_2.6.noarch 11/25
Upgrading : selinux-policy-targeted-3.14.3-41.el8_2.6.noarch 11/25
Running scriptlet: selinux-policy-targeted-3.14.3-41.el8_2.6.noarch 11/25
Running scriptlet: snapd-selinux-2.45.3.1-1.el8.noarch 12/25
Installing : snapd-selinux-2.45.3.1-1.el8.noarch 12/25
Running scriptlet: snapd-selinux-2.45.3.1-1.el8.noarch 12/25
Installing : snap-confine-2.45.3.1-1.el8.x86_64 13/25
Installing : snapd-2.45.3.1-1.el8.x86_64 14/25
Running scriptlet: snapd-2.45.3.1-1.el8.x86_64 14/25
Cleanup : selinux-policy-targeted-3.14.1-61.el8.noarch 15/25
Running scriptlet: selinux-policy-targeted-3.14.1-61.el8.noarch 15/25
Cleanup : selinux-policy-3.14.1-61.el8.noarch 16/25
Running scriptlet: selinux-policy-3.14.1-61.el8.noarch 16/25
Cleanup : policycoreutils-python-utils-2.8-16.1.el8.noarch 17/25
Cleanup : python3-policycoreutils-2.8-16.1.el8.noarch 18/25
Running scriptlet: policycoreutils-2.8-16.1.el8.x86_64 19/25
Cleanup : policycoreutils-2.8-16.1.el8.x86_64 19/25
Cleanup : python3-libsemanage-2.8-5.el8.x86_64 20/25
Cleanup : libsemanage-2.8-5.el8.x86_64 21/25
Cleanup : python3-libselinux-2.8-6.el8.x86_64 22/25
Cleanup : libselinux-utils-2.8-6.el8.x86_64 23/25
Cleanup : libselinux-2.8-6.el8.x86_64 24/25
Cleanup : libsepol-2.8-2.el8.x86_64 25/25
Running scriptlet: libsepol-2.8-2.el8.x86_64 25/25
Running scriptlet: snapd-selinux-2.45.3.1-1.el8.noarch 25/25
Running scriptlet: libsepol-2.8-2.el8.x86_64 25/25
Verifying : snap-confine-2.45.3.1-1.el8.x86_64 1/25
Verifying : snapd-2.45.3.1-1.el8.x86_64 2/25
Verifying : snapd-selinux-2.45.3.1-1.el8.noarch 3/25
Verifying : libselinux-2.9-3.el8.x86_64 4/25
Verifying : libselinux-2.8-6.el8.x86_64 5/25
Verifying : libselinux-utils-2.9-3.el8.x86_64 6/25
Verifying : libselinux-utils-2.8-6.el8.x86_64 7/25
Verifying : libsemanage-2.9-2.el8.x86_64 8/25
Verifying : libsemanage-2.8-5.el8.x86_64 9/25
Verifying : libsepol-2.9-1.el8.x86_64 10/25
Verifying : libsepol-2.8-2.el8.x86_64 11/25
Verifying : policycoreutils-2.9-9.el8.x86_64 12/25
Verifying : policycoreutils-2.8-16.1.el8.x86_64 13/25
Verifying : policycoreutils-python-utils-2.9-9.el8.noarch 14/25
Verifying : policycoreutils-python-utils-2.8-16.1.el8.noarch 15/25
Verifying : python3-libselinux-2.9-3.el8.x86_64 16/25
Verifying : python3-libselinux-2.8-6.el8.x86_64 17/25
Verifying : python3-libsemanage-2.9-2.el8.x86_64 18/25
Verifying : python3-libsemanage-2.8-5.el8.x86_64 19/25
Verifying : python3-policycoreutils-2.9-9.el8.noarch 20/25
Verifying : python3-policycoreutils-2.8-16.1.el8.noarch 21/25
Verifying : selinux-policy-3.14.3-41.el8_2.6.noarch 22/25
Verifying : selinux-policy-3.14.1-61.el8.noarch 23/25
Verifying : selinux-policy-targeted-3.14.3-41.el8_2.6.noarch 24/25
Verifying : selinux-policy-targeted-3.14.1-61.el8.noarch 25/25
Upgraded:
libselinux-2.9-3.el8.x86_64 libselinux-utils-2.9-3.el8.x86_64
libsemanage-2.9-2.el8.x86_64 libsepol-2.9-1.el8.x86_64
policycoreutils-2.9-9.el8.x86_64 policycoreutils-python-utils-2.9-9.el8.noarch
python3-libselinux-2.9-3.el8.x86_64 python3-libsemanage-2.9-2.el8.x86_64
python3-policycoreutils-2.9-9.el8.noarch selinux-policy-3.14.3-41.el8_2.6.noarch
selinux-policy-targeted-3.14.3-41.el8_2.6.noarch
Installed:
snapd-2.45.3.1-1.el8.x86_64 snap-confine-2.45.3.1-1.el8.x86_64 snapd-selinux-2.45.3.1-1.el8.noarch
Complete!
Step 4: Enable and start snappy
[root@sa-lxc ~]# ln -s /var/lib/snapd/snap /snap
[root@sa-lxc ~]# systemctl enable --now snapd.socket
Created symlink /etc/systemd/system/sockets.target.wants/snapd.socket → /usr/lib/systemd/system/snapd.socket.
[root@sa-lxc ~]# systemctl enable snapd.service
Created symlink /etc/systemd/system/multi-user.target.wants/snapd.service → /usr/lib/systemd/system/snapd.service.
[root@sa-lxc ~]# systemctl start snapd.service
Step 5: Install lxc
[root@sa-lxc ~]# snap install lxd
lxd 4.6 from Canonical✓ installed
Step 6: Configure lxc
To configure lxc we need to type the lxd init command and answer a couple of prompts as shown below.
[root@sa-lxc ~]# lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]: mylxc
Name of the storage backend to use (lvm, ceph, btrfs, dir) [default=btrfs]: lvm
Create a new LVM pool? (yes/no) [default=yes]: yes
Would you like to use an existing empty disk or partition? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=5GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none
Would you like LXD to be available over the network? (yes/no) [default=no]: yes
Address to bind LXD to (not including port) [default=all]:
Port to bind LXD to [default=8443]:
Trust password for new clients:
Again:
No password set, client certificates will have to be manually trusted. Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
Step 7: Launch a container
Once lxd has been initialized we can go ahead and launch our first container using the lxc launch command.
[root@sa-lxc ~]# lxc launch ubuntu:18.04
Creating the instance
Instance name is: caring-dane
Starting caring-dane
To view currently running containers use the lxc list command.
[root@sa-lxc ~]# lxc list
+-------------+---------+-----------------------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------------+---------+-----------------------+------+-----------+-----------+
| caring-dane | RUNNING | 10.14.41.189 (eth0) | | CONTAINER | 0 |
+-------------+---------+-----------------------+------+-----------+-----------+
[root@sa-lxc ~]#
Note: Since this was just a lab setup, I had stopped the firewalld service on my Centos system. In a production setup, be sure to add the appropriate firewall rules to allow the setup to work.
Conclusion
We hope that this article has been helpful to you and we look forward to your suggestions and feedback.