Helm 安装
在现有 K8s 集群上完成 CubeSandbox 的 Helm 安装。
安装流程
① 集群就绪
↓
② 给节点打标签(以及角色污点)
↓
③ 准备 values 配置
↓
④ helm upgrade --install
↓
⑤ 验证1. 前置条件
| 项目 | 要求 |
|---|---|
| Kubernetes | ≥ v1.24+ |
| 工具 | kubectl、Helm v3.10+ |
| 存储 | 集群有可用 StorageClass |
| 镜像拉取 | 节点能联网拉取镜像 |
节点角色
CubeSandbox 用 标签 区分两类节点:
| 角色 | 建议规格 | 用途 |
|---|---|---|
| 控制面节点 | ≥ 1 台;生产建议 3+;≥ 4C8G | 跑Cube的控制面组件 |
| 计算节点 | ≥ 1 台;建议 16C32G+ | 跑沙箱 |
建议
使用独立的机器作为计算节点。
什么是 PVM?(技术原理)
PVM(Pagetable-based Virtual Machine)是一种基于页表的嵌套虚拟化框架,构建于 KVM 之上。与传统嵌套虚拟化不同,PVM 不依赖宿主 hypervisor 向 guest 暴露 Intel VT-x / AMD-V 等硬件虚拟化扩展,而是在 guest 内核层通过共享内存区域和影子页表(shadow page table)来完成特权级切换与内存虚拟化,对宿主 hypervisor 完全透明。
PVM 最初由论文 《PVM: Efficient Shadow Paging for Deploying Secure Containers in Cloud-native Environment》 提出。腾讯云在此基础上进行了大量功能与性能改进、bugfix,并将相关工作开源至 OpenCloudOS 内核,供社区使用。数年来,我们已在腾讯云生产环境部署了大量 PVM 实例,其可靠性已经过生产验证。
2. 确认集群就绪
kubectl get nodes -o wide
kubectl get storageclass # 非空
helm version --short # ≥ v3.10记下稍后要用的节点名。确认至少有一台节点用于跑控制面、另一台跑计算面。
3. 给节点打标签、角色
3.1 多节点(推荐,控制面 / 计算面分离)
正常情况下,请为 K8s 添加至少 2 台机器,采用控制面、计算面分离的方式进行部署:
请执行命令为相关节点打标签:
# 控制面节点
kubectl label nodes <control-node> cube.tencent.com/cube-control=true --overwrite
# 计算节点(跑沙箱)
kubectl label nodes <compute-node> cube.tencent.com/cube-node=true --overwrite
# 若计算节点不是裸金属服务器,则还需要打这个 label ,即可自动安装 PVM
kubectl label nodes <pvm-compute-node> cube.tencent.com/allow-pvm-bootstrap=true --overwrite打角色污点(避免无关负载落到这些节点上):
# 可选
# kubectl taint nodes <control-node> cube.tencent.com/control=true:NoSchedule --overwrite
# 计算节点必打
kubectl taint nodes <compute-node> cube.tencent.com/compute=true:NoSchedule --overwrite3.2 单节点(不推荐)
提示
对于单节点的情况,我们更推荐采用 快速开始 的方式进行部署,而不是使用 K8s。
单节点标签与污点
若您的 K8s 集群内仅有 1 台机器,可尝试通过以下方式打标签、污点(不推荐):
export NODE=<你的节点名>
kubectl label nodes "$NODE" \
cube.tencent.com/cube-control=true \
cube.tencent.com/cube-node=true \
cube.tencent.com/allow-pvm-bootstrap=true \
--overwrite
kubectl taint nodes "$NODE" cube.tencent.com/control=true:NoSchedule --overwrite
kubectl taint nodes "$NODE" cube.tencent.com/compute=true:NoSchedule --overwrite4. 准备配置文件
执行创建配置文件:
cp deploy/kubernetes/chart/runtime-values.example.yaml runtime-values.yaml根据您的需求对其进行修改,至少填写以下内容:
cubeProxy:
advertiseIP: "10.0.1.10"
domain: "cube.app"
tls:
mode: selfSigned # 试用;生产建议 existingSecret / certManager
# 必填
mysql:
host: "" # 空 = 使用内置 MySQL
password: "replace-me-mysql-password"
rootPassword: "replace-me-mysql-root-password"
redis:
host: ""
password: "replace-me-redis-password"更多配置
控制面 PVC 配置
请转到 8.1 控制面 PVC 配置
计算节点数据盘
Cube 会在宿主机 /data/cubelet下写入数据,且该路径必须是 XFS文件系统。 为便于体验,我们默认会帮您创建 一块 25GB 的loopback 镜像文件 并挂载。
若您希望在生产环境部署,或调整相关配置,请转到 8.2 计算节点数据盘配置。
计算节点网络(cube-node 重建)
请在部署前决定
默认的宿主机网络下,沙箱设备留在宿主机 netns,不随 cube-node Pod 重建销毁;在 cubelet 重启后沙箱存活的实机验证落地前,drain 仍是支持路径。若改用 Pod 网络(cubeNode.hostNetwork: false),则沙箱运行期间该 Pod 不可重建——该节点上所有沙箱的网络全部中断(入站、出站均中断),且无法自愈。详细说明与取舍(含 NetworkPolicy):8.3 cube-node 网络与 Pod 重建。
宿主机网络默认值是新增行为,尚未在所有 CNI / admission 配置下验证。hostNetwork Pod 绕过 CNI IPAM、不被 NetworkPolicy 选中;eBPF 型 CNI(如 Cilium)自身的 eBPF 程序可能与宿主机网卡上的 cubevs 钩子冲突;集群若强制 restricted Pod Security Admission,会拒绝 hostNetwork Pod。请先在测试集群验证此默认值,再用于生产;集群不允许 hostNetwork 时设 cubeNode.hostNetwork: false(见 8.3)。
5. Helm 安装
中国大陆用户
在以下任一安装命令中额外加上 -f deploy/kubernetes/chart/values-cn.yaml,即可从国内镜像源拉取镜像。
在仓库根目录执行以下命令即可完成安装:
由于该过程会下载较多资源、执行初始化动作,根据您的机器性能、网络状况,需要一段时间才能完成部署。
标准多节点部署:
# 标准多节点
helm upgrade --install cube ./deploy/kubernetes/chart \
-n cube-system \
--create-namespace \
-f runtime-values.yaml \
--wait \
--timeout 90m腾讯云 TKE:
helm upgrade --install cube ./deploy/kubernetes/chart \
-n cube-system \
--create-namespace \
-f deploy/kubernetes/chart/values-tke.yaml \
-f runtime-values.yaml \
--wait \
--timeout 90m单节点试用:
helm upgrade --install cube ./deploy/kubernetes/chart \
-n cube-system \
--create-namespace \
-f deploy/kubernetes/chart/values-single-node.yaml \
-f runtime-values.yaml \
--wait \
--timeout 90m6. 验证部署
# 1) Pod 是否 Ready
kubectl get pods -n cube-system -o wide
# 2) 计算节点是否已注册到 CubeOps
kubectl exec -n cube-system deploy/cube-cubemastercli -- \
sh -lc 'cubeopscli --address "$CUBEOPSCLI_ADDRESS" --port "$CUBEOPSCLI_PORT" node list'
# 3) 内置端到端测试(约数分钟)
helm test cube -n cube-system --timeout 20m --logs期望:
cube-nodeReady 数量 = 打了cube-node=true的节点数- 命名空间
cube-system下的各个服务均为 Ready helm test通过
访问Cube 的 WebUI 界面:
kubectl -n cube-system port-forward svc/cube-webui 12088:12088
# 浏览器打开 http://127.0.0.1:120887. 卸载
helm uninstall cube -n cube-system
kubectl delete namespace cube-system卸载不会自动清理:
- 节点上的 Cube 标签 / 角色污点
- 计算节点 hostPath 数据
- PVM 宿主机内核改动
8. 高级配置
8.1 控制面 PVC 配置
- 默认:CubeMaster / MySQL / Redis / MinIO 走集群 default StorageClass
- 指定 SC:在
runtime-values.yaml修改persistence.storageClassName: <name> - 单节点 / 无 CSI:可改用 hostPath(见
runtime-values.example.yaml注释)
8.2 计算节点数据盘配置
对于 生产部署 ,我们建议您通过运维手段,为每台计算节点配置单独的数据盘,格式化为 XFS 文件系统,并挂载在 /data/cubelet 下,这样能获得最佳的性能、稳定性。 然后,在 runtime-values.yaml 内配置:
bootstrap:
nodeInit:
dataCubelet:
loopback:
enabled: false若您的节点上没有独立数据盘,我们默认会在初次初始化计算节点时,在/data/cubelet下为您挂载 1 块 25G 的loop 设备。
只影响「第一次」创建
默认仅在 /data/cubelet-xfs.img 不存在 时自动创建磁盘镜像文件。 后续更改配置不会自动扩容。要换更大盘需在维护窗口内手工处理。
若您希望自定义数据盘配置,可按照以下方法在安装前调整配置:
| values 路径 | 默认 | 说明 |
|---|---|---|
bootstrap.nodeInit.dataCubelet.loopback.enabled | true | 为 true 时,bootstrap 会在节点上创建并挂载 loopback XFS |
bootstrap.nodeInit.dataCubelet.loopback.imagePath | /data/cubelet-xfs.img | 镜像文件路径 |
bootstrap.nodeInit.dataCubelet.loopback.size | 25G | 首次创建镜像时的大小(truncate -s) |
bootstrap:
nodeInit:
dataCubelet:
loopback:
enabled: true
size: 200G # 按容量规划调整;需小于存放 image 的文件系统剩余空间8.3 cube-node 网络与 Pod 重建
一句话结论
cube-node 默认使用宿主机网络,Pod 重建不再改变沙箱网络设备所在的 network namespace。在 cubelet 重启后沙箱存活的实机验证落地前,计算面仍以 drain 为支持路径——见升级。若改用 Pod 网络(cubeNode.hostNetwork: false),则该 Pod 不可重建——重建会导致该节点上所有沙箱的网络全部中断(入站、出站均中断)且无法自愈。
为什么网络模式决定这件事
沙箱的网络设备(TAP 设备)与 cubevs 钩子位于 cube-node Pod 的 network namespace 中,因此 Pod 的网络模式决定了重建时它们会怎样:
| 项目 | 说明 |
|---|---|
| 触发条件 | 任何导致 Pod 重建的操作:DaemonSet template 变更、镜像升级、手工 kubectl delete pod 等 |
| hostNetwork(默认) | netns 即宿主机 netns,不随 Pod 重建变化,设备得以保留。cubelet 重启后沙箱存活尚未实机验证——在此之前仍应 drain(见升级) |
Pod 网络(hostNetwork: false) | Pod netns 被销毁:该节点上所有沙箱的网络全部中断(入站、出站均中断)且不能自愈。只能销毁并重建受影响的沙箱 |
计算面升级同样受此影响,详见升级。
默认:宿主机网络
cubeNode.hostNetwork 默认为 true,全新安装无需任何操作。保持默认时需要确认:
| 事项 | 说明 |
|---|---|
| DNS | dnsPolicy 自动切为 ClusterFirstWithHostNet,集群内域名解析正常 |
| 端口冲突 | cubelet(9998 / 9999 / 9966)与启用时的 CubeS3lvol 占用宿主机端口;已被占用时 cube-node-init 会 fail-fast(bootstrap.nodeInit.checkHostPorts)。CubeEgress 端口不在此检查中——启用时请自行确认。cubelet 端口无认证,防火墙按 kubelet 10250 同级对待 |
| NetworkPolicy | 无法管控沙箱流量,见下文 |
| 监控 / 防火墙 | 基于 Pod IP / Pod CIDR 的规则需改为基于节点 IP |
| CNI / admission | hostNetwork Pod 绕过 CNI IPAM、不被 NetworkPolicy 选中;eBPF 型 CNI(如 Cilium)可能与宿主机网卡上的 cubevs 钩子冲突;restricted Pod Security Admission 会拒绝 hostNetwork Pod。此默认是新增的——先在测试集群验证,或设 cubeNode.hostNetwork: false |
改用 Pod 网络
当 Kubernetes NetworkPolicy 需要管控沙箱流量(例如「沙箱能否访问某个 Service」)时,设 cubeNode.hostNetwork: false。Pod 网络其余方面都是代价:
cube-nodePod 重建会中断该节点上所有沙箱的网络;- guest MTU 需要容纳 CNI 封装——
cubeNode.network.mtu: auto会按探测到的网卡下调。
在已有 release 上改这个值会重建所有 Big Pod,因此由一个 pre-upgrade Hook 拦截:见升级 · 切换网络模式。
后续工作:PR #1189(尚未合入,仅供参考)
若要在保持宿主机网络的同时用 NetworkPolicy 管控沙箱访问集群内 Service / Pod 的流量,以及实现完整的 cube-node 原地替换,可参考 PR #1189:
- 仅将发往集群 CIDR 的流量经节点本地 EgressProxy Pod 转发,并 SNAT 为 Proxy Pod IP,使其受您自定义的 NetworkPolicy 管控;其余流量仍走正常路由。
常见问题速查
| 现象 | 怎么处理 |
|---|---|
| 控制面 Pod 一直 Pending | 默认需要节点有 cube-control=true(或你改过的 nodeSelector);再查污点 / toleration |
cube-node DESIRED=0 | 计算节点是否打了 cube-node=true? |
Helm 报 CHANGE_ME_* / 校验失败 | 检查 runtime-values.yaml 密码与 placement 是否完整 |
| 首次安装很久 / 节点重启 | 启用 PVM 时正常;等指纹就绪、门闩清除后再看 bootstrap / Big Pod |
更细的说明见本目录其它文档: