安装incus部署lxc容器
目录
这篇文章介绍了如何安装incus
注意
注1、本人使用的系统为debian13
1 安装incus
1.1 命令安装incus
sudo apt install incus-base
安装btrfs
sudo apt install btrfs-progs
1.2 配置incus
初始化incus,全部默认下一步即可
incus admin init
检查内核转发是否已开启 (1 为开启)
sysctl net.ipv4.ip_forward
创建一个alpine容器
incus launch images:alpine/edge alpine01
进入容器 (Shell)
incus shell alpine01
其他incus命令
查看所有容器状态 incus list
停止容器 incus stop my-debian
启动已有的容器 incus start my-debian
删除容器(需先停止) incus delete my-debian
查看容器详细信息 incus info my-debian
1.3 配置容器静态ipv4
查看网桥网段
incus network show incusbr0
配置静态IP,重启生效
# 语法:incus config device set <容器名> <网卡名> ipv4.address <静态IP>
incus config device set alpine01 eth0 ipv4.address 10.1.168.165
incus config device override alpine01 eth0 ipv4.address=10.1.168.165 # 首次使用解绑模板eth0
1.4 关闭Incus防火墙
incus network set incusbr0 ipv4.firewall false
incus network set incusbr0 ipv6.firewall false
1.5 配置端口转发
编辑配置文件
sudo nano /etc/nftables.conf
放置如下内容
#!/usr/sbin/nft -f
# 清除旧规则
flush ruleset
# 定义变量
define WAN_IF = "ens18" # !!!请根据实际情况修改此网卡名!!!
define BRIDGE_IF = "incusbr0" # Incus 默认网桥名
# ==========================================
# 1. 过滤表:负责安全性(谁能进,谁能过)
# ==========================================
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
# 允许本地回环
iif "lo" accept
# 允许已建立和关联的连接 (回包)
ct state established,related accept
# 允许 Ping (可选)
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# 允许管理服务:宿主机 SSH 。相当于宿主机防火墙
tcp dport 22 accept
tcp dport 80 accept
# 兼容 Incus:允许容器获取 IP (DHCP) 和请求 DNS
iifname $BRIDGE_IF udp dport { 53, 67 } accept
iifname $BRIDGE_IF tcp dport { 53, 67 } accept
}
chain forward {
type filter hook forward priority filter; policy drop;
# 允许已建立和关联的连接
ct state established,related accept
# 允许容器访问外部网络
iifname $BRIDGE_IF oifname $WAN_IF accept
# 允许容器之间互相通信
iifname $BRIDGE_IF oifname $BRIDGE_IF accept
# 【核心安全规则】
# 自动放行在 NAT 表中命中转发规则的所有流量 (含 TCP 和 UDP)
ct status dnat accept
}
chain output {
type filter hook output priority filter; policy accept;
}
}
# ==========================================
# 2. NAT表:负责转发逻辑(改写目标地址)
# ==========================================
table ip nat {
# 端口转发映射映射表
# 结构: [ 协议 . 外部端口 ] : [ 内部IP . 内部端口 ]
map port_forward_map {
type inet_proto . inet_service : ipv4_addr . inet_service
elements = {
tcp . 56256 : 10.239.122.103 . 22,
tcp . 8080 : 10.239.122.42 . 80,
udp . 8080 : 10.239.122.42 . 80,
udp . 51820 : 10.239.122.43 . 51820
}
}
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
# 核心转发指令:基于协议和端口自动查找 Map 并执行 DNAT
dnat ip addr . port to meta l4proto . th dport map @port_forward_map
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# 伪装出口流量,让容器能上网
oifname $WAN_IF masquerade
}
}
验证文件
sudo nft -c -f /etc/nftables.conf
应用配置
sudo nft -f /etc/nftables.conf
进入容器 (Shell)
incus shell alpine01
命令行临时添加,重启后失效
# 同时增加一条 TCP 转发
sudo nft add element ip nat port_forward_map { tcp . 7777 : 10.239.122.41 . 7777 }
# 同时增加一条 UDP 转发
sudo nft add element ip nat port_forward_map { udp . 7777 : 10.239.122.41 . 7777 }
自动保存当前运行的规则。如果你通过命令行临时添加了很多规则,懒得再去手动改文件,可以直接把内存中运行的“完美状态”覆盖到配置文件里:
sudo sh -c "nft list ruleset > /etc/nftables.conf"
注意:这会把文件顶部的#!/usr/sbin/nft -f等注释删掉,但规则是完整的。
2 打包lxc镜像
2.1 手动打包镜像
安装debootstrap
sudo apt install debootstrap tar xz-utils
创建一个干净的工作目录
mkdir -p ~/incus-build/rootfs
cd ~/incus-build
构建Rootfs根文件系统
sudo debootstrap --variant=minbase --arch=amd64 bookworm ./rootfs http://mirrors.tuna.tsinghua.edu.cn/debian/
现在的 rootfs 目录只是的一堆死文件,我们需要进入内部进行配置,否则容器启动会报错或无法联网。
sudo chroot ./rootfs /bin/bash
设置 PATH 环境变量
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
配置网络(Incus 依赖 DHCP,必须配置)
# 安装网络工具和 SSH
apt-get update
apt-get install -y iproute2 iputils-ping curl openssh-server
# 配置网卡自动获取 IP (systemd-networkd 方式)
mkdir -p /etc/systemd/network
cat <<EOF > /etc/systemd/network/eth0.network
[Match]
Name=eth0
[Network]
DHCP=yes
EOF
# 启用网络服务
systemctl enable systemd-networkd
设置 root 密码(否则你进不去)
echo "root:password" | chpasswd
允许 root 登录 SSH
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
清理垃圾并退出
apt-get clean
rm -rf /var/lib/apt/lists/*
exit
编写元数据 (Metadata)模板
#在工作目录下创建模板文件夹
mkdir templates
配置自动主机名 (Hostname)
#在工作目录下创建模板文件夹
cd templates
nano hostname.tpl
文件内容
{{ container.name }}
编写/etc/hosts模板 (templates/hosts.tpl)
nano hosts.tpl
文件内容
127.0.0.1 localhost
127.0.1.1 {{ container.name }}
# The following lines are desirable for IPv6 capable hosts
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
工作目录下创建 metadata.yaml
cat <<EOF > metadata.yaml
architecture: "x86_64"
creation_date: $(date +%s)
properties:
description: "My Scratch Debian 12"
os: "debian"
release: "bookworm"
EOF
配置 metadata.yaml
architecture: "x86_64"
creation_date: 1706870400
properties:
description: "Debian with Auto-Hostname"
os: "debian"
release: "bookworm"
# 核心配置在这里
templates:
# 1. 目标文件在容器内的绝对路径
/etc/hostname:
# 什么时候触发替换?(create=创建时, copy=从快照恢复时, start=每次启动时)
when:
- create
- copy
# 使用哪个模板文件?(相对于 metadata 压缩包内的 templates/ 目录)
template: hostname.tpl
# 2. 配置 hosts 文件
/etc/hosts:
when:
- create
- copy
template: hosts.tpl
打包 Metadata
tar -cJvf ./metadata.tar.xz metadata.yaml templates/
打包 Rootfs: 关键点: 必须进入 rootfs 目录内部打包,且使用 –numeric-owner 保持 UID/GID 为数字,防止跨系统用户映射错误
cd rootfs
sudo tar --numeric-owner -cJvf ../rootfs.tar.xz .
cd ..
导入并测试
# 导入镜像
incus image import metadata.tar.xz rootfs.tar.xz --alias debian-sid
# 启动容器测试
incus launch debian-sid debian01
# 查看是否运行
incus list
# 进入容器
incus shell debian01