作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。
介绍
一个Linux容器(LINK0)是一个与其他系统分离的过程集。对于最终用户来说,Linux容器作为虚拟机功能,但它更轻,你没有运行额外的Linux内核,容器不需要任何CPU硬件虚拟化支持,这意味着你可以在同一服务器上创建更多的容器,而不是虚拟机。
想象一下,你有一个服务器,该服务器应该为你的客户运行多个网站。一方面,每个网站都可能是一个虚拟主机/服务器块,与Apache或Nginx网络服务器相同的实例。另一方面,当你使用虚拟机时,你会为每个网站创建一个独立的嵌入式虚拟机。
LXD允许您创建和管理这些容器。LXD提供一个超视觉服务来管理容器的整个生命周期。在本教程中,您将配置LXD并使用它在容器中运行 Nginx。
前提条件
要完成本教程,您将需要以下内容:
要设置一个服务器,包括一个非 root sudo 用户和防火墙,你可以创建一个运行 Ubuntu 20.04 的 DigitalOcean Droplet(https://www.digitalocean.com/products/linux-distribution/ubuntu/),然后遵循我们的 初始服务器设置指南。记住你的服务器的公共 IP 地址。我们将后来称它为 your_server_ip
。
- 至少有 5 GB 的区块存储空间。 要设置此,你可以遵循 DigitalOcean’s Block Storage Volumes Quickstart。 在配置区块存储时,选择
手动格式和安装
以允许 LXD按需要准备它。 您将使用此来存储所有与容器相关的数据。
<$>[note] 注: 从Ubuntu 20.04开始,LXD正式可作为快递包提供。这是一个新的快递包格式,具有多个优点。可以在任何支持快递包的Linux发行版中安装快递包(https://snapcraft.io/docs/installing-snapd)。在运行LXD快递包时建议使用至少2GB RAM的服务器。下表概述了LXD快递包的功能:
Feature | snap package |
---|---|
available LXD versions | 2.0, 3.0, 4.0, 4.x |
memory requirements | moderate, for snapd service. Suggested server with 2GB RAM |
upgrade considerations | can defer LXD upgrade up to 60 days |
ability to upgrade from the other package format | can upgrade from deb to snap |
美元
按照本教程的其余部分来使用LXD从Ubuntu 20.04的快递包,但是,如果你想使用LXD deb包,请参阅我们的教程 如何在Ubuntu 18.04上安装和使用LXD。
步骤 1 – 准备您的环境为LXD
在您配置和运行 LXD 之前,您将准备您的服务器环境. 这包括将您的 sudo 用户添加到lxd
组中,并配置您的存储后端。
将非根帐户添加到lxd
Unix 组
设置非 root 帐户时,使用以下命令将其添加到lxd
组中,该命令将用户帐户和 Unix 组作为参数,以便将用户帐户添加到现有的 Unix 组:
1sudo adduser sammy lxd
现在申请新会员:
1su sammy
输入你的密码,然后按进入
。
最后,确认您的用户已被添加到lxd
组:
1id -nG
你会得到这样的输出:
1sammy sudo lxd
现在您已经准备好继续配置 LXD。
准备存储后台
首先,您将配置存储后端。
当你在Ubuntu上运行LXD时,推荐的存储备份是ZFS文件系统。ZFS也与DigitalOcean Block Storage(https://www.digitalocean.com/products/storage/)非常好。为了在LXD中启用ZFS支持,先更新你的包列表,然后安装zfsutils-linux
辅助包:
1sudo apt update
2sudo apt install -y zfsutils-linux
我们几乎准备好运行LXD初始化脚本。
在做之前,您必须识别并记住您的区块存储的设备名称。
要做到这一点,请使用ls
来检查/dev/disk/by-id/
目录:
1ls -l /dev/disk/by-id/
在此特定示例中,设备名称的完整路径为 /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-0
:
1[secondary_label Output]
2total 0
3lrwxrwxrwx 1 root root 9 Sep 16 20:30 scsi-0DO_Volume_volume-fra1-0 -> ../../sda
记下您的存储设备的完整文件路径,您将在下一步中使用它,当您配置 LXD。
步骤 2 — 初始化和配置 LXD
LXD在Ubuntu 20.04中作为一个快递包可用,它是预先安装的,但你必须配置它。
首先,请验证安装了 LXD 快照包. 命令快照列表
显示已安装的快照包:
1snap list
Ubuntu 20.04 預先安裝 LXD 4.0.3,並追蹤「4.0/stable」通道. LXD 4.0 支援五年(直到 2025 年)。
1[secondary_label Output of the "snap list" command — Listing the installed snap packages]
2Name Version Rev Tracking Publisher Notes
3core18 20200724 1885 latest/stable canonical✓ base
4lxd 4.0.3 16922 4.0/stable/… canonical✓ -
5snapd 2.45.3.1 8790 latest/stable canonical✓ snapd
要查找有关 LXD 安装的 snap 包的更多信息,请运行snap info lxd
。
您现在将配置 LXD。
配置 LXD 的存储选项
使用sudo lxd init
命令启动 LXD 初始化过程:
1sudo lxd init
首先,该程序会询问您是否要启用 LXD 聚合。为本教程的目的,请按ENTER
来接受默认不
,或者键入不
,然后按ENTER
。
1[secondary_label Output]
2Would you like to use LXD clustering? (yes/no) [default=no]: no
接下来的六个提示处理存储池. 给出以下答案:
- 按
ENTER
来配置新的存储池。 - 按
ENTER
来接受默认的存储池名。 - 按
ENTER
来接受默认的zfs
存储后端。 - 按
ENTER
来创建新的ZFS池。 - 键
是
来使用现有区块设备。
你的答案将看起来如下:
1[secondary_label Output]
2Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
3Name of the new storage pool [default=default]: default
4Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]: zfs
5Create a new ZFS pool? (yes/no) [default=yes]: yes
6Would you like to use an existing block device? (yes/no) [default=no]: yes
7Path to the existing block device: /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-01
您现在已经为 LXD 配置了存储备端,继续使用 LXD 的init
脚本,您现在将配置一些网络选项。
配置 LXD 的网络选项
LXD 现在会询问您是否想要连接到 MAAS (Metal As A Server) 服务器. MAAS 是软件,使空金属服务器看起来像虚拟机,并被处理成虚拟机。
我们在独立模式下运行 LXD,因此接受默认值并回答不
:
1[secondary_label Output]
2Would you like to connect to a MAAS server? (yes/no) [default=no]: no
然后,您将被要求为 LXD 容器配置网络桥梁,从而实现以下功能:
- 每个集装箱都会自动获得一个私有 IP 地址。
- 每个集装箱都可以通过私有网络相互通信。
- 每个集装箱都可以启动连接到互联网。
当被要求创建一个新的本地网络桥梁时,选择是
:
1[secondary_label Output]
2Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
然后接受默认名称, lxdbr0
:
1[secondary_label Output]
2What should the new bridge be called? [default=lxdbr0]: lxdbr0
接受桥梁的私人 IP 地址范围的自动选择:
1[secondary_label Output]
2What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
3What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
最后,LXD提出了以下混乱的问题:
当被问及是否要在网络上管理LXD时,请按ENTER
或回答不
:
1[secondary_label Output]
2Would you like LXD to be available over the network? (yes/no) [default=no]: no
当被问及是否要自动更新旧容器图像时,请按ENTER
或回答Yes
:
1[secondary_label Output]
2Would you like stale cached images to be updated automatically? (yes/no) [default=yes] yes
当被问及是否要查看并保留您刚刚创建的 YAML 配置时,请回答是
。
1[secondary_label Output]
2Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: no
一个脚本将在后台运行. 通常不会收到任何输出。
现在您已经为 LXD 配置了网络和存储选项,接下来您将创建您的第一个 LXD 容器。
步骤 2 —创建和配置一个LXD容器
现在您已经成功配置了 LXD,您已经准备好创建和管理您的第一个容器了。 在 LXD 中,您可以使用lxc
命令来管理容器,然后执行一些操作,例如列表
,启动
,开始
,停止
和删除
。
使用lxc 列表
查看可用的安装容器:
1lxc list
由于这是第一次lxc
命令与LXD超视图进行通信,它会显示一些关于如何启动容器的信息。最后,命令会显示一个空的容器列表。
1[secondary_label Output of the "lxd list" command]
2To start your first container, try: lxc launch ubuntu:18.04
3+------+-------+------+------+------+-----------+
4| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
5+------+-------+------+------+------+-----------+
现在创建一个运行 Nginx 的容器,首先使用lxc launch
命令创建并启动一个名为webserver
的 Ubuntu 18.04 容器。
创建webserver
容器.在ubuntu:18.04
中的18.04
是Ubuntu 18.04的简介,ubuntu:
是LXD图像预配置库的标识符,你也可以使用ubuntu:bionic
作为图像名称:
1lxc launch ubuntu:20.04 webserver
<$>[注]
注 :您可以通过运行lxc 图像列表 ubuntu:
和其他 Linux 发行版来找到所有可用的 Ubuntu 图像的完整列表,通过运行lxc 图像列表图像:
。
因为这是你第一次创建一个集装箱,这个命令将从互联网下载集装箱图像并缓存它。
1[secondary_label Output]
2Creating webserver
3Starting webserver
当webserver
容器启动时,使用lxc 列表
命令显示有关信息. 我们添加了 - columns ns4
以显示仅为名称
,状态
和IPv4
地址的列。
1lxc list --columns ns4
输出显示一个表,显示每个容器的名称、当前状态、IP地址和类型:
1[secondary_label Output]
2+-----------+---------+------------------------------------+
3| NAME | STATE | IPV4 |
4+-----------+---------+------------------------------------+
5| webserver | RUNNING | your_webserver_container_ip (eth0) |
6+-----------+---------+------------------------------------+
LXD 的 DHCP 服务器提供此 IP 地址,在大多数情况下即使重新启动服务器也会保持相同。但是,在以下步骤中,您将创建iptables
规则来将连接从互联网传输到容器。
下列命令将配置容器以获得静态IP分配. 首先,您将取代由默认LXD配置文件继承的eth0
设备的网络配置。
具体来说,lxc config device
是一个执行config
操作来配置一个设备
的命令。第一个行具有override
的子操作来将设备eth0
从容器webserver
上排列。第二个行有子操作来将eth0
容器的eth0
设备的ipv4.address
字段设置为最初由DHCP服务器提供的IP地址。
运行第一个config
命令:
1lxc config device override webserver eth0
你会得到这样的输出:
1[secondary_label Output]
2Device eth0 overridden for webserver
现在设置静态IP:
1lxc config device set webserver eth0 ipv4.address your_webserver_container_ip
如果命令成功,您将不会收到输出。
重新启动容器:
1lxc restart webserver
现在检查容器的状态:
1lxc list
您应该看到容器是运行
,而IPV4
地址是您的静态地址。
您已经准备好在容器内安装和配置 Nginx。
步骤 3 — 配置 Nginx 在 LXD 容器内
在此步骤中,您将连接到Web服务器
容器并配置Web服务器。
使用lxc shell
命令连接到容器,该命令采用容器的名称,并启动容器内部的壳:
1lxc shell webserver
一旦进入容器,你的壳提示将看起来如下:
1[environment second]
这个壳,即使是根壳,也仅限于容器,你在这个壳中运行的任何东西都留在容器中,不能逃到主机服务器。
<$>[注]
注: 当将壳放入容器时,您可能会看到一个警告,如mesg: ttyname failed: No such device
. 当容器中的壳试图从配置文件 /root/.profile
中运行 mesg
命令时,会产生此消息。
一旦进入容器,更新包列表并安装 Nginx:
1[environment second]
2apt update
3apt install nginx
安装了 Nginx 时,您现在将编辑默认的 Nginx 网页,具体来说,您将添加两行文本,以便明确该网站是在网页服务器
容器内部托管的。
使用「nano」或您偏好的编辑器,打开文件 /var/www/html/index.nginx-debian.html
:
1[environment second]
2nano /var/www/html/index.nginx-debian.html
将两个突出的句子添加到文件中:
1[secondary_label /var/www/html/index.nginx-debian.html]
2[environment second]
3<!DOCTYPE html>
4<html>
5<head>
6<title>Welcome to nginx on LXD container webserver!</title>
7<style>
8 body {
9 width: 35em;
10 margin: 0 auto;
11 font-family: Tahoma, Verdana, Arial, sans-serif;
12 }
13</style>
14</head>
15<body>
16<h1>Welcome to nginx on LXD container webserver!</h1>
17<p>If you see this page, the nginx web server is successfully installed and
18working. Further configuration is required.</p>
19...
您已经在两个地方编辑了文件,并特别添加了文本LXD 容器 Web 服务器
。
现在从容器中脱离:
1[environment second]
2logout
一旦服务器的默认提示返回,请使用curl
来测试容器中的 Web 服务器是否在工作. 要做到这一点,您需要 Web 容器的 IP 地址,您之前使用了lxc 列表
命令。
使用curl
来测试您的 Web 服务器:
1curl http://your_webserver_container_ip
您将收到 Nginx 默认 HTML 欢迎页面作为输出. 请注意,它包括您的编辑:
1[secondary_label Output]
2<!DOCTYPE html>
3<html>
4<head>
5<title>Welcome to nginx on LXD container webserver!</title>
6<style>
7 body {
8 width: 35em;
9 margin: 0 auto;
10 font-family: Tahoma, Verdana, Arial, sans-serif;
11 }
12</style>
13</head>
14<body>
15<h1>Welcome to nginx on LXD container webserver!</h1>
16<p>If you see this page, the nginx web server is successfully installed and
17working. Further configuration is required.</p>
18...
网页服务器正在工作,但您只能在主机上使用私人IP访问它,在下一步,您将向此容器路由外部请求,以便世界通过互联网访问您的网站。
步骤 4 — 使用 LXD 传输到 Nginx 容器的接入连接
现在你已经配置了 Nginx,现在是时候将网络服务器容器连接到互联网了。 首先,你需要将服务器设置为将可能在端口 80 上接收的任何连接转发到
网络服务器容器。 要做到这一点,你将创建一个
iptables`规则来传输网络连接。 您可以在我们的教程中了解更多有关IPTables的信息,例如: IPtables Firewall 如何工作和 IPtables Essentials: Common Firewall Rules and Commands。
此iptables
命令需要两个 IP 地址:服务器的公共 IP 地址(your_server_ip
)和webserver
容器的私人 IP 地址(your_webserver_container_ip
),您可以使用lxc 列表
命令获取。
运行此命令来创建一个新的 IPtables 规则:
1PORT=80 PUBLIC_IP=your_server_ip CONTAINER_IP=your_container_ip IFACE=eth0 sudo -E bash -c 'iptables -t nat -I PREROUTING -i $IFACE -p TCP -d $PUBLIC_IP --dport $PORT -j DNAT --to-destination $CONTAINER_IP:$PORT -m comment --comment "forward to the Nginx container"'
让我们来研究这个命令:
t nat
指明我们正在使用nat
表进行地址翻译。-I PREROUTING
指明我们正在将规则添加到 PREROUTING 链上。-i $IFACE
指明了接口eth0
,这是Droplets 的主机上的默认公共网络接口。-p TCP
表示我们正在使用 TCP 协议。-d $PUBLIC_IP
指明了规则的目的地 IP 地址。
<$>[注]
注: 您可以重复使用此命令来设置转发规则。在行开始时重置变量 PORT
、 PUBLIC_IP
、 CONTAINER_IP
和 IFACE
。
现在列出你的IPTables规则:
1sudo iptables -t nat -L PREROUTING
你会看到这样的输出:
1[secondary_label Output]
2Chain PREROUTING (policy ACCEPT)
3target prot opt source destination
4DNAT tcp -- anywhere your_server_ip tcp dpt:http /* forward to this container */ to:your_container_ip:80
5...
现在测试网页服务器是否可以从互联网访问
使用本地机器的弯曲
命令来测试连接:
1[environment local]
2curl --verbose 'http://your_server_ip'
您将看到标题,然后是您在容器中创建的网页的内容:
1[secondary_label Output]
2* Trying your_server_ip...
3* Connected to your_server_ip (your_server_ip) port 80 (#0)
4> GET / HTTP/1.1
5> User-Agent: curl/7.47.0
6> Accept: */*
7>
8< HTTP/1.1 200 OK
9< Server: nginx/1.10.0 (Ubuntu)
10...
11<!DOCTYPE html>
12<html>
13<head>
14<title>Welcome to nginx on LXD container webserver!</title>
15<style>
16 body {
17...
这确认请求正在进入容器。
最后,您将保存防火墙规则,以便在重新启动后再次应用。
要做到这一点,先安装iptables-persistent
包:
1sudo apt install iptables-persistent
安装包时,应用程序会提示您保存当前的防火墙规则. 接受并保存所有当前的规则。
当您重新启动机器时,防火墙规则将加载,此外,您的LXD容器中的Nginx服务将自动重新启动。
您已成功配置 LXD. 在最后一步中,您将学习如何停止和破坏服务。
步骤 5 – 使用 LXD 阻止和移除容器
您可以决定要下载容器并删除它. 在此步骤中,您将停止并删除容器。
首先,停止容器:
1lxc stop webserver
使用lxc 列表
命令来验证状态:
1lxc list
您将看到容器的状态表示停止
:
1[secondary_label Output]
2+-----------+---------+------+------+------------+-----------+
3| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
4+-----------+---------+------+------+------------+-----------+
5| webserver | STOPPED | | | PERSISTENT | 0 |
6+-----------+---------+------+------+------------+-----------+
若要移除容器,请使用‘lxc delete’:
1lxc delete webserver
运行lxc 列表
再次显示没有运行容器:
1lxc list
命令将输出如下:
1+------+-------+------+------+------+-----------+
2| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
3+------+-------+------+------+------+-----------+
使用lxc 帮助
命令查看其他选项。
若要移除将流量路由到容器的防火墙规则,请先使用此命令在规则列表中找到该规则,该命令将一行号与每个规则关联:
1sudo iptables -t nat -L PREROUTING --line-numbers
您将看到您的规则,前缀为行号,如下:
1[secondary_label Output]
2Chain PREROUTING (policy ACCEPT)
3num target prot opt source destination
41 DNAT tcp -- anywhere your_server_ip tcp dpt:http /* forward to the Nginx container */ to:your_container_ip
使用该行数删除规则:
1sudo iptables -t nat -D PREROUTING 1
再次列出规则以确保删除:
1sudo iptables -t nat -L PREROUTING --line-numbers
规则被删除:
1[secondary_label Output]
2Chain PREROUTING (policy ACCEPT)
3num target prot opt source destination
现在将更改保存,以便在重新启动服务器时不返回规则:
1sudo netfilter-persistent save
您现在可以将另一个容器带上自己的设置,并添加一个新的防火墙规则来向其传输流量。
结论
在本教程中,您安装并配置了LXD,然后使用 Nginx在LXD容器内部运行,创建了一个网站,并向我们IPtables公开提供。
从这里,你可以配置更多的网站,每个限制在自己的容器,并使用反向代理来指导流量到相应的容器. 教程 How to Host Multiple Web Sites with Nginx and HAProxy Using LXD on Ubuntu 16.04 )带你通过这个设置。
请参阅 LXD 参考文档 有关如何使用 LXD 的更多信息。
要练习LXD,你可以试试LXD在线(https://linuxcontainers.org/lxd/try-it/)并遵循基于Web的教程。
若要获取 LXD 上的用户支持,请访问 LXD 讨论论坛。