本文尝试通过api的方式,操作incus创建指定配置的nat lxc小机。
在Debian系统上进行操作实践。
- 创建/销毁实例
- 开关机
- 分配转发端口
- 内存、核心、存储限制等
incus安装和配置
安装incus
apt install incus
如果出现以下问题(Debian12):
root@ohmy:~# apt install incus
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
incus : Depends: qemu-system-x86 (>= 1:8.0) but 1:7.2+dfsg-7+deb12u16 is to be installed
E: Unable to correct problems, you have held broken packages.
root@ohmy:~#
编辑/etc/apt/sources.list
,添加行
deb http://deb.debian.org/debian bookworm-backports main contrib non-free
然后重新尝试安装
apt update
apt install -t bookworm-backports qemu-system-x86
apt install incus
安装web管理界面(可跳)
wget -q -O - https://pkgs.zabbly.com/key.asc | gpg --show-keys --fingerprint
mkdir -p /etc/apt/keyrings/
wget -O /etc/apt/keyrings/zabbly.asc https://pkgs.zabbly.com/key.asc
apt install -y incus-ui-canonical
安装btrfs-progs(限制存储)
apt install -y btrfs-progs
初始化incus
incus admin init
基本上都是默认,非默认的情况有注解
root@ohmy:~# incus admin init
Would you like to use 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]:
Name of the storage backend to use (btrfs, dir) [default=btrfs]: # dir无法限制实例的存储大小
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GiB of the new loop device (1GiB minimum) [default=5GiB]: 10GiB
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=incusbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 192.168.1.1/24 # 自己控制子网段,有个预期比较好分配
Would you like to NAT IPv4 traffic on your bridge? [default=yes]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none # 不分配ipv6
Would you like the server 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 "init" preseed to be printed? (yes/no) [default=no]: yes
config:
images.auto_update_interval: "0"
networks:
- config:
ipv4.address: 192.168.1.1/24
ipv4.nat: "true"
ipv6.address: none
description: ""
name: incusbr0
type: ""
project: default
storage_pools:
- config:
size: 10GiB
description: ""
name: default
driver: btrfs
storage_volumes: []
profiles:
- config: {}
description: ""
devices:
eth0:
name: eth0
network: incusbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
project: default
projects: []
cluster: null
自定义自己的Debian12镜像
拉取Debian12镜像
因为需要cloud-init
,所以拉的是images:debian/12/cloud
,而不是images:debian/12
incus launch images:debian/12/cloud raw
对镜像进行自定义
进入raw镜像
incus exec raw -- bash
安装ssh
apt-get update
apt install -y openssh-server
systemctl enable ssh
systemctl start ssh
systemctl status ssh
配置ssh
nano /etc/ssh/sshd_config
确保以下设置:
PermitRootLogin yes
PasswordAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
收尾
mkdir -p /root/.ssh
echo "" >> /root/.ssh/authorized_keys
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
apt clean
rm -rf /var/lib/apt/lists/*
退出
exit
停止raw镜像,重新发布为debian12
incus stop raw
incus publish raw --alias debian12 --reuse
配置外网访问
理论上可以客户端配个证书,然后进行访问。但是我想转化为验证cookie或者其它header的方式。
假设nginx已经安装。
# 设置 incus只能本地8443端口访问
incus config set core.https_address 127.0.0.1:8443
# 创建证书
openssl req -x509 -newkey rsa:4096 -keyout client.key -out client.crt -days 3650 -nodes -subj "/CN=myincus"
# 信任证书
incus config trust add-certificate client.crt
# incus config trust list
# 证书挪到指定位置
mkdir -p /etc/nginx/certs
cp client.crt /etc/nginx/certs/nginx-client.crt
cp client.key /etc/nginx/certs/nginx-client.key
chmod 600 /etc/nginx/certs/nginx-client.key
mkdir -p /etc/nginx/sites-available
编辑 Nginx 配置文件 /etc/nginx/sites-available/incus.conf
,内容示范:
只有Cookie的aaa
值为12345677654321
才能正常访问。
访问路径/woshidashagua
可以将Cookie的aaa
值设为12345677654321
。
server {
listen 443 ssl;
server_name incus.example.com;
ssl_certificate $NixopsCert; # 你的证书路径
ssl_certificate_key $NixopsKey; # 你的私钥路径
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
location / {
if ( $cookie_aaa != "12345677654321"){
return 404;
}
proxy_pass https://127.0.0.1:8443;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 如果是web管理界面,需要websocket支持
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 使用客户端证书和私钥认证 Incus API
proxy_ssl_certificate /etc/nginx/certs/nginx-client.crt;
proxy_ssl_certificate_key /etc/nginx/certs/nginx-client.key;
# 不验证 Incus API 的自签名证书(如果有)
proxy_ssl_verify off;
}
location = /woshidashagua {
add_header Set-Cookie 'aaa=12345677654321; domain=$host; path=/';
return 302 /;
}
}
启用站点并重启 Nginx
ln -s /etc/nginx/sites-available/incus.conf /etc/nginx/sites-enabled/
nginx -s reload
相关API操作
实例创建
实例名称nb2
,OS镜像Debian12
,配置1c256M2GB
,时区Asia/Shanghai
。
用户名root
,密码kkUkO.4RtYyx
。
内网ip192.168.1.2
,外网ip1.2.3.4
。
内网22端口对应外网59122,内外网59123-59127一一对应。
实例创建后自动开机。
curl -k -X POST https://incus.example.com/1.0/instances \
-H "Content-Type: application/json" \
-H "Cookie: aaa=12345677654321" \
-d '{
"name": "nb2",
"start": true,
"architecture": "x86_64",
"profiles": [
"default"
],
"source": {
"type": "image",
"alias": "debian12"
},
"config": {
"limits.cpu": "1",
"limits.cpu.priority": "0",
"limits.cpu.allowance": "50%",
"limits.memory": "256MB",
"boot.autostart": "true",
"user.user-data": "#cloud-config\ntimezone: Asia/Shanghai\nchpasswd:\n list: |\n root:kkUkO.4RtYyx\n expire: False\nssh_pwauth: True\nusers:\n - name: root\n lock_passwd: False\n"
},
"devices": {
"root": {
"path": "/",
"pool": "default",
"size": "2GB",
"limits.max": "2GB",
"limits.read": "5000iops",
"limits.write": "5000iops",
"type": "disk"
},
"eth0": {
"ipv4.address": "192.168.1.2",
"limits.egress": "500Mbit",
"limits.ingress": "500Mbit",
"limits.max": "500Mbit",
"mtu": "1500",
"nictype": "bridged",
"parent": "incusbr0",
"type": "nic"
},
"proxy-ssh": {
"bind": "host",
"connect": "tcp:192.168.1.2:22",
"listen": "tcp:1.2.3.4:59122",
"nat": "true",
"type": "proxy"
},
"proxy-1": {
"bind": "host",
"connect": "tcp:192.168.1.2:59123-59127",
"listen": "tcp:1.2.3.4:59123-59127",
"nat": "true",
"type": "proxy"
}
}
}'
实例开关机
假设实例名称nb2
curl -k -X PUT https://incus.example.com/1.0/instances/nb2/state --data '{"action":"start"}' #开机
curl -k -X PUT https://incus.example.com/1.0/instances/nb2/state --data '{"action":"stop"}' #关机
实例删除
假设实例名称nb2
curl -k -X DELETE /1.0/instances/nb2 #删机
实例的其它操作
举个例子,假设实例名称nb2
(已关机),将内存变为128MB
:
curl -k -X PATCH https://incus.example.com/1.0/instances/nb2 \
-H "Content-Type: application/json" \
-d '{
"config": {
"limits.memory": "128MB",
}
}'