如何在 Ubuntu 18.04 上设置和使用 LXD

作者选择了 自由和开源基金作为 写给捐款计划的一部分接受捐款。

介绍

一个Linux容器(LINK0)是一个与其他系统分离的过程集。对于最终用户来说,一个Linux容器作为一个虚拟机功能,但它更轻。你没有运行额外的Linux内核的能力,容器不需要任何CPU硬件虚拟化支持。

想象一下,你有一个服务器,该服务器应该为你的客户运行多个网站。一方面,每个网站都可能是一个虚拟主机/服务器块,与Apache或Nginx网络服务器相同的实例。另一方面,当你使用虚拟机时,你会为每个网站创建一个独立的嵌入式虚拟机。

LXD允许您创建和管理这些容器。LXD提供一个超视觉服务来管理容器的整个生命周期。在本教程中,您将配置LXD并使用它在容器中运行 Nginx

前提条件

要完成本教程,您将需要以下内容:

要设置一个服务器,包括一个非 root sudo 用户和防火墙,你可以创建一个运行 Ubuntu 18.04 的 DigitalOcean Droplet(https://www.digitalocean.com/products/linux-distribution/ubuntu/),然后遵循我们的 初始服务器设置指南。记住你的服务器的公共 IP 地址。我们将后来称它为 your_server_ip

  • 至少有 5GB的区块存储空间。 要设置此,你可以遵循 DigitalOcean’s Block Storage Volumes Quickstart。 在配置区块存储时,选择 手动格式和安装以允许 LXD根据需要准备它。 您将使用此来存储所有与容器相关的数据。

<$>[注] 注: LXD 在 Ubuntu 18.04 中预先安装,而安装的 LXD 包是 deb 包,但从 Ubuntu 20.04 开始,较新的 LXD 版本现在只能作为 snap 包提供。

因此,Ubuntu 18.04 是最后一个具有 LXD 作为 deb 包的 Ubuntu 版本. 这个 LXD deb 包具有标准支持,直到 2023 年,2028 年生命结束。

Featuredeb packagesnap package
available LXD versions3.02.0, 3.0, 4.0, 4.x
memory requirementsminimalmoderate, for snapd service
upgrade considerationsyou can decide not to upgrade LXDcan defer LXD upgrade up to 60 days
ability to switch from the other package formatnot supportedcan switch from deb to snap

请遵循本教程的其余部分,以便在 Ubuntu 18.04 中使用 deb 包中的 LXD。如果您希望在 Ubuntu 18.04 中使用 LXD 快递包,请参阅 [TODO-TUTORIAL-FOR-LXD-IN-UBUNTU-20.04]。

步骤 1 — 配置 LXD

LXD 可在 Ubuntu 18.04 中作为 Deb 套件提供,它是预先安装的,但您必须在使用之前配置它。 LXD 由 LXD 服务和默认客户端实用程序组成,可帮助您配置该服务。 此客户端实用程序是lxc。 客户端实用程序可以访问 LXD 服务,如果您将其运行为root,或者如果您的非 root 帐户是lxd Unix 组成员。

将非根帐户添加到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. 使用sudo lxd init命令启动 LXD:

1sudo lxd init

接下来的两个部分将引导你通过每个问题的适当答案。

配置 LXD 的存储选项

首先,该程序会询问您是否要启用 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:18.04 webserver

<$>[注] :您可以通过运行lxc 图像列表 ubuntu:和其他 Linux 发行版来找到所有可用的 Ubuntu 图像的完整列表,通过运行lxc 图像列表图像: 两者都是容器图像的仓库。对于每个容器图像,您可以通过命令lxc 图像信息 ubuntu:18.04获取更多信息。

因为这是你第一次创建一个集装箱,这个命令将从互联网下载集装箱图像并缓存它。

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 地址。

<$>[注] 注: 您可以重复使用此命令来设置转发规则。在行开始时重置变量 PORTPUBLIC_IPCONTAINER_IPIFACE

现在列出你的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 讨论论坛

Published At
Categories with 技术
comments powered by Disqus