LXC 是 Linux Container 的缩写,类似虚拟化技术中的 OpenVZ,是一种半虚拟化技术,可以提供一个和宿主机相对隔绝的沙盒环境。在容器中安装的各种软件不会影响到宿主机,同时也可以通过配置容器的资源限制,来保证容器中运行的软件不会占用过多资源。
前言
与 Docker 不同,LXC 和 OpenVZ 会保留用户操作的状态,而 Docker 则是提供一个无状态的预部署的容器,只有映射出来的文件才会得到保存。
许多优秀的管理面板提供了管理 LXC/OpenVZ 容器的功能,比如 Proxmox 等,但是由于管理面板的内存占用较高(纯净的 Debian9.4 镜像安装 Proxmox 后占用约 660MB 的内存),不适合小内存的机器,因此我选择 lxc 提供的使用命令行工具来对容器进行管理。
本文将主要包括如下内容:
- 创建 LXC 容器
- 限制 LXC 容器可用的资源(CPU,内存,磁盘等)
- 配置 LXC 容器的网络,且为 LXC 容器提供端口映射。
本文介绍的内容主要适用于如下两种情况:
- 内存较小的机器上无面板使用 lxc 虚拟化以节省内存消耗
- 面板出现 bug 时使用命令行工具排查错误
注:本文根据 Debian9.4 环境撰写,其余发行版那请自行调整相关命令。
LXC 的安装
对于比较新的 Debian 系统来说,安装 lxc 就是一句话
apt install lxc
网络配置
宿主机的网络配置
首先对宿主机进行网络配置,配置的目标是创建一个网桥及相关的 iptables 命令,实现 NAT 功能。
首先配置网桥,需要在网络配置文件(/etc/network/interfaces
)中添加如下内容即可
重要:记得检查你的网络接口是否为eth0,如果不是则需要修改配置文件的最后两行。
auto vmbr0
iface vmbr0 inet static
address 192.168.45.1
netmask 255.255.255.0
bridge_ports none
bridge_stp off
bridge_fd 0
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -A POSTROUTING -s '192.168.45.0/24' -o eth0 -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '192.168.45.0/24' -o eth0 -j MASQUERADE
其次配置 /etc/default/lxc-net
文件(没有的话创建一个)。
USE_LXC_BRIDGE="true"
LXC_BRIDGE="vmbr0"
LXC_ADDR="192.168.45.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="192.168.45.0/24"
LXC_DHCP_RANGE="192.168.45.150,192.168.45.200"
LXC_DHCP_MAX="51"
LXC_DHCP_CONFILE=""
LXC_DOMAIN=""
重启lxc-net
及网络服务。
systemctl restart lxc-net.service
systemctl restart networking.service
reboot # 或者直接重启系统
为容器配置NAT网络
首先修改配置文件让容器通过刚才创建的 NAT 网络连接互联网。
如果准备让所有的容器都使用该网络配置,可以修改默认的配置文件 /etc/lxc/default.conf
,如果只打算修改个别容器的配置,可以在 /var/lib/lxc/<容器名>/config
找到个别容器的配置文件。
## Network
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = vmbr0
## xx代表随机生成,每次重启都会有所变化
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
# 如果个别容器,可以指定 IP 地址及网关
lxc.network.ipv4 = 192.168.45.101/24
lxc.network.ipv4.gateway = 192.168.45.1
另外需要注意的是,部分容器模板是不包含任何 DNS 设定的,需要手动在容器内 /etc/resolv.conf
中指定 DNS 服务器:
nameserver 8.8.8.8
nameserver 8.8.4.4
创建容器
创建容器用的是 lxc-create
命令,最常见的创建方式包含两个参数:
# 使用 <template> 模板创建名为 <name> 的容器
lxc-create -t <template> -n <name>
如果你有提前编写完成的配置文件,可以通过 -f 参数指定
# 使用 <template> 模板及 <config_file> 配置文件,创建名为 <name> 的容器
lxc-create -t <template> -f <config_file> -n <name>
不同的模板拥有不同的参数,可以通过如下命令查询:
# 查看 <template> 模板的更多参数
lxc-create -t <template> -h
lxc-create
创建的容器需要通过 lxc-start -n <name>
启动。
自动启动需要在容器的配置文件里面加入指定参数:
lxc.start.auto = 1
配置容器
接下来要做的是修改容器的配置文件,LXC 容器的配置文件在 /var/lib/lxc/<容器名>/config
。
限制容器的 CPU 和内存占用
创建容器之后,默认容器可以使用全部的资源,需要修改容器的配置文件才能限制容器的资源使用。对配置文件的修改本质上是通过 cgroups 来限制容器的使用,具体的参数可以参考 cgroups 的参数。
Arch Wiki 提供了一个 cgroups 的详细介绍
一个典型的资源限制配置文件包含如下内容:
# 可使用内存量
lxc.cgroup.memory.limit_in_bytes = 512M
# 突发内存量 = 可用内存 + swap
# 该选项需对 grub 参数进行设置
# 可以参考 https://github.com/yudai/cf_nise_installer/issues/124
# 执行如下命令即可
# sudo echo "GRUB_CMDLINE_LINUX=\"cgroup_enable=memory swapaccount=1\"" >> /etc/default/grub
# sudo /usr/sbin/update-grub
lxc.cgroup.memory.memsw.limit_in_bytes = 1G
# CPU 核心数量
# 可以通过具体的数字精确指定占用的 CPU 核心编号
# 示例代表可以使用 1 2 3 4 号 CPU 核心。
lxc.cgroup.cpuset.cpus = 1,2-4
# CPU 资源占用比例
lxc.cgroup.cpu.shares = 1024
除了修改配置文件,也可以通过命令行直接指定 cgroup 参数,如:
# 仅允许名为 lxc_name 容器使用 CPU 的核心 1
lxc-cgroup -n lxc_name cpuset.cpus "1"
限制容器的磁盘大小
具体可以参考 man lxc-create
中 -B 参数的部分,在这里简单的提供一个命令对虚拟机进行限制。
注: loop 并不是最佳的参数,更好的方法是使用 lvm,但是这对磁盘分区有要求。
# 限制磁盘大小 5GB
lxc-create -n <name> -t <template> -B loop --fssize 5G
通过 iptables 进行端口转发
具体可以参考 这篇教程,只需要将转发的目标 IP 设置为容器的子网 IP 即可。
这里提供一个脚本来辅助设置端口转发。
# 保存为 nat.sh
#!/bin/bash
dev="ens3" # 修改成网络接口的名字
user_ip="192.168.45.$1"
# iptables -t nat -A POSTROUTING -d ${user_ip} -j SNAT --to-source ${main_ip}
iptables -t nat -A PREROUTING -i $dev -p tcp -m tcp --dport ${1}22 -j DNAT --to-destination ${user_ip}:22
iptables -t nat -A PREROUTING -i $dev -p tcp -m tcp --dport ${1}00:${1}20 -j DNAT --to-destination ${user_ip}
iptables -t nat -A PREROUTING -i $dev -p udp -m udp --dport ${1}00:${1}20 -j DNAT --to-destination ${user_ip}
echo -e "done."
使用脚本时需要根据上文中提到的内容对脚本进行微调,
bash nat.sh 101
未曾修改脚本的情况下,这个命令代表将 192.168.45.101 的 22 端口转发到主机的 10122 端口,并把 192.168.45.101 的 10100~10120 端口转发到主机的 10100~10120 端口。
配置完成后可以通过 ssh <宿主机IP> -p 10122
来访问容器的22端口。
注:容器需处于启动状态,且安装 openssh-server 并监听 22 端口。
LXC 常用命令
# 创建容器
lxc-create -t <template> -n <name>
# 启动容器
lxc-start -n <name>
# 停止容器
lxc-stop -n <name>
# 进入容器
lxc-attach -n <name>
# 查看所有容器,可通过参数指定只查看特定状态的容器
lxc-ls
# 查看容器信息
lxc-info -n <name>
# 查看容器中的进程
lxc-ps -n <name>
一个用于创建 LXC 容器的 Python 脚本
TODO
楼主残忍的关闭了评论