issue #47 的 backend 评估已经验证:privileged PVE LXC 中可以运行 k3s、Kata Containers 与 Cloud Hypervisor;Kata 4.1.0 的 clh-runtime-rs 实际报告 memory.shared=true,guest 写入 1 GiB 时只增加一次 shared memory charge,没有重现 早期 private memfd 的 anon + shmem 双重记账。
clh-runtime-rs
memory.shared=true
anon + shmem
下一步需要把 PoC 收敛成独立的正式 sandbox 集群,供 OpenSandbox、CI 和后续 AI Agent workload 使用。正式环境不得依赖手工登录配置;所有持久状态必须能由 Ansible 与 Flux 从仓库重建,并能够检测实际节点状态与声明状态的偏差。
pve-rg-hdd
/dev/kvm
k3s-io/k3s-ansible
0600
site.yml
verify.yml
kata-clh-runtime-rs
ci-pod
ci-vm
dependsOn
infrastructure/sandbox-cluster/ README.md ansible/ requirements.yml inventory/ site.yml verify.yml roles/ clusters/sandbox/ flux-system/ infrastructure/kata/ infrastructure/spire-agent/ infrastructure/monitoring/ infrastructure/opensandbox-operator/ workloads/opensandbox/
现有 infrastructure/kata-lxc-lab 只保留为历史 PoC 和已验证陷阱记录,不作为正式 环境的部署入口。
infrastructure/kata-lxc-lab
vm.info.config.memory.shared=true
extensions.poolRef
CHANGELOG.md
关联:#47、#34。
补充 2026-09-17 Kata block-backed CI storage PoC 结果:
[runtime] emptydir_mode = "block-plain"
/var/lib/docker
/dev/vdb
overlay2
fuse-overlayfs
disk.img
mknod /dev/kmsg c 1 11
/dev/kmsg
emptyDir.sizeLimit: 8Gi
结论:Kata 不再因 virtio-fs/overlay2 问题直接淘汰。#83 的 ci-vm 应使用独立的 block-plain RuntimeClass,并把 overlay2、kind、backing-file 回收及性能阈值纳入 上线验收;不能使用默认 shared-fs RuntimeClass 承载镜像构建。
block-plain
shared-fs
完整数据已写入 infrastructure/kata-lxc-lab/README.md。
infrastructure/kata-lxc-lab/README.md
设计修订(2026-09-17):正式 sandbox 集群取消独立 /var/lib/kubelet volume。PoC 确认 block-plain 的 disk.img 容量取决于承载目录文件系统、且 emptyDir.sizeLimit 不可靠,但单独 kubelet volume 会额外引入 DRBD volume、LXC mount 和清理生命周期,同时不能隔离 containerd 等其他节点数据。正式节点统一使用 pve-rg-hdd 上的 32 GiB rootfs;容量安全改由节点磁盘监控、Pod 删除后的 backing-file/VMM 回收检查及构建基准验收保证。该修订取代正文及前一条 PoC 评论中“正式节点必须使用独立 kubelet volume”的结论。当前两台 LXC 已完成迁移,后端实际容量、PVE 配置和容器内 ext4 均为 32 GiB,旧 volume 已删除。
/var/lib/kubelet
emptyDir.sizeLimit
数据库入口决策(2026-09-17):首期不部署 PgBouncer、Patroni、repmgr 或额外 DCS。PostgreSQL 使用 primary + synchronous standby,不宣称自动 HA;由 Ansible runbook 执行隔离旧 primary、提升 standby、切换入口和 failback。K3s datastore 使用 VyOS 上的固定 TCP LB 入口,LB 仅指向当前已声明 primary,不依据 TCP/pgsql 存活检查自动把写流量切到 standby。优先复用 labnet gateway 10.60.0.1:5432,避免新增 VIP;最终配置以 VyOS 当前版本支持的原生语法验证结果为准。
2026-09-17 正式 Kata 阶段验收结果:
发现一个独立架构缺口:普通 SPIFFE CSI volume 在 Kata guest 内只能看到 spire-agent.sock 路径,实际连接返回 connection refused,因为现有 CSI driver 是 host Unix socket 目录 bind mount,socket RPC 不能跨 VM/virtiofs 边界。两台节点结果一致。该问题已拆为 #94,不将 Kata guest SPIFFE 误记为通过。
另发现 root Kustomization timeout=3m 小于 Kata 首装约 6m,导致一次暂态 False;子 Kustomization/HelmRelease 实际成功,下一轮 root 已恢复 True。持久修复见 PR #93。
No dependencies set.
The note is not visible to the blocked user.
背景
issue #47 的 backend 评估已经验证:privileged PVE LXC 中可以运行 k3s、Kata
Containers 与 Cloud Hypervisor;Kata 4.1.0 的
clh-runtime-rs实际报告memory.shared=true,guest 写入 1 GiB 时只增加一次 shared memory charge,没有重现早期 private memfd 的
anon + shmem双重记账。下一步需要把 PoC 收敛成独立的正式 sandbox 集群,供 OpenSandbox、CI 和后续 AI
Agent workload 使用。正式环境不得依赖手工登录配置;所有持久状态必须能由 Ansible
与 Flux 从仓库重建,并能够检测实际节点状态与声明状态的偏差。
所有权边界
Ansible
LXC。
pve-rg-hddrootfs、CPU、内存、swap、/dev/kvm、vhost、TUN、kmsg、AppArmor、capability、cgroup 与 mount 配置。k3s-io/k3s-ansiblecollection 安装和升级 K3s;配置文件权限使用
0600。site.yml与只读verify.yml;普通重复执行不得产生变化。Flux
kata-clh-runtime-rsRuntimeClass。声明。
ci-pod与ci-vmPools、API Service/Gateway。dependsOn明确顺序;Kata 不能作为 OpenSandbox chart 的隐式依赖。
目录目标
现有
infrastructure/kata-lxc-lab只保留为历史 PoC 和已验证陷阱记录,不作为正式环境的部署入口。
集群与数据库
runbook;不能仅安装 streaming replication 就宣称自动 HA。
SPIFFE/SPIRE
Server 必须提供 sandbox 节点可访问的地址。
ci-pod和ci-vmworkload 必须取得自己的 SPIFFE identity,不得共享 OpenSandboxServer 或外层 runner 的身份。
SPIFFE ID。
监控
remote write。
PostgreSQL/复制延迟、SPIRE Agent/SVID、Kata、OpenSandbox API/Pool 与 LXC
memory/swap/PSI/OOM。
签发失败、sandbox 创建失败/超时、Pool 耗尽、memory pressure/OOM 建立告警。
vm.info.config.memory.shared=true。部署顺序
memory.shared=true。验收标准
site.yml和等待 Flux reconciliation 即可恢复环境。通过测试触发。
extensions.poolRef选择ci-pod或ci-vm;Pool 可配置零预热并按需创建。credential 或临时数据。
运维原则
CHANGELOG.md保持冻结;持久状态和 runbook 写入对应 README。关联:#47、#34。
补充 2026-09-17 Kata block-backed CI storage PoC 结果:
clh-runtime-rs设置[runtime] emptydir_mode = "block-plain"后,/var/lib/docker是 guest/dev/vdb上的 ext4,Docker 29.1.5 可使用原生overlay2,不再依赖fuse-overlayfs。disk.img热插拔为 blockdevice,host/LXC 没有使用 loop device。
runc 对照 34 秒,Kata 约慢 35%。
(50.3 MB/s);一万个小文件两者均约 2 秒。
guest 内执行
mknod /dev/kmsg c 1 11,否则 kind node kubelet 因缺少/dev/kmsg退出。修复后 kind 总创建时间 122 秒,等待阶段 23 秒 Ready。emptyDir.sizeLimit: 8Gi没有决定 block image 容量;12 GiB LXC rootfs 产生约12 GiB 稀疏 image。这是 Kata 已知限制,正式节点必须给 kubelet volume 目录使用
独立且容量受控的文件系统。
disk.img、VMM 和 kind 容器全部回收,无 loop device 或 OOM 残留。结论:Kata 不再因 virtio-fs/overlay2 问题直接淘汰。#83 的
ci-vm应使用独立的block-plainRuntimeClass,并把 overlay2、kind、backing-file 回收及性能阈值纳入上线验收;不能使用默认
shared-fsRuntimeClass 承载镜像构建。完整数据已写入
infrastructure/kata-lxc-lab/README.md。设计修订(2026-09-17):正式 sandbox 集群取消独立
/var/lib/kubeletvolume。PoC 确认block-plain的disk.img容量取决于承载目录文件系统、且emptyDir.sizeLimit不可靠,但单独 kubelet volume 会额外引入 DRBD volume、LXC mount 和清理生命周期,同时不能隔离 containerd 等其他节点数据。正式节点统一使用pve-rg-hdd上的 32 GiB rootfs;容量安全改由节点磁盘监控、Pod 删除后的 backing-file/VMM 回收检查及构建基准验收保证。该修订取代正文及前一条 PoC 评论中“正式节点必须使用独立 kubelet volume”的结论。当前两台 LXC 已完成迁移,后端实际容量、PVE 配置和容器内 ext4 均为 32 GiB,旧 volume 已删除。数据库入口决策(2026-09-17):首期不部署 PgBouncer、Patroni、repmgr 或额外 DCS。PostgreSQL 使用 primary + synchronous standby,不宣称自动 HA;由 Ansible runbook 执行隔离旧 primary、提升 standby、切换入口和 failback。K3s datastore 使用 VyOS 上的固定 TCP LB 入口,LB 仅指向当前已声明 primary,不依据 TCP/pgsql 存活检查自动把写流量切到 standby。优先复用 labnet gateway 10.60.0.1:5432,避免新增 VIP;最终配置以 VyOS 当前版本支持的原生语法验证结果为准。
2026-09-17 正式 Kata 阶段验收结果:
发现一个独立架构缺口:普通 SPIFFE CSI volume 在 Kata guest 内只能看到 spire-agent.sock 路径,实际连接返回 connection refused,因为现有 CSI driver 是 host Unix socket 目录 bind mount,socket RPC 不能跨 VM/virtiofs 边界。两台节点结果一致。该问题已拆为 #94,不将 Kata guest SPIFFE 误记为通过。
另发现 root Kustomization timeout=3m 小于 Kata 首装约 6m,导致一次暂态 False;子 Kustomization/HelmRelease 实际成功,下一轮 root 已恢复 True。持久修复见 PR #93。