在CentOS 8上使用LXC/LXD运行Linux容器
LXC
Linux容器项目(LXC)是一个开源容器平台,提供了一组工具,模板,库和语言绑定。它提供的容器包括一个完整的Linux系统,就像一个VM,具有自己的文件系统,网络和多个应用程序。 LXC具有简单的命令行界面,可改善启动容器时的用户体验(RedHat,2017年)。通过功能强大的API和简单的工具,它使Linux用户可以轻松创建和管理系统或者应用程序容器。在进行容器化之前,Docker是在LXC之上构建的,但是从那以后他们就开始使用容器化了。
LXC的特点
当前的LXC使用以下内核功能来包含进程:来源:LinuxContainers
内核名称空间(ipc,uts,mount,pid,网络和用户)Apparmor和SELinux配置文件安全策略Chroots(使用ivot_root)内核功能CGroups(控制组)
LXD
LXD是下一代系统容器管理器。它是用于管理LXC系统容器的惊人界面,不应将其误解为平台或者容器类型。 LXD的功能包括快照和图像控制。我们可以猜测,LXD增强了LXC技术的功能。它提供类似于虚拟机的用户体验,但是使用Linux容器。
LXD的功能来源:LinuxContainers
LXD的一些最大功能是:通过设计确保安全(无特权的容器,资源限制等等)可扩展的(从便携式计算机上的容器到数千个计算节点)直观的(简单,清晰的API和清晰的命令行体验)基于图像的(每天发布各种Linux发行版)支持跨主机容器和镜像传输(包括使用CRIU进行实时迁移)高级资源控制(CPU,内存,网络I/O,块I/O,磁盘使用率和内核资源)设备直通(USB,GPU,Unix字符和块设备,NIC,磁盘和路径)网络管理(网桥创建和配置,跨主机隧道)存储管理(支持多个存储后端,存储池和存储卷)
在CentOS 8上安装LXC/LXD
如果我们希望在CentOS 8服务器上试用LXC/LXD来运行某些应用程序,以下步骤将尽快准备好平台使用。
更新并准备服务器
这是非常关键的一步,在此步骤中,我们通过确保安装了最新的补丁程序和软件包来确保房屋装修良好。继续运行以下命令以准备服务器。
sudo dnf update -y && sudo dnf upgrade -y sudo dnf install -y vim curl nano
禁用SELinux
如果我们擅长管理SELinux上下文,那么这是一个可选步骤。要使其宽松,请运行以下命令
sudo setenforce 0 sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
启用并配置EPEL存储库
运行以下命令以在CentOS 8上安装并启用EPEL存储库,然后更新服务器以从Epel获取最新软件包。
sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm sudo dnf update
在CentOS 8上安装快照
在此设置中,我们将安装Snappys LXD软件包,因为它具有Snap软件包所具有的简单性和支持。因此,我们需要在服务器上安装snapd,如下所示:
sudo yum install snapd -y
安装后,需要启用用于管理主快照通信套接字的systemd单元:
sudo systemctl enable --now snapd.socket
要启用经典快照支持,请输入以下内容在/var/lib/snapd/snap和/snap之间创建符号链接:
sudo ln -s /var/lib/snapd/snap /snap
注销并重新登录,或者重新启动系统以确保正确更新快照路径。一旦安装好快照,让我们继续下一步。
添加内核参数
LXD需要一些重要的内核选项,我们将在服务器上启用该选项。通过以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
配置这些设置后,由于核心内核功能已更改,因此需要重新引导服务器。重新启动服务器。
sudo reboot
在CentOS 8上安装lxd snap
最后,在服务器备份之后,就该退出从Snap存储中安装的目标软件包LXD。就像制作Snap一样简单,我们只需要运行以下命令,便会安装我们的LXD。
$sudo snap install --classic lxd
启动测试LXD容器
到目前为止,我们已经安装了LXC/LXD,但是还没有容器可以容纳我们感兴趣的应用程序。因此,在启动某些容器之前,让我们将用户帐户添加到组lxd中,以便它在没有权限限制的情况下管理LXD容器。
sudo usermod -aG lxd <your-username> newgrp lxd
注意:newgrp命令用于在登录会话期间更改当前组ID。如果给出了可选标志,则用户环境将被重新初始化,就像用户已登录一样,否则当前环境(包括当前工作目录)保持不变。 newgrp将当前的真实组ID更改为命名组。
接下来,让我们配置LXD环境或者通过运行以下命令对其进行初始化。它会带我们解决几个问题。请根据环境需求回答。我将默认值用于空白值。
$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]:
上面的命令将创建一个桥lxdbr0。我们将这个桥接接口添加到可信区域,以便连接通过。换句话说,我们将允许通过lxdbr0的所有传入流量。执行以下防火墙命令
sudo firewall-cmd --add-interface=lxdbr0 --zone=trusted --permanent sudo firewall-cmd --reload
创建容器
初始化lxd并通过lxc命令为用户授予启动和管理容器的权限后,让我们创建一个容器。以下语法可用作指导:
lxc launch images:[distro]/[version]/[architecture] [your-container-name]
现在我们已经足够开悟,并且不费吹灰之力,让我们通过运行以下命令来创建测试CentOS 8和Ubuntu 20.04容器:
$lxc launch images:centos/8/amd64 cent8 Creating cent8 Retrieving image: Unpack: 100% (4.22GB/s) Starting cent8
通过运行以下命令启动Ubuntu容器:
$lxc launch ubuntu:20.04 ubuntu20 Creating ubuntu20 Starting ubuntu20
一旦启动它们,我们可以轻松列出容器,从而:
$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 | +-------+---------+---------------------+-----------------------------------------------+-----------+-----------+
我们还可以停止,启动,重新启动,删除以及检查容器的更多信息,如下所示,其中<container>是容器的名称,如lxc list命令所示。
lxc start <container> lxc stop <container> lxc restart <container> lxc delete <container>
例如
lxc stop ubuntu20 lxc delete ubuntu20
请注意,必须先停止正在运行的容器,然后才能将其删除。
使用info命令选项获取有关容器的信息
$lxc info container ##For example $lxc info cent8
示例出色的输出:
Name: cent8 Location: none Remote: unix:// Architecture: x86_64 Created: 2017/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
在容器中执行临时命令:
就像可以在Docker容器中执行的方式一样,我们也可以在lxd容器内运行命令。语法是这样的。
$lxc exec <container-name> <command>
执行命令的示例如下:
$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!
让我们在容器中安装Apache
$lxc exec cent8 -- yum -y install httpd Last metadata expiration check: 0:00:41 ago on Sat Nov 7 12:56:38 2017. 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
安装后,我们可以登录到容器,创建示例页面,启动Web服务器并检查其状态
$lxc exec cent8 -- /bin/bash ##We are now in the container [theitroad@localhost ~]# systemctl start httpd [theitroad@localhost ~]# 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 2017-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
在容器中创建示例页面,以供Apache进行演示
[theitroad@localhost ~]# 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="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>
然后在容器内重新启动Apache并退出。
[theitroad@localhost ~]# systemctl restart httpd
从外部访问容器内的应用程序
好了,既然我们已经将应用程序部署在给定的容器上(例如,上述命令中的Apache),那么目标受众将如何准确地从外部访问我们托管的内容?我们可以使用防火墙规则,也可以更优雅地使用,可以部署反向代理以将流量路由到应用程序。
使用反向代理服务器,例如Nginx
在CentOS 8主机系统上安装Nginx Web服务器:
sudo yum -y install vim nginx
设置服务的Nginx HTTP代理
创建一个新的配置文件。
sudo nano /etc/nginx/conf.d/app1.conf
修改此配置代码段以适合设置。请注意,Nginx将在端口9090上侦听,然后将流量重定向到Apache在端口80运行的容器。
##App1 Upstreams upstream app1 { server 10.80.35.177:80; ##Notice the IP of the container here. } server { listen 9090; server_name app1.theitroad.local; 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; }
有效的DNS记录对于应用程序的外部(公共)访问是必需的。
检查配置语法:
$sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
如果设置返回正反馈,请重新启动nginx服务。
sudo systemctl restart nginx
允许防火墙上的端口9090
sudo firewall-cmd --permanent --add-port=9090/tcp sudo firewall-cmd --reload
现在,我们准备访问我们的应用程序。打开我们喜欢的浏览器,并将其指向我们刚刚完成配置的FQDN或者Nginx代理的IP地址和端口。 http://<ip-or-fqdn>:9090。