Ubuntu LXC

创建 LXC 容器

安装 LXC
sudo apt install lxc -y
lxc-create 看呒的语法
lxc-create --help
lxc-create --name=NAME --template=TEMPLATE [OPTION...]
Options :
  -n, --name=NAME               NAME of the container
  -t, --template=TEMPLATE       Template to use to setup container

实在是看不懂,只好上网找,消化一下整理并简化。

lxc-create 消化后的语法
lxc-create -t download -n $lxcname -- -d ubuntu -r $release -a amd64
-t download 缓存文件夹 (1)
--name (新建的) 容器名称 $lxcname (2)
--dist 操作系统 ubuntu
--release 操作系统版本 (release) (3)
--arch 指定架构 amd64。
1 下载的 lxc 保存在 /var/cache/lxc/download
2 容器文件会放在 /var/lib/lxc/$lxcname
3 $release 是什么? 这里的参数 bionic 是 ub18,xenial 是 ub16,那其他版本呢? Releases - Ubuntu Wiki
Version     Code name       $releae
Ubuntu 20   Focal Fossa     focal
Ubuntu 18   Bionic Beaver   bionic
Ubuntu 16   Xenial Xerus    xenial
Ubuntu 14   Trusty Tahr     trusty

先别急着创建容器,建议您看一下 设置 LXC 采用 br0 桥接网络

创建 base18 容器
# 容器命名为 base18, 先创建基本容器, 安装基本功能后再拷贝至新容器
lxcname=base18
sudo lxc-create -t download -n $lxcname -- -d ubuntu -r bionic -a amd64 (1)
1 若出现下列错误,等一段时间再试一次。
ERROR: Unable to fetch GPG key from keyserver.
启动容器
lxcname=base18

# 启动容器
sudo lxc-start -n $lxcname (1)

# 登录容器,帐户为 root 帐户
sudo lxc-attach -n $lxcname

# 设置 root 帐户密码
passwd

# 设置 ubuntu 帐户密码 (已有 ubuntu 及 www-data 帐户)
# ubuntu 帐户密码默认值为 ubuntu
passwd ubuntu

# 采用 dist-upgrade 更新
apt update && apt dist-upgrade -y

# lxc 可安装常用套件 nano
apt install nano -y

# 可接续安装其他套件或调整 (2)

# 离开容器
exit
1 依据版本不同可能不需要 -n 参数,如 sudo lxc-start $lxcname
2 可依据 Ubuntu 安装手册 安装必要套件。

LXC 设置

LXC 全局设置 /etc/default/lxc-net
USE_LXC_BRIDGE="true"(1)
1 "true" 表示激活 lxcbr0 (LXC 内置的 NAT) 接口,"false" 则为取消。
编辑容器组态
lxcname=base18
nano /var/lib/lxc/$lxcname/config
/var/lib/lxc/$lxcname/config
# 可加入 LXC 自动开机
lxc.start.auto = 1

# Container specific configuration
lxc.uts.name = base18 (1)

# Network configuration
# Ubuntu 18
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0 (2)
# lxc.net.0.link = br0 (3)
# lxc.net.0.ipv4 = 192.168.1.102/24 (4)
# lxc.net.0.ipv4.gateway = 192.168.1.254

# Ubuntu 16
lxc.network.type = veth
lxc.network.link = lxcbr0 (2)
# lxc.network.link = br0 (3)
# lxc.network.ipv4 = 192.168.1.102/24 (4)
# lxc.network.ipv4.gateway = 192.168.1.254
1 指定容器的名称,一般会指定成容器目录名称,但该值似乎无作用。
2 lxcbr0:LXC 缺省的 NAT 网络接口。
3 自行创建的 br0 桥接网络接口。
4 如果容器采用固定 IP 按实际修改。

前续的步骤完成,再拷贝 LXC 容器。

lxcname=base18
newlxc=new18
lxc-stop -n $lxcname

# lxc-copy [-n] <container-name> -N <new-container-name>
lxc-copy -n $lxcname -N $newlxc (1)
1 $newlxc 是 容器名称容器主机名称 没有关系,记得要去改新容器内的主机名称。

LXC 常用指令

#检查版本
lxc-info --version

# 判断 linux 内核是否支持 LXC
lxc-checkconfig

lxc-ls --help

# 列出容器
lxc-ls -f

lxcname=base18

# 修改组态
nano /var/lib/lxc/$lxcname/config

# 启动容器
lxc-start -n $lxcname
# 注: 在旧版的 lxc 需要前置 -n,如 lxc-start -n $lxcname

# 停止容器
lxc-stop -n $lxcname

# 登录容器,帐户为 root 帐户
lxc-attac -n $lxcname

# 登录容器 (需要输入用户名和密码)
lxc-console -n $lxcname

# 检查占用多少内存及其他状态
lxc-info -n $lxcname

# 拷贝容器
# lxc-copy [-n] <container-name> -N <new-container-name>
lxc-stop -n $lxcname
lxc-copy -n $lxcname -N <new-container-name>

# 删除容器
lxc-destroy -n <container-name>

设置 LXC 采用 br0 桥接网络

LXC 在缺省的情况下采用 NAT 的方式,容器只能被 Host 访问,如果其他主机要能访问,Host 必须采用桥接网卡(br0)。

先完成下列,再取消 LXC 缺省 NAT 桥接。

/etc/default/lxc-net
# USE_LXC_BRIDGE="true"
USE_LXC_BRIDGE="false"(1)
1 取消 LXC 的桥接。

修改 LXC 创建容器的默认值,将网络接口指向桥接接口。

/etc/lxc/default.conf
lxc.net.0.type = veth
#lxc.net.0.link = lxcbr0
lxc.net.0.link = br0(1)

lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx
1 LXC 的网络接口指向桥接 br0 接口

调整容器组态,文件在 Host 主机上

/var/lib/lxc/$lxcname/config
# Network configuration
lxc.net.0.type = veth
# lxc.net.0.link = lxcbr0
lxc.net.0.link = br0(1)

lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:77:ee:2c

# lxc.net.0.ipv4 = 192.168.1.102/24(2)
# lxc.net.0.ipv4.gateway = 192.168.1.254

lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:77:ee:2c
1 LXC 的网络接口指向桥接 br0 接口
2 如果容器采用固定 IP 按实际修改。

LXC 容器桥接测试

进入容器,检查一下位置是否为 LAN (别忘了,如果是在设置之前已启动容器,应该重启它)

lxcname=base18
lxc-start -n $lxcname
lxc-attach -n $lxcname
ifconfig (1)
ip a
ip -c a
1 出错 bash: ifconfig: command not found,可参考: command line - ifconfig missing after Ubuntu 18.04 install - Ask Ubuntu , 改用 ip 吧!如果要用 ifconfig,则安装 sudo apt install net-tools,或者查看 sudo apt-cache search ifconfig 看是要装那一个。

LXC 容器备份

容器以 tar 压缩或解压缩只有一个重点,采用 --numeric-owner 保留容器文件权限。

关于 --numeric-owner

LXC 容器文件的 uid/gid (User Identifier/Group Identifier) 为容器专属, 但运行 tar 的 Host 系统会尝试解析容器文件的 uid/gid,解决文件拥有权问题。 采用 --numeric-owner 保留容器文件的 uid/gid, 不要让 Host 去做一些跟自己毫无关系的解析动作,若将其解析为其他值则会发生不良情况。

参考: ubuntu - How do I Backup / Move LXC containers? - Stack Overflow

The --numeric-owner flag is very important! Without it, the container may not boot because the uid/gids get mangled in the extracted file system.

容器备份及发送

停止容器
lxcname=base18
cd /var/lib/lxc/$lxcname
lxc-stop -n $lxcname
压缩时直接在共享目录创建 tar 文件 (Windows shared folder)
tar --numeric-owner -czvf /mnt/share/$lxcname.tar.gz ./*
压缩时直接将压缩档以 ssh 发送至目标主机
# 切换目录至来源容器
# cd /var/lib/lxc/$lxcname

# 设置目标主机的 root 帐户及主机位置
UserHost='root@192.168.1.1'

# LXC 的容器名称,这时要决定。
# 先检查目标主机
ssh $UserHost ls /var/lib/lxc/
# 新容器名称
newlxc=base18

# 创建目标主机文件夹
ssh $UserHost mkdir /var/lib/lxc/$newlxc
tar --numeric-owner -czvf - ./* | ssh $UserHost "cat > /var/lib/lxc/$newlxc/clone.tar.gz"
目标主机解压
# ssh $UserHost

newlxc=base18

# 直接解压 Windows shared folder 内的 tar
mkdir /var/lib/lxc/$newlxc/
cd /var/lib/lxc/$newlxc/
tar --numeric-owner -xzvf /mnt/share/base18.tar.gz .

# 目标主机已有, 直接解压即可
cd /var/lib/lxc/$newlxc/
tar --numeric-owner -xzvf clone.tar.gz .
调整目标主机内容器名称
newlxc=base18

# 若需要产生 MAC
OID="00:16:3e"
RAND=$(echo $newlxc | md5sum | sed 's/\(..\)\(..\)\(..\).*/\1:\2:\3/')
echo "$OID:$RAND"

# 修改容器组态
nano /var/lib/lxc/$newlxc/config

# 启动容器
lxc-start -n $newlxc
lxc-attach -n $newlxc

# 修改容器内的主机名称
nano /etc/hostname
nano /etc/hosts

# 离开容器
exit

# 重启容器, 以便更新容器入的主机名称
lxc-stop -n $newlxc
lxc-start -n $newlxc