LXD-Linux容器系统的基本特性

LXD-Linux容器系统的基本特性

LXD 是下一代系统容器管理器,所以它说 。 它提供类似于虚拟机的用户界面,但使用 Linux 容器。

LXD核心 是一个特权守护进程(以 root 权限运行的服务),它通过本地 unix 套接字以及网络(如果安装了适当的配置)提供 REST API。 客户端(例如 LXD 提供的命令行工具)通过此 REST API 发出请求。 这意味着无论您访问本地主机还是远程主机,一切都是一样的。

在本文中,我们不会详细讨论 LXD 的概念,也不会考虑文档中概述的所有可用功能,包括最近在 LXD 最新版本中实现的对 QEMU 虚拟机与容器并行支持的实现。 相反,我们将只学习容器管理的基础知识 - 设置存储池、网络、运行容器、应用资源限制以及如何使用快照,以便您可以基本了解 LXD 并在 Linux 上使用容器。

完整信息请参考官方来源:

导航

安装LXD ^

在 Ubuntu 发行版上安装 LXD ^

在Ubuntu 19.10发行包中 lxd 有广播 快照包:

apt search lxd

lxd/eoan 1:0.7 all
  Transitional package - lxd -> snap (lxd)

这意味着将同时安装两个软件包,一个作为系统软件包,另一个作为快照软件包。 在系统上安装两个软件包可能会产生一些问题,如果快照软件包管理器删除了快照软件包,系统软件包可能会成为孤立的。

查找包 lxd 在快照存储库中,您可以使用以下命令:

snap find lxd

Name             Version        Summary
lxd              3.21           System container manager and API
lxd-demo-server  0+git.6d54658  Online software demo sessions using LXD
nova             ocata          OpenStack Compute Service (nova)
nova-hypervisor  ocata          OpenStack Compute Service - KVM Hypervisor (nova)
distrobuilder    1.0            Image builder for LXC and LXD
fabrica          0.1            Build snaps by simply pointing a web form to...
satellite        0.1.2          Advanced scalable Open source intelligence platform

通过运行命令 list 你可以确保包裹 lxd 尚未安装:

snap list

Name  Version    Rev   Tracking  Publisher   Notes
core  16-2.43.3  8689  stable    canonical✓  core

尽管LXD是一个snap包,但它必须通过系统包安装 lxd,这将在系统中创建相应的组,必要的实用程序 /usr/bin 等等

sudo apt update
sudo apt install lxd

让我们确保该包作为快照包安装:

snap list

Name  Version    Rev    Tracking  Publisher   Notes
core  16-2.43.3  8689   stable    canonical✓  core
lxd   3.21       13474  stable/…  canonical✓  -

在 Arch Linux 发行版上安装 LXD ^

要在系统上安装 LXD 软件包,您需要运行以下命令,第一个命令将更新存储库中系统上可用的软件包列表,第二个命令将直接安装该软件包:

sudo pacman -Syyu && sudo pacman -S lxd

安装软件包后,为了让普通用户管理LXD,必须将其添加到系统组中 lxd:

sudo usermod -a -G lxd user1

让我们确保用户 user1 添加到组 lxd:

id -Gn user1

user1 adm dialout cdrom floppy sudo audio dip video plugdev netdev lxd

如果该组 lxd 在列表中不可见,那么您需要再次激活用户会话。 为此,您需要注销并以同一用户登录。

激活于 systemd 在系统启动时加载LXD服务:

sudo systemctl enable lxd

让我们启动服务:

sudo systemctl start lxd

检查服务状态:

sudo systemctl status lxd

存储 LXD(存储) ^

在初始化开始之前,我们需要了解LXD中的存储是如何逻辑排列的。

贮存 (存储) 由...组成 来自一个或多个 储存池 它使用受支持的文件系统之一,例如 ZFS、BTRFS、LVM 或常规目录。 每一个 储存池 分为卷(储存量)包含用于其他目的的图像、容器或数据。

  • 意象 - 这些是专门组装的发行版,没有 Linux 内核,可以从外部来源获得
  • 集装箱 - 这些是从映像部署的发行版,可供使用
  • 快照 - 这些是您可以返回的容器状态的快照

LXD-Linux容器系统的基本特性

要管理 LXD 中的存储,请使用命令 lxc storage 您可以通过指定密钥来获取的证书 - lxc storage --help

以下命令显示所有的列表 储存池 在 LXD 存储中:

lxc storage list

+---------+-------------+--------+--------------------------------+---------+
|  NAME   | DESCRIPTION | DRIVER |             SOURCE             | USED BY |
+---------+-------------+--------+--------------------------------+---------+
| hddpool |             | btrfs  | /dev/loop1                     | 2       |
+---------+-------------+--------+--------------------------------+---------+
| ssdpool |             | btrfs  | /var/lib/lxd/disks/ssdpool.img | 4       |
+---------+-------------+--------+--------------------------------+---------+

查看全部列表 储存量 在选定的 储存池 为团队服务 lxc storage volume list:

lxc storage volume list hddpool

+-------+----------------------------------+-------------+---------+
| TYPE  |          NAME                    | DESCRIPTION | USED BY |
+-------+----------------------------------+-------------+---------+
| image | ebd565585223487526ddb3607f515... |             | 1       |
+-------+----------------------------------+-------------+---------+

lxc storage volume list ssdpool

+-----------+----------------------------------+-------------+---------+
|   TYPE    |            NAME                  | DESCRIPTION | USED BY |
+-----------+----------------------------------+-------------+---------+
| container | alp3                             |             | 1       |
+-----------+----------------------------------+-------------+---------+
| container | jupyter                          |             | 1       |
+-----------+----------------------------------+-------------+---------+
| image     | ebd565585223487526ddb3607f515... |             | 1       |
+-----------+----------------------------------+-------------+---------+

另外,如果对于 储存池 创建时选择了BTRFS文件系统,然后得到一个列表 储存量 или 子卷 在BTRFS解释中,可以使用该文件系统的工具包:

sudo btrfs subvolume list -p /var/lib/lxd/storage-pools/hddpool

ID 257 gen 818 parent 5 top level 5 path images/ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3

sudo btrfs subvolume list -p /var/lib/lxd/storage-pools/ssdpool

ID 257 gen 1820 parent 5 top level 5 path images/ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
ID 260 gen 1819 parent 5 top level 5 path containers/jupyter
ID 263 gen 1820 parent 5 top level 5 path containers/alp3

初始化LXD ^

在创建和使用容器之前,您必须执行常规 LXD 初始化,以创建和配置网络和存储。 这可以通过调用命令使用列表中可用的标准客户端命令手动完成 lxc --help 或使用初始化向导 lxd init 回答几个问题。

为存储池选择文件系统 ^

在初始化期间,LXD 会询问几个问题,包括确定默认的文件系统类型 储存池。 默认情况下,选择 BTRFS 文件系统。 创建后将无法更改为其他 FS。 建议选择 FS 功能比较表:

专栏
目录
BTRFS
LVM
ZFS
消费电子展

优化图像存储
没有



优化实例创建
没有



优化快照创建
没有



优化图像传输
没有

没有

优化实例传输
没有

没有

写入时复制
没有



基于块
没有
没有

没有

即时克隆
没有



可在容器内使用的存储驱动程序


没有
没有
没有

从较旧的快照(不是最新的)恢复



没有

存储配额
是的(*)



没有

使用向导初始化网络和存储池 ^

我们将看到的下一个命令建议通过使用初始化向导回答简单的问题来设置 LXD 的主要组件。

运行命令 lxc init 并在冒号后输入问题的答案,如下例所示,或根据您的情况进行更改:

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]: ssdpool         
Name of the storage backend to use (lvm, btrfs, dir) [default=btrfs]: 
Create a new BTRFS pool? (yes/no) [default=yes]: 
Would you like to use an existing block device? (yes/no) [default=no]: 
Size in GB of the new loop device (1GB minimum) [default=15GB]: 10GB
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]: 10.0.5.1/24
Would you like LXD to NAT IPv4 traffic on your bridge? [default=yes]: 
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none
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] no
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: 

创建额外的存储池 ^

在上一步中我们创建了 储存池 被命名为 ssdpool 其文件位于我的系统上 /var/lib/lxd/disks/ssdpool.img。 该文件系统地址对应于我的 PC 中的物理 SSD 驱动器。

以下行动,以扩大对所扮演角色的理解 储存池 在存储库中,我们将创建第二个 储存池 其物理位置将位于不同类型的磁盘 HDD 上。 问题是 LXD 不允许你创建 储存池 地址外 /var/lib/lxd/disks/ 甚至符号链接也不起作用, 看开发商的回复。 我们可以在初始化/格式化期间绕过这个限制 储存池 通过将值指定为块设备,而不是通过在键中指定环回文件的路径 source.

所以,在创建之前 储存池 您需要定义一个环回文件或它将使用的文件系统上的现有分区。 为此,我们将创建并使用一个大小限制为 10GB 的文件:

dd if=/dev/zero of=/mnt/work/lxd/hddpool.img bs=1MB count=10000

10000+0 records in
10000+0 records out
10000000000 bytes (10 GB, 9,3 GiB) copied, 38,4414 s, 260 MB/s

让我们将环回文件连接到一个空闲的环回设备:

sudo losetup --find --show /mnt/work/lxd/hddpool.img

/dev/loop1

感谢钥匙 --show 执行该命令会在屏幕上返回回送文件所连接的设备的名称。 如果有必要,我们可以显示所有此类繁忙设备的列表,以确保我们的操作正确:

losetup -l

NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                      DIO LOG-SEC
/dev/loop1         0      0         0  0 /mnt/work/lxd/hddpool.img        0     512
/dev/loop0         0      0         1  0 /var/lib/lxd/disks/ssdpool.img   0     512

从列表中可以发现该设备有 /dev/loop1 包含环回文件 /mnt/work/lxd/hddpool.img,并在设备中 /dev/loop0 包含环回文件 /var/lib/lxd/disks/ssdpool.img 对应于默认的 储存池.

以下命令创建一个新的 储存池 在基于我们刚刚准备的环回文件的LXD中。 LXD将格式化环回文件 /mnt/work/lxd/hddpool.img 在设备中 /dev/loop1 对于 BTRFS 文件系统:

lxc storage create hddpool btrfs size=10GB source=/dev/loop1

让我们显示所有的列表 储存池 向屏幕:

lxc storage list

+---------+-------------+--------+--------------------------------+---------+
|  NAME   | DESCRIPTION | DRIVER |             SOURCE             | USED BY |
+---------+-------------+--------+--------------------------------+---------+
| hddpool |             | btrfs  | /dev/loop1                     | 0       |
+---------+-------------+--------+--------------------------------+---------+
| ssdpool |             | btrfs  | /var/lib/lxd/disks/ssdpool.img | 0       |
+---------+-------------+--------+--------------------------------+---------+

增加存储池大小 ^

创建后 储存池,如有需要,可以进行扩展。 为了 储存池 基于BTRFS文件系统,执行以下命令:

sudo truncate -s +5G /mnt/work/lxd/hddpool.img
sudo losetup -c /dev/loop1
sudo btrfs filesystem resize max /var/lib/lxd/storage-pools/hddpool

将环回文件自动插入到环回设备插槽中 ^

我们有一个小问题,当重新启动主机系统时,文件 /mnt/work/lxd/hddpool.img 会“飞”出设备 /dev/loop1 并且 LXD 服务在加载时会崩溃,因为它在此设备中看不到它。 要解决这个问题,您需要创建一个系统服务,将该文件插入到设备中 /dev/loop1 当主机系统启动时。

让我们创造 单元 文件类型 服务 в /etc/systemd/system/ 对于SystemD初始化系统:

cat << EOF | sudo tee -a /etc/systemd/system/lxd-hddpool.service
[Unit]
Description=Losetup LXD Storage Pool (hddpool)
After=local-fs.target

[Service]
Type=oneshot
ExecStart=/sbin/losetup /dev/loop1 /mnt/work/lxd/hddpool.img
RemainAfterExit=true

[Install]
WantedBy=local-fs.target
EOF

激活服务:

sudo systemctl enable lxd-hddpool

Created symlink /etc/systemd/system/local-fs.target.wants/lxd-hddpool.service → /etc/systemd/system/lxd-hddpool.service.

重启主机系统后,我们检查服务状态:

systemctl status lxd-hddpool.service 

● lxd-hddpool.service - Losetup LXD Storage Pool (hddpool)
     Loaded: loaded (/etc/systemd/system/lxd-hddpool.service; enabled; vendor preset: disabled)
     Active: active (exited) since Wed 2020-04-08 03:43:53 MSK; 1min 37s ago
    Process: 711 ExecStart=/sbin/losetup /dev/loop1 /mnt/work/lxd/hddpool.img (code=exited, status=0/SUCCESS)
   Main PID: 711 (code=exited, status=0/SUCCESS)

апр 08 03:43:52 manjaro systemd[1]: Starting Losetup LXD Storage Pool (hddpool)...
апр 08 03:43:53 manjaro systemd[1]: Finished Losetup LXD Storage Pool (hddpool).

从输出中我们可以验证服务状态是 要积极。,尽管事实上我们的脚本从一个命令的执行已经完成,但该选项允许我们这样做 RemainAfterExit=true.

安全。 容器权限 ^

由于所有容器进程实际上都使用其内核在主机系统上隔离运行,为了进一步保护容器进程对主机系统的访问,LXD 提供了进程权限,其中:

  • 特权容器 - 这些是容器,其中具有 UID 和 GID 的进程对应于与主机系统上相同的所有者。 例如,运行在UID为0的容器中的进程与主机系统上UID为0的进程具有所有相同的访问权限。换句话说,容器中的root用户不仅拥有容器上,而且如果他可以超出容器的隔离命名空间,也可以在主机系统上。

  • 非特权容器 - 这些容器中的进程属于 UID 和 GID(编号为 0 到 65535)的所有者,但对于主机系统,所有者分别使用添加​​的 SubUID 和 SubGID 位进行屏蔽。 例如,容器中 UID=0 的用户在主机系统上将被视为 SubUID + UID。 这可以保护主机系统,因为如果容器中的任何进程能够逃脱其隔离的命名空间,则它只能作为具有未知的、非常高的 UID/GID 的进程与主机系统通信。

默认情况下,新创建的容器具有非特权状态,因此我们必须定义 SubUID 和 SubGID。

让我们创建两个配置文件,分别在其中设置 SubUID 和 SubGID 的掩码:

sudo touch /etc{/subuid,/subgid}
sudo usermod --add-subuids 1000000-1065535 root 
sudo usermod --add-subgids 1000000-1065535 root

要应用更改,必须重新启动 LXD 服务:

sudo systemctl restart lxd

创建虚拟网络交换机 ^

由于我们之前使用初始化向导初始化了网络 lxd init 并创建了一个网络设备 lxdbr0那么在本节中我们将简单熟悉 LXD 中的网络以及如何使用客户端命令创建虚拟交换机(网桥)。

下图演示了交换机(桥)如何将主机和容器连接到网络中:

LXD-Linux容器系统的基本特性

容器可以通过网络与其他容器或提供这些容器的主机进行通信。 为此,您需要将容器的虚拟网卡与虚拟交换机链接起来。 我们将首先创建一个交换机,容器的网络接口将在容器本身创建后在后续章节中链接。

以下命令创建带有子网的交换机 10.0.5.0/24 和 IPv4 地址 10.0.5.1/24,并且还包括 ipv4.nat 这样容器就可以使用NAT服务通过主机访问Internet:

lxc network create lxdbr0 ipv4.address=10.0.5.1/24 ipv4.nat=true ipv6.address=none

检查 LXD 中可用的网络设备列表:

lxc network list

+--------+----------+---------+-------------+---------+
|  NAME  |   TYPE   | MANAGED | DESCRIPTION | USED BY |
+--------+----------+---------+-------------+---------+
| eno1   | physical | NO      |             | 0       |
+--------+----------+---------+-------------+---------+
| lxdbr0 | bridge   | YES     |             | 0       |
+--------+----------+---------+-------------+---------+

您还可以使用 Linux 发行版的标准工具验证是否已创建网络设备 - ip link или ip addr:

ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether bc:ee:7b:5a:6b:44 brd ff:ff:ff:ff:ff:ff
    altname enp0s25
    inet6 fe80::9571:11f3:6e0c:c07b/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: lxdbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether c2:38:90:df:cb:59 brd ff:ff:ff:ff:ff:ff
    inet 10.0.5.1/24 scope global lxdbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::c038:90ff:fedf:cb59/64 scope link 
       valid_lft forever preferred_lft forever
5: veth3ddab174@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master lxdbr0 state UP group default qlen 1000
    link/ether ca:c3:5c:1d:22:26 brd ff:ff:ff:ff:ff:ff link-netnsid 0

配置文件 ^

LXD 中的每个容器都有自己的配置,并且可以使用全局声明的配置来扩展它,称为 配置文件。 将配置文件应用到容器具有级联模型,以下示例演示了这一点:

LXD-Linux容器系统的基本特性

在此示例中,LXD 系统中创建了三个配置文件: default, hddpool и hostfs。 所有三个配置文件都应用于具有本地配置(灰色区域)的容器。 轮廓 default 有一个设备 root 其中有一个参数 poolssdpool,但是得益于级联配置应用模型,我们可以将配置文件应用到容器上 hddpool 其中有一个参数 pool 将覆盖配置文件中的相同参数 default 并且容器将接收设备配置 root 带参数 pool 等于 hddpool,以及个人资料 hostfs 只需将新设备添加到容器即可。

要查看可用配置文件的列表,请使用以下命令:

lxc profile list

+---------+---------+
|  NAME   | USED BY |
+---------+---------+
| default | 1       |
+---------+---------+
| hddroot | 0       |
+---------+---------+
| ssdroot | 1       |
+---------+---------+

可以通过添加密钥来获取用于使用配置文件的可用命令的完整列表 --help:

lxc profile --help

Description:
  Manage profiles

Usage:
  lxc profile [command]

Available Commands:
  add         Add profiles to instances
  assign      Assign sets of profiles to instances
  copy        Copy profiles
  create      Create profiles
  delete      Delete profiles
  device      Manage instance devices
  edit        Edit profile configurations as YAML
  get         Get values for profile configuration keys
  list        List profiles
  remove      Remove profiles from instances
  rename      Rename profiles
  set         Set profile configuration keys
  show        Show profile configurations
  unset       Unset profile configuration keys

编辑您的个人资料 ^

默认配置文件 default 容器没有网卡配置,并且所有新创建的容器都没有网络,因此需要使用单独的命令创建本地(专用)网络设备,但我们可以在配置中创建全局网络设备配置文件将在使用此配置文件的所有容器之间共享。 这样,在创建新容器的命令之后,它们将立即拥有可访问网络的网络。 同时,没有任何限制;如果需要的话,我们可以随时创建本地网络设备。

以下命令会将设备添加到配置文件中 eth0 类型 nic 连接到网络 lxdbr0:

lxc profile device add default eth0 nic network=lxdbr0 name=eth0

需要注意的是,由于我们实际上将设备添加到配置文件中,因此如果我们在设备中指定了静态 IP 地址,那么将使用此配置文件的所有容器将共享相同的 IP 地址。 如果需要创建一个为容器分配静态 IP 地址的容器,那么您应该使用 IP 地址参数在容器级别(本地配置)创建网络设备配置,而不是在配置文件级别。

让我们检查一下个人资料:

lxc profile show default

config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
  root:
    path: /
    pool: ssdpool
    type: disk
name: default
used_by: []

在此配置文件中,我们可以看到对于所有新创建的容器,将创建两个设备:

  • eth0 - 设备类型 nic 连接到交换机(网桥) lxdbr0
  • root - 设备类型 disk 它使用存储池 ssdpool

创建新的配置文件 ^

使用之前创建的 储存池 容器,创建配置文件 ssdroot 我们将在其中添加一个设备,例如 disk 带挂载点 / (root) 使用之前创建的 储存池 - ssdpool:

lxc profile create ssdroot
lxc profile device add ssdroot root disk path=/ pool=ssdpool

同样,我们创建一个类似的设备 disk,但在这种情况下使用 储存池 - hddpool:

lxc profile create hddroot
lxc profile device add hddroot root disk path=/ pool=hddpool

检查配置文件:

lxc profile show ssdroot

config: {}
description: ""
devices:
  root:
    path: /
    pool: ssdpool
    type: disk
name: ssdroot
used_by: []

lxc profile show hddroot

config: {}
description: ""
devices:
  root:
    path: /
    pool: hddpool
    type: disk
name: hddroot
used_by: []

图片库 ^

容器是根据专门组装的不具有 Linux 内核的发行版的映像创建的。 因此,在运行容器之前,必须从该镜像进行部署。 图像的来源是本地存储库,图像从外部存储库下载到其中。

远程图像存储库 ^

默认情况下,LXD 配置为从三个远程源接收图像:

  • Ubuntu: (适用于稳定的 Ubuntu 映像)
  • ubuntu每日: (适用于每日 Ubuntu 镜像)
  • 图片: (对于许多其他发行版)

lxc remote list

+-----------------+------------------------------------------+--------+--------+
|      NAME       |                   URL                    | PUBLIC | STATIC |
+-----------------+------------------------------------------+--------+--------+
| images          | https://images.linuxcontainers.org       | YES    | NO     |
+-----------------+------------------------------------------+--------+--------+
| local (default) | unix://                                  | NO     | YES    |
+-----------------+------------------------------------------+--------+--------+
| ubuntu          | https://cloud-images.ubuntu.com/releases | YES    | YES    |
+-----------------+------------------------------------------+--------+--------+
| ubuntu-daily    | https://cloud-images.ubuntu.com/daily    | YES    | YES    |
+-----------------+------------------------------------------+--------+--------+

例如,存储库 ubuntu: 有以下图像:

lxc image -c dasut list ubuntu: | head -n 11

+----------------------------------------------+--------------+----------+------------+
|                   DESCRIPTION                | ARCHITECTURE |   SIZE   |   TYPE     |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150728)  | x86_64       | 153.72MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150819)  | x86_64       | 152.91MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150906)  | x86_64       | 154.69MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150930)  | x86_64       | 153.86MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+

为了显示有限数量的列,我们使用了该选项 -c 带参数 dasut,并且还使用命令限制列表的长度 head.

过滤可用于显示图像列表。 以下命令将列出所有可用的分发架构 AlpineLinux:

lxc image -c ldast list images:alpine/3.11

+------------------------------+--------------------------------------+--------------+
|            ALIAS             |             DESCRIPTION              | ARCHITECTURE |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11 (3 more)         | Alpine 3.11 amd64 (20200220_13:00)   | x86_64       |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/arm64 (1 more)   | Alpine 3.11 arm64 (20200220_13:00)   | aarch64      |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/armhf (1 more)   | Alpine 3.11 armhf (20200220_13:00)   | armv7l       |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/i386 (1 more)    | Alpine 3.11 i386 (20200220_13:01)    | i686         |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/ppc64el (1 more) | Alpine 3.11 ppc64el (20200220_13:00) | ppc64le      |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/s390x (1 more)   | Alpine 3.11 s390x (20200220_13:00)   | s390x        |
+------------------------------+--------------------------------------+--------------+

本地镜像仓库 ^

要开始使用容器,您需要将全局存储库中的镜像添加到本地存储库中 local:。 现在本地存储库是空的,该命令将确保这一点 lxc image list。 如果方法 list 不指定存储库,则默认使用本地存储库 - local:

lxc image list local:

+-------+-------------+--------+-------------+--------------+------+------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE |
+-------+-------------+--------+-------------+--------------+------+------+

存储库中的图像使用以下方法进行管理:

团队
使用说明

lxc 图像 别号
管理图像别名

lxc 图像 复制
在服务器之间复制图像

lxc 图像 删除
删除图片

lxc 图像 编辑
编辑图像属性

lxc 图像 出口
导出和下载图像

lxc 图像 进口
将图像导入图像存储

lxc 图像 info
显示有关图像的有用信息

lxc 图像 名单
列出图像

lxc 图像 刷新
刷新图像

lxc 图像 显示
显示图像属性

将全局镜像复制到本地镜像 images::

lxc image copy images:alpine/3.11/amd64 local: --alias=alpine3

Image copied successfully!

让我们显示本地存储库中当前可用的所有图像的列表 local::

lxc image -c lfdatsu list local:

+---------+--------------+------------------------------------+--------------+
|  ALIAS  | FINGERPRINT  |            DESCRIPTION             | ARCHITECTURE |
+---------+--------------+------------------------------------+--------------+
| alpine3 | 73a3093d4a5c | Alpine 3.11 amd64 (20200220_13:00) | x86_64       |
+---------+--------------+------------------------------------+--------------+

LXD配置 ^

除了交互模式之外,LXD 还支持非交互配置安装模式,即以 YAML 文件的形式指定配置,这是一种特殊格式,允许您一次安装整个配置,绕过执行本文上面讨论的许多交互式命令,包括网络配置、配置文件的创建等。 这部分我们这里就不展开说了,大家可以自行查看。 在文档中.

下一个交互命令 lxc config 我们将看到它允许您设置配置。 例如,为了确保下载到本地存储库的图像不会从全局存储库自动更新,我们可以使用以下命令启用此行为:

lxc config set images.auto_update_cached=false

创建和管理容器 ^

要创建容器,请使用命令 lxc init 值传递给哪些对象 репозиторий:образ 然后是所需的容器 ID。 存储库可以指定为本地 local: 任何全球性的问题也是如此。 如果未指定存储库,则默认使用本地存储库来搜索镜像。 如果从全局仓库指定镜像,那么该镜像会先下载到本地仓库,然后用于创建容器。

让我们运行以下命令来创建我们的第一个容器:

lxc init alpine3 alp --storage=hddpool --profile=default --profile=hddroot

让我们按顺序查看此处使用的命令键:

  • alpine3 — 为之前上传到本地仓库的镜像指定别名(alias)。 如果没有为此图像创建别名,那么您始终可以通过其引用该图像 指纹 显示在表中。
  • alp — 设置容器的标识符
  • --storage — 该键表示在哪个 储存池 将创建一个容器
  • --profile — 这些键将先前创建的配置文件中的配置级联应用到容器

我们启动容器,它开始启动发行版的 init 系统:

lxc start alp

您还可以使用命令 lxc launch 这使您可以合并团队 lxc init и lxc start 在一次操作中。

检查容器的状态:

lxc list -c ns46tb
+------+---------+------------------+------+-----------+--------------+
| NAME |  STATE  |       IPV4       | IPV6 |   TYPE    | STORAGE POOL |
+------+---------+------------------+------+-----------+--------------+
| alp  | RUNNING | 10.0.5.46 (eth0) |      | CONTAINER | hddpool      |
+------+---------+------------------+------+-----------+--------------+

检查容器配置:

lxc config show alp

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200326_13:39)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200326_13:39"
  image.type: squashfs
  volatile.base_image: ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
  volatile.eth0.host_name: vethb1fe71d8
  volatile.eth0.hwaddr: 00:16:3e:5f:73:3e
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.power: RUNNING
devices:
  root:
    path: /
    pool: hddpool
    type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""

在该部分 profiles 我们可以确保该容器使用两个配置文件 - default и hddroot。 在部分 devices 我们只能检测一台设备,因为该网络设备是在配置文件级别创建的 default。 为了查看容器使用的所有设备,您需要添加一个密钥 --expanded:

lxc config show alp --expanded

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200326_13:39)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200326_13:39"
  image.type: squashfs
  volatile.base_image: ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
  volatile.eth0.host_name: vethb1fe71d8
  volatile.eth0.hwaddr: 00:16:3e:5f:73:3e
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.power: RUNNING
devices:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
  root:
    path: /
    pool: hddpool
    type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""

设置静态IP地址 ^

如果我们尝试为网络设备设置IP地址 eth0 团队 lxc config device set alp 用于容器配置,那么我们将收到一个错误,报告该设备不存在,因为该设备 eth0 容器使用的属于配置文件 default:

lxc config device set alp eth0 ipv4.address 10.0.5.5

Error: The device doesn't exist

我们当然可以设置一个静态IP地址 eth0 配置文件中的设备,但对于将使用此配置文件的所有容器来说都是相同的。 因此,让我们添加一个专用于容器的设备:

lxc config device add alp eth0 nic name=eth0 nictype=bridged parent=lxdbr0 ipv4.address=10.0.5.5

然后需要重启容器:

lxc restart alp

如果我们现在查看容器配置,我们不需要使用该选项 --expanded 查看网络设备 eth0,因为我们在容器级别创建了它,并且它从配置文件级联到同一设备 default:

lxc config show alp

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200326_13:39)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200326_13:39"
  image.type: squashfs
  volatile.base_image: ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
  volatile.eth0.host_name: veth2a1dc59d
  volatile.eth0.hwaddr: 00:16:3e:0e:e2:71
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.power: RUNNING
devices:
  eth0:
    ipv4.address: 10.0.5.5
    name: eth0
    nictype: bridged
    parent: lxdbr0
    type: nic
  root:
    path: /
    pool: hddpool
    type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""

移除容器 ^

要删除容器,请使用命令 lxc delete,但在删除容器之前,必须使用命令停止它 lxc stop:

lxc stop alp

lxc list

+------+---------+-------------------+------+-----------+-----------+
| NAME |  STATE  |       IPV4        | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+-------------------+------+-----------+-----------+
| alp  | STOPPED | 10.0.5.10 (eth0)  |      | CONTAINER | 0         |
+------+---------+-------------------+------+-----------+-----------+

当我们验证容器的状态已变为 已停止,它可以从 储存池:

lxc delete alp

集装箱存取 ^

要绕过网络连接直接在容器中执行命令,请使用以下命令 lxc exec 它在容器中执行命令而不启动系统 shell。 如果您需要使用变量、文件重定向(管道)等 shell 模式在 shell 中执行命令,那么您需要显式启动 shell 并将命令作为键传递,例如:

lxc exec alp -- /bin/sh -c "echo $HOME"

该命令使用了特殊的转义字符 对于特殊字符 $ 使得变量 $HOME 不在主机上解释,而仅在容器内解释。

也可以启动交互式 shell 模式,然后通过执行热键结束会话 CTRL+D:

lxc exec alp -- /bin/sh

容器资源管理 ^

在 LXD 中,您可以使用一组特殊的配置来管理容器资源。 可以找到容器配置参数的完整列表 在文档中.

内存资源限制 ^

参数 limits.memory 限制容器可用的 RAM 量。 该值是一个数字和其中之一 可用后缀.

让我们将容器的 RAM 限制设置为 256 MB:

lxc config set alp limits.memory 256MB

此外,还有其他限制内存的参数:

  • limits.memory.enforce
  • limits.memory.hugepages
  • limits.memory.swap
  • limits.memory.swap.priority

团队 lxc config show 允许您显示整个容器配置,包括设置的应用资源限制:

lxc config show alp

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200220_13:00)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200220_13:00"
  image.type: squashfs
  limits.memory: 256MB
  volatile.base_image: 73a3093d4a5ce0148fd84b95369b3fbecd19a537ddfd2e2d20caa2eef0e8fd60
  volatile.eth0.host_name: veth75b6df07
  volatile.eth0.hwaddr: 00:16:3e:a1:e7:46
  volatile.idmap.base: "0"
  volatile.idmap.current: '[]'
  volatile.idmap.next: '[]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
devices: {}
ephemeral: false
profiles:
- default
stateful: false
description: ""

CPU资源限制 ^

有多种方法可以限制 CPU 资源。 限制类型:

  • limit.cpu - 将容器绑定到一个或多个CPU核心
  • limits.cpu.allowance - 在超过时间限制时管理 CFS 调度程序配额,或在超过百分比时管理通用 CPU 资源共享机制
  • limits.cpu.priority - 当共享一组处理器的多个实例被分配相同百分比的处理器时,调度程序优先级

lxc config set alp limits.cpu.allowance 40%

lxc config show alp

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200220_13:00)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200220_13:00"
  image.type: squashfs
  limits.cpu.allowance: 40%
  limits.memory: 256MB
  volatile.base_image: 73a3093d4a5ce0148fd84b95369b3fbecd19a537ddfd2e2d20caa2eef0e8fd60
  volatile.eth0.host_name: veth75b6df07
  volatile.eth0.hwaddr: 00:16:3e:a1:e7:46
  volatile.idmap.base: "0"
  volatile.idmap.current: '[]'
  volatile.idmap.next: '[]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
devices: {}
ephemeral: false
profiles:
- default
stateful: false
description: ""

磁盘空间限制 ^

除了诸如此类的限制 limits.read, limits.write 我们还可以限制容器消耗的磁盘空间量(仅适用于 ZFS 或 BTRFS):

lxc config device set alp root size=2GB

安装后,在参数中 devices.root.size 我们可以验证设置的限制:

lxc config show alp
...
devices:
  root:
    path: /
    pool: hddpool
    size: 2GB
    type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""

要查看已使用的磁盘配额,我们可以通过命令获取 lxc info:

lxc info alp
...
Resources:
  Processes: 5
  Disk usage:
    root: 1.05GB
  CPU usage:
    CPU usage (in seconds): 1
  Memory usage:
    Memory (current): 5.46MB
  Network usage:
    eth0:
      Bytes received: 802B
      Bytes sent: 1.59kB
      Packets received: 4
      Packets sent: 14
    lo:
      Bytes received: 0B
      Bytes sent: 0B
      Packets received: 0
      Packets sent: 0

尽管我们已将容器的根设备限制为 2GB,但系统实用程序(例如 df 不会看到这个限制。 为此,我们将进行一个小测试并了解其工作原理。

让我们在同一个容器中创建 2 个新的相同容器 储存池 (硬盘池):

lxc init alpine3 alp1 --storage=hddpool --profile=default --profile=hddroot
lxc init alpine3 alp2 --storage=hddpool --profile=default --profile=hddroot

lxc list
+------+---------+------------------+------+-----------+-----------+
| NAME |  STATE  |       IPV4       | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+------------------+------+-----------+-----------+
| alp1 | RUNNING | 10.0.5.46 (eth0) |      | CONTAINER | 0         |
+------+---------+------------------+------+-----------+-----------+
| alp2 | RUNNING | 10.0.5.30 (eth0) |      | CONTAINER | 0         |
+------+---------+------------------+------+-----------+-----------+

让我们在其中一个容器中创建一个 1GB 文件:

lxc exec alp1 -- dd if=/dev/urandom of=file.img bs=1M count=1000

让我们确保文件已创建:

lxc exec alp1 -- ls -lh
total 1000M  
-rw-r--r--    1 root     root     1000.0M Mar 27 10:16 file.img

如果我们查看第二个容器,检查同一位置是否存在文件,那么该文件将不存在,这是预期的,因为容器是在自己的容器中创建的 储存量 在相同的 储存池:

lxc exec alp2 -- ls -lh
total 0

但我们来比较一下它产生的值 df 在一个和另一个容器上:

lxc exec alp1 -- df -hT
Filesystem           Type            Size      Used Available Use% Mounted on
/dev/loop1           btrfs           9.3G   1016.4M      7.8G  11% /
...

lxc exec alp2 -- df -hT
Filesystem           Type            Size      Used Available Use% Mounted on
/dev/loop1           btrfs           9.3G   1016.4M      7.8G  11% /
...

设备 /dev/loop1 安装为根分区 储存池 这些容器使用这些容器,因此它们在两个容器之间共享其体积。

资源消耗统计 ^

您可以使用以下命令查看容器的资源消耗统计信息:

lxc info alp

Name: alp
Location: none
Remote: unix://
Architecture: x86_64
Created: 2020/04/08 18:05 UTC
Status: Running
Type: container
Profiles: default, hddroot
Pid: 19219
Ips:
  eth0: inet    10.0.5.5        veth2a1dc59d
  eth0: inet6   fe80::216:3eff:fe0e:e271        veth2a1dc59d
  lo:   inet    127.0.0.1
  lo:   inet6   ::1
Resources:
  Processes: 5
  Disk usage:
    root: 495.62kB
  CPU usage:
    CPU usage (in seconds): 1
  Memory usage:
    Memory (current): 4.79MB
  Network usage:
    eth0:
      Bytes received: 730B
      Bytes sent: 1.59kB
      Packets received: 3
      Packets sent: 14
    lo:
      Bytes received: 0B
      Bytes sent: 0B
      Packets received: 0
      Packets sent: 0

使用快照 ^

LXD 能够创建快照并从中恢复容器状态。

要创建快照,请运行以下命令:

lxc snapshot alp snapshot1

团队 lxc snapshot 没有可用钥匙 list因此,要查看快照列表,您需要使用显示有关容器的一般信息的命令:

lxc info alp
...
...
Snapshots:
  snapshot1 (taken at 2020/04/08 18:18 UTC) (stateless)

您可以使用以下命令从快照恢复容器 lxc restore 指定要执行恢复的容器和快照别名:

lxc restore alp snapshot1

以下命令用于删除快照。 请注意,命令语法与其他命令语法并不相似;这里您需要在容器名称后指定正斜杠。 如果省略斜杠,则删除快照的命令将被解释为删除容器的命令!

lxc delete alp/snapshot1

在上面的示例中,我们研究了所谓的无状态快照。 LXD还有另一种类型的快照——有状态的,它保存容器中所有进程的当前状态。 有许多与状态快照相关的有趣且有用的功能。

还有什么? ^

  • Python 开发人员可以使用模块 吡咯烷酮 为 LXD 提供 API

更新 10.04.2020/15/00 XNUMX:XNUMX:添加导航

来源: habr.com

添加评论