Run Linux containers with LXC/LXD on CentOS 8
You can download this article in PDF format via the link below to support us.Download the guide in PDF formatClose
“It’s not the blessings we call, but how we use them is the true measure of Thanksgiving.” -WT Purkiser
Demystifying LXC
The Linux Container Project (LXC) is an open source container platform that provides a set of tools, templates, libraries and language bindings. The container it provides includes a complete Linux system, like a VM, with its own file system, network, and multiple applications. LXC has a simple command-line interface that improves the user experience when starting a container (RedHat, 2020). Through powerful APIs and simple tools, it enables Linux users to easily create and manage systems or application containers. Before containerization, Docker was built on top of LXC, but since then they have moved to containerization.
Features of LXC
The current LXC uses the following kernel functions to contain processes: Source: LinuxContainers
- Kernel namespace (ipc, uts, mount, pid, network and user)
- Apparmor and SELinux configuration files
- Seccomp policy
- chroots (use pivot_root)
- Kernel function
- CGroups (control group)
Demystifying LXD
LXD is the next generation system container manager. It is an amazing interface for managing LXC system containers, and it should not be misunderstood as a platform or container type. The functions of LXD include snapshot and image control. As you can guess, LXD enhances the capabilities of LXC technology. It provides a user experience similar to a virtual machine, but uses Linux containers.
The function source of LXD: LinuxContainers
Some of the biggest features of LXD are:
- Ensure security through design (unprivileged containers, resource restrictions, etc.)
- Scalable (from containers on laptops to thousands of compute nodes)
- Intuitive (simple, clear API and clear command line experience)
- Image-based (various Linux distributions are released every day)
- Support cross-host container and image transmission (including real-time migration using CRIU)
- Advanced resource control (CPU, memory, network I/O, block I/O, disk usage and kernel resources)
- Device pass-through (USB, GPU, Unix character and block devices, NIC, disk and path)
- Network management (network bridge creation and configuration, cross-host tunneling, etc.)
- Storage management (supports multiple storage backends, storage pools and storage volumes)
Install LXC/LXD on CentOS 8
If you want to try LXC/LXD on CentOS 8 server to run certain applications, the following steps will help you get the platform ready for use as soon as possible.
Step 1: Update and prepare the server
This is a very critical step. We ensure that our house is well furnished by ensuring that the latest patches and software packages are installed. Continue to run the following commands to prepare the server.
sudo dnf update -y && sudo dnf upgrade -y
sudo dnf install -y vim curl nano
Disable SELinux
If you are good at managing SELinux context, then this is an optional step.To make it lenient, run the following command
sudo setenforce 0
sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
Step 2: Enable and configure EPEL repository
Run the following commands to install and enable EPEL repo on CentOS 8, then update the server to get the latest packages from Epel.
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
sudo dnf update
Step 3: Install the snapshot on CentOS 8
In this setup, we will install Snappy’s LXD package because it has the simplicity and support of the Snap package. Therefore, we need to install snapd on the server as follows:
sudo yum install snapd -y
After installation, you need to enable the systemd unit for managing the main snapshot communication socket:
sudo systemctl enable --now snapd.socket
To enable classic snapshot support, enter the following to create a symbolic link between /var/lib/snapd/snap and /snap:
sudo ln -s /var/lib/snapd/snap /snap
Log out and log in again, or restart the system to ensure that the snapshot path is updated correctly. Once the snapshot is installed, let’s move on to the next step.
Step 4: Add kernel parameters
LXD requires some important kernel options, which we will enable on the server. Configure them by running the following commands on the terminal: root.
$ sudo su -
# grubby --args="user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)"
# grubby --args="namespace.unpriv_enable=1" --update-kernel="$(grubby --default-kernel)"
# echo "user.max_user_namespaces=3883" | sudo tee -a /etc/sysctl.d/99-userns.conf
After configuring these settings, the server needs to be rebooted because the core core functionality has changed. Restart the server.
sudo reboot
Step 5: Install lxd snap on CentOS 8
Finally, after the server is backed up, it’s time to retrieve the LXD package of interest from the Snap storage. It’s as simple as making a Snap, we just need to run the following command, and our LXD will be installed.
$ sudo snap install --classic lxd
Step 6: Start the test LXD container
So far, we have installed LXC/LXD, but there is no container that can hold the application we are interested in. Therefore, before starting some containers, let’s add the user account to the group lxd so that it can manage the LXD container without permission restrictions.
sudo usermod -aG lxd <your-username>
newgrp lxd
note: of newgrp The command is used to change the current group ID during the login session. If the optional-flag is given, the user’s environment will be reinitialized as if the user has logged in, otherwise the current environment (including the current working directory) remains unchanged. newgrp changes the current real group ID to a named group.
Next, we configure or “initialize” the LXD environment by running the following commands. It will take you to solve several problems. Please answer according to your environmental needs. I use the default value for the blank value.
$ 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]: Name of the storage backend to use (btrfs, dir, lvm, ceph) [default=btrfs]: lvm Create a new LVM pool? (yes/no) [default=yes]: Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]: Size in GB of the new loop device (1GB minimum) [default=9GB]: 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]: Would you like LXD to be available over the network? (yes/no) [default=no]: 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]:
The above command will create a bridge lxdbr0. We add this bridge interface to the trusted zone so that the connection can pass.In other words, we will allow all incoming traffic to pass lxdbr0.Execute the following firewall commands
sudo firewall-cmd --add-interface=lxdbr0 --zone=trusted --permanent
sudo firewall-cmd --reload
Create a container
After lxd is initialized, your user will be granted permission to start and manage containers with the following permissions: x Command, let’s create a container. The following syntax can be used as a guide:
lxc launch images:[distro]/[version]/[architecture] [your-container-name]
Now that we are enlightened enough and effortlessly, let’s create a test CentOS 8 and Ubuntu 20.04 container by running the following command:
$ lxc launch images:centos/8/amd64 cent8
Creating cent8
Retrieving image: Unpack: 100% (4.22GB/s)
Starting cent8
Start the Ubuntu container by running the following command:
$ lxc launch ubuntu:20.04 ubuntu20
Creating ubuntu20
Starting ubuntu20
Once they are started, you can easily list your containers, thereby:
$ lxc list
+-------+---------+---------------------+-----------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-------+---------+---------------------+-----------------------------------------------+-----------+-----------+
| cent8 | RUNNING | 10.80.35.177 (eth0) | fd42:b3a2:efa8:5aa5:216:3eff:fe1d:38c3 (eth0) | CONTAINER | 0 |
+-------+---------+---------------------+-----------------------------------------------+-----------+-----------+
You can also stop, start, restart, delete and check more information about the container, as shown below, where
lxc start <container>
lxc stop <container>
lxc restart <container>
lxc delete <container>
E.g
lxc stop ubuntu20
lxc delete ubuntu20
Note that the running container must be stopped before it can be deleted.
Use the info command option to get information about the container
$ lxc info container
##For example
$ lxc info cent8
Example excellent output:
Name: cent8
Location: none
Remote: unix://
Architecture: x86_64
Created: 2020/11/07 11:25 UTC
Status: Running
Type: container
Profiles: default
Pid: 2724
Ips:
eth0: inet 10.80.35.177 veth975e84ff
eth0: inet6 fd42:b3a2:efa8:5aa5:216:3eff:fe1d:38c3 veth975e84ff
eth0: inet6 fe80::216:3eff:fe1d:38c3 veth975e84ff
lo: inet 127.0.0.1
lo: inet6 ::1
Resources:
Processes: 13
Disk usage:
root: 737.98MB
CPU usage:
CPU usage (in seconds): 1
Memory usage:
Memory (current): 93.32MB
Memory (peak): 98.56MB
Network usage:
eth0:
Bytes received: 3.57kB
Bytes sent: 2.22kB
Packets received: 30
Packets sent: 22
lo:
Bytes received: 0B
Bytes sent: 0B
Packets received: 0
Packets sent: 0
Step 7: Execute temporary commands in the container:
Like you can “carried outIn a Docker container, you can also run commands in an lxd container. The syntax is like this.
$ lxc exec <container-name> <command>
Examples of executing commands are as follows:
$ lxc exec cent8 -- yum -y update
CentOS-8 - AppStream 538 kB/s | 5.8 MB 00:11
CentOS-8 - Base 619 kB/s | 2.2 MB 00:03
CentOS-8 - Extras 8.1 kB/s | 8.1 kB 00:01
Dependencies resolved.
Nothing to do.
Complete!
Let’s install Apache in the container
$ lxc exec cent8 -- yum -y install httpd
Last metadata expiration check: 0:00:41 ago on Sat Nov 7 12:56:38 2020.
Dependencies resolved.
====================================================================================================================================== Package Architecture Version Repository Size
======================================================================================================================================Installing:
httpd x86_64 2.4.37-21.module_el8.2.0+494+1df74eae AppStream 1.7 M
Installing dependencies:
apr x86_64 1.6.3-9.el8 AppStream 125 k
apr-util x86_64 1.6.1-6.el8 AppStream 105 k
After installation, we can log in to the container, create a sample page, start the web server and check its status
$ lxc exec cent8 -- /bin/bash
##We are now in the container
[[email protected] ~]# systemctl start httpd
[[email protected] ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since Sat 2020-11-07 12:58:09 UTC; 5s ago
Docs: man:httpd.service(8)
Main PID: 175 (httpd)
Status: "Started, listening on: port 80"
Tasks: 213 (limit: 11069)
Memory: 27.6M
CGroup: /system.slice/httpd.service
├─175 /usr/sbin/httpd -DFOREGROUND
├─176 /usr/sbin/httpd -DFOREGROUND
├─177 /usr/sbin/httpd -DFOREGROUND
├─178 /usr/sbin/httpd -DFOREGROUND
└─179 /usr/sbin/httpd -DFOREGROUND
Create a sample page in the container for Apache to demonstrate
[[email protected] ~]# vi /var/www/html/index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Spoon-Knife</title>
<LINK href="https://computingforgeeks.com/run-linux-containers-with-lxc-lxd-on-centos//styles.css" rel="stylesheet" type="text/css">
</head>
<body>
<img src="forkit.gif" id="octocat" alt="" />
<h2> About SELinux </h2><br>
<p>
SELinux gives you the ability to limit the privileges associated with executing processes and reduce the damage that could result from system and applications vulnerabilities exploitation. For this reason, it is recommended to keep SELinux in enforcing mode unless you have a good reason to disable it.
</p>
<h2> Modes</h2><br>
<p>
The other available mode for running SELinux in enabled state is Permissive. In this mode, SELinux policy is not enforced and access is not denied but denials are logged for actions that would have been denied if running in enforcing mode.
</p>
</body>
</html>
Then restart Apache in the container and exit.
[[email protected] ~]# systemctl restart httpd
Step 8: Access the application in the container from the outside
Well, now that you have deployed your application on a given container (for example, Apache in the above command), how will the target audience access your hosted content from the outside? You can use firewall rules, or you can use a more elegant approach, you can deploy a reverse proxy to route traffic to your application.
Use a reverse proxy server, such as Nginx
Install Nginx web server on CentOS 8 host system:
sudo yum -y install vim nginx
Set up the Nginx HTTP proxy for the service
Create a new configuration file.
sudo nano /etc/nginx/conf.d/app1.conf
Modify this configuration code snippet to suit your setup. Note that Nginx will listen on port 9090 and then redirect traffic to the container where Apache is running on port 80.
##App1 Upstreams
upstream app1 {
server 10.80.35.177:80; ##Notice the IP of the container here.
}
server {
listen 9090;
server_name app1.computingforgeeks.com;
access_log /var/log/nginx/app1_access.log;
error_log /var/log/nginx/app1_error.log;
# Proxy settings
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
# Request for root domain
location / {
proxy_redirect off;
proxy_pass http://app1;
}
# Gzip
gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript;
gzip on;
}
A valid DNS record is necessary for external (public) access to your application.
Check your configuration syntax:
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
If the setting returns positive feedback, please restart the nginx service.
sudo systemctl restart nginx
Allow port 9090 on the firewall
sudo firewall-cmd --permanent --add-port=9090/tcp
sudo firewall-cmd --reload
Now, we are ready to access our application. Open your favorite browser and point it to the IP address and port of the FQDN or Nginx proxy we just completed. http: //
in conclusion
We finally managed to install, manage and manage lxd / lxc Containers and hosting a simple application in one of the containers. We hope that this guide will provide you with as much information as you expect, and everything will be effective for you. Meeting you on the blog is enough to make us thank you for your visit and crazy support. Check out other exquisite guides below.
How to deploy LXD on CentOS 7 using Snap
Use Podman and Libpod to run Docker containers
How to run Docker/Podman containers as system services
You can download this article in PDF format via the link below to support us.Download the guide in PDF formatClose