在CentOS 8上使用LXC/LXD运行Linux容器

时间:2020-02-23 14:31:25  来源:igfitidea点击:

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>hello</title>
  <LINK href="styles.css" rel="stylesheet" type="text/css">
</head>

<body>
hello 

</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。我们应该看到类似以下的页面。