NiceLeeのBlog 用爱发电 bilibili~

备忘录 使用api操纵incus切割nat小机

2025-10-16
nIceLee

阅读:


本文尝试通过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",
      }
    }'

相似文章

内容
隐藏