头图

一、前言

在之前的章节 LXD 虚拟化平台(2):镜像管理 中,详细讲解了 LXD 虚拟化平台的镜像管理机制以及制作与使用的基本方法。

和容器类似,基于镜像,LXD 虚拟化平台可以创建 LXC 容器实例或者 KVM 虚拟机实例。实例管理是虚拟化平台中最为关键的功能,本文聚焦在 LXD 的实例管理方面,详细讲解 LXD 的实例创建、启停、快照、复制、迁移、配置等多项能力。

二、实例全局配置 profile

2.1 profile 的作用

LXD 在创建虚拟机实例的时候,需要指定虚拟机的初始化配置文件(profile),虚拟机实例可以指定一个或者多个配置文件,该特性方便管理员对虚拟机配置进行分类管理。

image.png

例如LXD管理员可以创建多个不同用途的 profile:

  • default:实例的默认配置,包含网卡、磁盘
  • docker:支持实例中启动 docker 服务;
  • k8s:支持实例中安装 Kubernetes 集群;
  • ......

当 LXD 管理员希望创建一个实例 test-1,用于安装 Kubernetes 集群时,可以使用 launch 指令的 -p 参数,同时把多个相关特性的配置分配给实例即可。

2.2 profile 指令的说明

profile 指令用于管理虚拟机实例配置文件,基本的用法如下:

root@easyops:~# lxc profile 
Usage:
  lxc profile [flags]
  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 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

常用的参数说明:

参数说明示例
add把配置添加到虚拟机实例lxc profile add instance-01 profile-01
assign把配置覆盖到虚拟机实例,与 add 指令不一样,assign 指令会覆盖虚拟机实例的所有配置lxc profile assign instance-01 profile-01
remove移除实例的配置文件lxc profile remove instance-01 profile-01
create创建虚拟机配置文件lxc profile create profile-01
delete删除虚拟机配置文件,该项操作必须在没有实例使用配置的情况下才能执行成功lxc profile delete profile-01
list查看虚拟机配置文件列表lxc profile list
show查看虚拟机配置文件详情lxc profile show profile-01

2.3 profile 的内容说明

LXD 在初始化的时候(lxd init)会自动生成一个名叫 default 的默认虚拟机配置,可通过 profile 指令查询:

root@easyops:~# lxc profile list
+---------+---------------------+---------+
|  NAME   |     DESCRIPTION     | USED BY |
+---------+---------------------+---------+
| default | Default LXD profile | 0       |
+---------+---------------------+---------+

查看 default 文件的内容:

root@easyops:~# lxc profile show default
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    nictype: bridged
    parent: br0
    type: nic
  root:
    path: /
    pool: default
    type: disk
name: default
used_by: []

对文件内容分析如下:

字段内容说明
name配置文件名称
description配置文件的描述信息
configLXD 的虚拟机配置均为 KV 的键值对,影响虚拟机的运行表现,例如:

1. 配置虚拟随着LXD服务自动启动:boot.autostart: "true"

2. 配置虚拟机内存边界为硬性限制:limits.memory.enforce: hard

更多详细的虚拟机配置见官方网站:https://linuxcontainers.org/lxd/docs/latest/explanation/insta...
devices虚拟机的设备信息,目前 LXD 支持 12 种设备类型,比较常用到的设备类型是 nic(网卡)、disk(磁盘)、unix-char(字符设备),通常会在默认的配置文件里面设置好默认网卡和根目录,配置好相关的信息
used_byLXD 系统自动生成,显示已经使用了此配置文件的虚拟机实例列表

2.4 profile 的生产案例

生产配置的情况下,虚拟机配置文件的常规应用方法:

  • default: 默认的虚拟机配置文件,配置基础网卡与根目录
  • 其他配置:按照特性来进行分类,例如为虚拟机添加支持容器化的特性、或者Kubernetes的特性。

在这里展示一个基本的案例,为一个 LXC Container 实例提供基础的网卡、根磁盘,并且支持实例内部安装 Kubernetes 集群和 Docker 服务。

首先,创建 default 配置文件,提供基础网卡与根磁盘:

config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    nictype: bridged
    parent: br0
    type: nic
  root:
    path: /
    pool: lxc-storage
    type: disk
name: default

然后创建 k8s 配置文件,提供虚拟机内安装 Docker 与 Kubernetes 服务的特性:

config:
  boot.autostart: "true"
  limits.memory.enforce: hard
  limits.memory.swap: "false"
  linux.kernel_modules: ip_vs,ip_vs_rr,ip_vs_wrr,ip_vs_sh,ip_tables,ip6_tables,netlink_diag,nf_nat,overlay,br_netfilter
  raw.lxc: |
    lxc.apparmor.profile=unconfined
    lxc.mount.auto=proc:rw sys:rw cgroup:rw
    lxc.cgroup.devices.allow=a
    lxc.cap.drop=
  security.nesting: "true"
  security.privileged: "true"
description: "Enable K8S and Docker Feature"
devices:
  aadisable:
    path: /sys/module/nf_conntrack/parameters/hashsize
    source: /sys/module/nf_conntrack/parameters/hashsize
    type: disk
  aadisable1:
    path: /sys/module/apparmor/parameters/enabled
    source: /dev/null
    type: disk
  aadisable2:
    path: /dev/kmsg
    source: /dev/kmsg
    type: unix-char
  aadisable3:
    path: /sys/fs/bpf
    source: /sys/fs/bpf
    type: disk
  aadisable4:
    path: /proc/sys/net/netfilter/nf_conntrack_max
    source: /proc/sys/net/netfilter/nf_conntrack_max
    type: disk
name: k8s

最后使用两份配置来创建实例 test-01:

lxc launch lxd-server-01:centos-8-base -p default -p k8s test-1 -c limits.cpu=8 -c limits.memory=24GiB

test-01 实例启动后,实例内部可以正常地安装和使用 Docker、Kubernetes 的服务。

三、实例管理

LXD 虚拟化平台同时支持对 LXC Container 和 KVM 虚拟机进行管理,下面详细讲解 LXD 的实例管理。

3.1 创建实例

launch 指令用于创建实例,基本的用法如下:

Description:
  Create and start instances from images

Usage:
  lxc launch [<remote>:]<image> [<remote>:][<name>] [flags]

Examples:
  lxc launch ubuntu:22.04 u1

  lxc launch ubuntu:22.04 u1 < config.yaml
      Create and start a container with configuration from config.yaml

  lxc launch ubuntu:22.04 v1 --vm
      Create and start a virtual machine

Flags:
  -c, --config                Config key/value to apply to the new instance
      --console[="console"]   Immediately attach to the console
  -d, --device                New key/value to apply to a specific device
      --empty                 Create an empty instance
  -e, --ephemeral             Ephemeral instance
  -n, --network               Network name
      --no-profiles           Create the instance with no profiles applied
  -p, --profile               Profile to apply to the new instance
  -s, --storage               Storage pool name
      --target                Cluster member name
  -t, --type                  Instance type
      --vm                    Create a virtual machine

Launch 指令的常用的参数说明如下:

参数说明示例
-p, --profile指定虚拟机的配置文件,可以指定一个或者多个配置文件lxc launch lxd-server-01:centos-8-base -p default -p k8s test-1
-s, --storage存放虚拟机的存储池,LXD 提供多种类型的虚拟化存储方式,例如目录、LVM、ZFS、BRTFS等等lxc launch lxd-server-01:centos-8-base test-1 -s ssd
-c, --config指定虚拟机的参数配置。如果不方便在 profile 中指定,或者希望覆盖 profile 中的虚拟机配置,可以在创建时使用此参数手动指定。可以多次使用来指定多个参数。lxc launch lxd-server-01:centos-8-base test-1 -c limits.cpu=8 -c limits.memory=24GiB
--vm创建 KVM 虚拟机实例。默认情况下 LXD 创建的实例均为 LXC Container,如果希望能创建硬件虚拟化的实例,可以指定该参数。lxc launch lxd-server-01:centos-8-base test-1 --vm

以下是一些案例,仅供参考。
1. 使用 ubuntu 22.04 创建 LXC 容器实例,名为 u1

lxc launch ubuntu:22.04 u1

2. 使用 ubuntu 22.04 创建 LXC 容器实例,1个CPU核心,2GiB内存,名为 u1

lxc launch ubuntu:22.04 u1 -c limits.cpu=1 -c limits.memory=2GiB

3. 使用 ubuntu 22.04 创建 LXC 容器实例,指定虚拟机配置文件 default 和 k8s,名为 u1

lxc launch ubuntu:22.04 -p default -p k8s u1 

4. 使用 ubuntu 22.04 创建 KVM 实例,名为 u1

lxc launch ubuntu:22.04 u1 --vm

5. 使用 ubuntu 22.04 创建 LXC 容器实例,存放在标识为 ssd 的存储池,名为 u1

lxc launch ubuntu:22.04 u1 -s ssd

3.2 查询与使用实例

虚拟机实例创建后,可以通过 list 指令来查看实例列表。

# 创建虚拟机实例
root@easyops:~# lxc launch ubuntu:22.04 u1 -c limits.cpu=1 -c limits.memory=64MiB
Creating u1
Starting u1

# 查询虚拟机实例列表
root@easyops:~# lxc list 
+------+---------+------+------+-----------+-----------+
| NAME |  STATE  | IPV4 | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+------+------+-----------+-----------+
| u1   | RUNNING |      |      | CONTAINER | 0         |
+------+---------+------+------+-----------+-----------+

3.2.1 访问 LXC Container 实例

刚创建的实例可能网络未就绪,因此无法通过 SSH 等网络的方式来访问,LXD 提供 exec 指令来访问 LXC 实例,以下是一些使用案例。

1.直接进入 LXD 实例:lxc exec [实例名称] bash

root@easyops:~# lxc exec u1 bash 
root@u1:~# hostname
u1
root@u1:~# free -h 
               total        used        free      shared  buff/cache   available
Mem:           256Mi        74Mi        59Mi       0.0Ki       121Mi       181Mi
Swap:             0B          0B          0B

1.在宿主机外部执行指令:lxc exec [实例名称] --sh -c "[CMD指令]"

root@easyops:~# lxc exec u1 -- sh -c "w"
 09:58:41 up 2 min,  0 users,  load average: 0.23, 2.81, 4.35
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT

3.2.2 访问 KVM 实例

如果是 KVM 实例,可以使用 console 指令或者 VNC 协议。

console 指令帮助用户在终端访问 KVM 实例,基本的用法如下:

Description:
  Attach to instance consoles

  This command allows you to interact with the boot console of an instance
  as well as retrieve past log entries from it.

Usage:
  lxc console [<remote>:]<instance> [flags]

Flags:
      --show-log   Retrieve the instance's console log
  -t, --type       Type of connection to establish: 'console' for serial console, 'vga' for SPICE graphical output (default "console")

--show-log 参数返回实例的终端日志,-t 可以指定 KVM 的实例终端模式。例如使用 console 指令访问 KVM 实例 u1:

lxc console u1 --show-log

如果 console 指令无法连接,也可以使用传统的 VNC 方式,参考以下案例:

# 通过 ps 指令定位 kvm 实例进程
# 可以查看到 vnc 的端口号
root@dev-physical-0-19:~# ps aux | grep dev-host-0-67-lxd-test
libvirt+  335520 17.9  1.1 18287660 4683796 ?    Sl   16:58  12:57 /usr/bin/qemu-system-x86_64 -name guest=dev-host-0-67-lxd-test,debug-threads=on ...... driver=none -vnc 0.0.0.0:5,audiodev=audio1 ......

# 可以看到 --vnc 0.0.0.0:5,VNC 软件的访问端口就是 [宿主机IP]:[5905]

3.3 实例快照与恢复

LXD 支持对实例进行创建快照,快照的指令 snapshot,从快照恢复实例的指令是 restore

提供以下的案例参考。
1. 为实例 u1 创建快照,名称为 u1-snapshot-202306161815

root@easyops:~# lxc snapshot u1 u1-snapshot-202306161815
root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+

# 通过 lxc info 来查看快照列表
root@easyops:~# lxc info u1
Name: u1
Status: RUNNING
Type: container
Architecture: x86_64
PID: 9508
Created: 2023/06/16 09:55 UTC
Last Used: 2023/06/16 09:56 UTC

......

Snapshots:
+--------------------------+----------------------+------------+----------+
|           NAME           |       TAKEN AT       | EXPIRES AT | STATEFUL |
+--------------------------+----------------------+------------+----------+
| u1-snapshot-202306161815 | 2023/06/16 10:17 UTC |            | NO       |
+--------------------------+----------------------+------------+----------+

可以创建多个快照,但是要注意磁盘容量,一些过期的备份建议需定时清理。

2. 从快照 u1-snapshot-202306161815 恢复实例 u1。

root@easyops:~# lxc restore u1 u1-snapshot-202306161815
root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+

3.4 复制实例

LXD 通过 copy(cp) 指令支持对实例进行复制,例如一些常用的开发环境、制作实例模板等场景,可以通过 copy 指令进行快速生成相应的环境。

提供以下的案例参考: 复制u1实例,命名为u2。

root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
root@easyops:~# lxc copy u1 u2
root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
| u2   | STOPPED |                     |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+

复制出来的实例处于关机状态,等待进一步的调整。

3.5 迁移实例

虚拟机实例可以在 LXD 服务器之间迁移,前提条件:

  • 如果是单机模式的 LXD Server 之间迁移实例,需要添加 remote 进行信任授权。例如从 LXD_SERVER_A 迁移主机到 LXD_SERVER_B,那么需要在 LXD_SERVER_A 上添加 remote server,把 LXD_SERVER_B 添加进来。
  • 如果是集群模型的 LXD Server,集群内部的成员之间的虚拟机实例,可以不受限制互相迁移。

LXD 的迁移指令是 move(mv),命令参数说明如下:

Description:
  Move instances within or in between LXD servers

  Transfer modes (--mode):
   - pull: Target server pulls the data from the source server (source must listen on network)
   - push: Source server pushes the data to the target server (target must listen on network)
   - relay: The CLI connects to both source and server and proxies the data (both source and target must listen on network)

  The pull transfer mode is the default as it is compatible with all LXD versions.

Usage:
  lxc move [<remote>:]<instance>[/<snapshot>] [<remote>:][<instance>[/<snapshot>]] [flags]

Aliases:
  move, mv

Examples:
  lxc move [<remote>:]<source instance> [<remote>:][<destination instance>] [--instance-only]
      Move an instance between two hosts, renaming it if destination name differs.

  lxc move <old name> <new name> [--instance-only]
      Rename a local instance.

  lxc move <instance>/<old snapshot name> <instance>/<new snapshot name>
      Rename a snapshot.

Flags:
      --allow-inconsistent   Ignore copy errors for volatile files
  -c, --config               Config key/value to apply to the target instance
  -d, --device               New key/value to apply to a specific device
      --instance-only        Move the instance without its snapshots
      --mode                 Transfer mode. One of pull, push or relay. (default "pull")
      --no-profiles          Unset all profiles on the target instance
  -p, --profile              Profile to apply to the target instance
      --stateless            Copy a stateful instance stateless
  -s, --storage              Storage pool name
      --target               Cluster member name
      --target-project       Copy to a project different from the source

可以看出,和虚拟机创建指令 launch 的大部分参数基本保持一致:

  • 可以通过 -p 参数指定迁移后的实例使用的虚拟机配置文件;
  • 可以通过 -s 参数指定迁移后的实例存储位置;
  • 可以通过 -c 参数指定迁移后的虚拟机配置参数。

提供以下的案例参考:
1. 把实例 u1 从 server_a 迁移到 server_b。

# 在 server_a 上执行指令
lxc move u1 server_b:u1

2. 把实例 u1 从 server_a 迁移到 server_b,放在 server_b 的存储池 ssd 上。

# 在 server_a 上执行指令
lxc move u1 server_b:u1 -s ssd

3. 把实例 u1 从 server_a 迁移到 server_b,使用虚拟机配置文件 default 和 k8s

# 在 server_a 上执行指令
lxc move u1 server_b:u1 -p default -p k8s

4. 把实例 u1 从 server_a 迁移到 server_b,迁移后设置CPU核心为1,内存大小为2GiB

# 在 server_a 上执行指令
lxc move u1 server_b:u1 -c limits.cpu=1 -c limits.memory=2GiB

3.6 启停实例

start、stop、restart 指令用于启动、停止、重启实例。例如:

root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
| u2   | STOPPED |                     |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
root@easyops:~# lxc start u2
root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
| u2   | RUNNING | 172.30.0.165 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+


root@easyops:~# lxc stop u2
root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
| u2   | STOPPED |                     |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+

stop、restart 指令可以指定 -f 参数来强制执行。

3.7 删除实例

LXD 虚拟机实例的删除指令是 delete,切记要谨慎使用,删除后的实例一般是无法恢复的。

参考案例:

root@easyops:~# lxc list 
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
| u2   | STOPPED |                     |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+
root@easyops:~# lxc delete u2
root@easyops:~# lxc list
+------+---------+---------------------+------+-----------+-----------+
| NAME |  STATE  |        IPV4         | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+---------------------+------+-----------+-----------+
| u1   | RUNNING | 172.30.0.221 (eth0) |      | CONTAINER | 1         |
+------+---------+---------------------+------+-----------+-----------+

注意:

  1. (再次强调)被删除的实例无法恢复;
  2. 实例需要在关机状态下才能被删除;
  3. 可以使用 -f 参数,无视虚拟机状态,执行强制删除。

三、结语

本文从虚拟机配置文件出发,详细讨论了虚拟机的配置管理与实例管理,LXD 提供的实例管理功能和主流的虚拟化平台基本一致。

值得一提的是,实例在创建后,依然可以对网卡、磁盘等设备进行调整,后续网络管理、存储管理的章节中再详细讨论。


Akito
0 声望3 粉丝