ONES 外置 Kubernetes 集群部署指南
本文档说明如何在已有的外部 Kubernetes 集群上部署 ONES 系统,包括前置要求、权限配置、存储准备、镜像+镜像仓库对接以及完整的部署流程。
本文档默认读者已具备 Kubernetes 基础运维能力,能够使用 kubectl 查询节点、Pod、Service、PVC、StorageClass 和事件信息等基本操作。
本文档是基于ONES已有的实践经验汇总而成,可能客户提供的 Kubernetes 集群在规范标准、语义理解上与ONES有所不同,为避免歧义,需客户提供如下规范待双方沟通确认:
| 类别 | 需要确认的内容 |
|---|---|
| 集群规范 | K8s 版本、CCE/ACK/EKS/自建、节点规格、节点 OS、容器运行时 |
| 网络规范 | VPC、子网、DNS、Ingress、SLB/ELB、域名、证书、出口访问、东西向访问 |
| 存储规范 | 是否允许动态 PVC、是否只允许静态 PV、NFS/云硬盘/SFS 使用原则、回收策略 |
| 镜像规范 | 镜像仓库地址、镜像同步方式、镜像扫描、安全准入 |
| 安全规范 | namespace、RBAC、PodSecurity、root 权限、特权容器、hostPath、NetworkPolicy |
| 运维规范 | 日志、监控、告警、备份、巡检、变更流程 |
| 高可用规范 | 副本数、反亲和、PDB、节点池隔离、故障恢复要求 |
| 资源规范 | requests/limits、配额、命名规范、标签规范 |
| 交付规范 | 谁创建资源、谁审批、谁有权限、交付边界 |
1. 概述
1.1 适用场景
- 已有生产级 Kubernetes 集群(如 K8s、K3s 等)
- 需要将 ONES 部署到现有集群中,而非使用安装器内置的 K3s
- 希望复用现有的基础设施(存储、网络、镜像仓库等)
1.2 架构说明
说明:ONES 会在集群中创建多个 namespace:
ones-installer:安装器资源ones-system:系统组件ones:业务组件
因此需要 Cluster Admin 权限。
2. 集群要求
2.1 基础要求
| 要求项 | 说明 | 验证命令 |
|---|---|---|
| Kubernetes 版本 | v1.22 - v1.32 | kubectl version |
| 集群状态 | Healthy,所有节点 Ready | kubectl get nodes |
| 节点操作系统 | 计划承载 ONES 的节点需为 Linux 64 位节点 | kubectl get nodes -o wide |
| 节点架构 | 计划承载 ONES 的节点 CPU 架构需保持一致,并与安装包/镜像架构一致(如 amd64 或 arm64) | kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{\"\\t\"}{.status.nodeInfo.architecture}{\"\\n\"}{end}' |
| kubectl 访问 | 具有集群管理权限 | kubectl auth can-i '*' '*' |
| kubeconfig | 可访问集群的 kubeconfig 文件 | 确保 $KUBECONFIG 或 ~/.kube/config 有效 |
⚠️ 部署前必须验证 kubectl 连接状态:
# 验证 kubectl 连接
kubectl cluster-info
# 验证集群状态
kubectl get nodes
# 验证是否有 cluster-admin 权限
kubectl auth can-i '*' '*' --all-namespaces
# 或验证关键权限
kubectl auth can-i create namespaces
kubectl auth can-i create deployments --all-namespaces
kubectl auth can-i create persistentvolumeclaims --all-namespaces
2.2 权限要求
ONES 安装器需要 Cluster Admin 权限,因为会在集群中创建和管理多个 namespace:
ones-installer:安装器资源ones-system:系统组件ones:业务组件ones-telemetry:可观测组件
所需权限包括:
- 创建/管理多个 Namespace
- 部署工作负载(Deployment、StatefulSet、DaemonSet、Pod 等)
- 配置网络(Service、Ingress、NetworkPolicy)
- 管理存储(PV、PVC、StorageClass)
- 配置 RBAC(ServiceAccount、Role、RoleBinding)
2.3 存储要求
2.3.1 StorageClass 类型
ONES 需要两种类型的 StorageClass:
| 类型 | 用途 | 访问模式 | 回收策略 |
|---|---|---|---|
| ReadWriteOnce (RWO) | 数据库、单副本存储 | RWO | Retain(推荐) |
| ReadWriteMany (RWX) | 共享文件存储 | RWX | Retain(推荐) |
⚠️ 重要:回收策略选择
- Retain(推荐):PVC 删除后,PV 和数据保留,避免数据丢失
- Delete:PVC 删除后,PV 和数据会被自动删除,存在数据丢失风险
建议:
- 生产环境务必使用 Retain 回收策略的 StorageClass
- 如果集群只有 Delete 策略的 StorageClass,建议先创建 Retain 策略的 StorageClass
检查现有 StorageClass:
kubectl get storageclass
必须验证 StorageClass 可实际创建 PVC:
仅看到 StorageClass 名称并不能说明集群满足要求,还需分别验证 RWO 和 RWX 的动态供给能力。
# 创建测试 namespace
kubectl create namespace ones-precheck
# 验证 RWO StorageClass(将 <your-rwo-storageclass> 替换为实际名称)
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rwo-check
namespace: ones-precheck
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: <your-rwo-storageclass>
EOF
# 验证 RWX StorageClass(将 <your-rwx-storageclass> 替换为实际名称)
cat <<'EOF' | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rwx-check
namespace: ones-precheck
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: <your-rwx-storageclass>
EOF
# 观察 PVC 是否成功绑定到 Bound
kubectl get pvc -n ones-precheck -w
# 验证完成后清理
kubectl delete namespace ones-precheck
说明:
- 不同环境中的 StorageClass 名称可能不同(如云厂商默认块存储类、文件存储类等)
- 用户需要根据自己集群的实际情况选择合适的 StorageClass
- 确保 StorageClass 的 provisioner 正常工 作
- 如 PVC 长时间处于
Pending,说明存储类、底层存储或 CSI provisioner 仍未满足部署要求
2.3.2 生产资源规格建议
存储资源规格:
| 存储类型 | 最小容量 | 用途 |
|---|---|---|
| S3 兼容对象存储 | > 100G | 业务附件存储 |
| RWX 共享存储 | ≥ 100G | 共享数据交换 |
| RWO 块存储 | 总大小 > 500G | 数据库、中间件等数据 |
说明:
- 对象存储用于存储业务附件、图片等文件
- RWX 共享存储用于跨节点数据共享和交换(如 NFS、CephFS 等)
- RWO 块存储用于数据库、中间件等需要独占访问的组件
2.3.3 配置 StorageClass
部署时通过环境变量指定:
# RWO 存储类(根据实际集群情况填写)
STORAGECLASS_NAME_FOR_READ_WRITE_ONCE=<your-rwo-storageclass>
STORAGECLASS_NAME_FOR_READ_WRITE_ONCE_WITH_RETAIN=<your-rwo-retain-storageclass>
# RWX 存储类(根据实际集群情况填写)
STORAGECLASS_NAME_FOR_READ_WRITE_MANY=<your-rwx-storageclass>
STORAGECLASS_NAME_FOR_READ_WRITE_MANY_WITH_RETAIN=<your-rwx-retain-storageclass>
示例(根据实际集群调整):
# 示例 1:通用命名
STORAGECLASS_NAME_FOR_READ_WRITE_ONCE=standard
STORAGECLASS_NAME_FOR_READ_WRITE_MANY=nfs-storage
# 示例 2:AWS EKS
STORAGECLASS_NAME_FOR_READ_WRITE_ONCE=gp2
STORAGECLASS_NAME_FOR_READ_WRITE_MANY=efs
2.3.4 常见云厂商资源示例
| 云厂商 | RWO 示例 | RWX 示例 | 对象存储 |
|---|---|---|---|
| 华为云 CCE | EVS / csi-disk | SFS / SFS Turbo | OBS |
| 阿里云 ACK | ESSD / disk | NAS | OSS |
| AWS EKS | EBS | EFS | S3 |
2.4 网络要求
2.4.1 集群网络能力
外置 Kubernetes 集群必须具备以下网络能力:
- 支持
Service的NodePort类型:ONES 安装和安装后的默认对外访问方式均依赖NodePort - 允许访问节点 IP +
NodePort:客户端、前置负载均衡或反向代理需要能够访问集群节点 IP 对应的NodePort端口 - 允许使用集群的
NodePort端口范围:默认情况下 Kubernetes 的NodePort范围通常为30000-32767,如集群修改了该范围,需确保下文涉及的端口已包含在实际可用范围内
集群节点之间网络要求:
- 延迟:< 50ms
- 带宽:> 100M
- 丢包率:< 0.1%
- 抖动:< 10ms
部署要求:
- 集群服务器须位于同一机房、同一交换机、同一网段
- 若部署于虚拟机,底层宿主机需满足相同条件
- 避免跨机房或跨网段部署集群,减少网络延迟和故障风险
- 如果是云主机,可采用按流量计费的带宽模式
2.4.2 端口要求
以下端口均通过 Kubernetes NodePort Service 对外暴露,不是额外独立的集群网络能力要求。
部署过程中需要通过 NodePort 暴露的端口:
- 30011:安装器 Web 界面(installer-web)
- 30012:安装器 API(installer-api)
安装完成后需要通过 NodePort 暴露的端口:
- 30011:业务访问端口(默认,可调整)
可选端口:
- 80/443:如通过 Ingress、负载均衡或反向代理对外提供标准 HTTP/HTTPS 访问,可按需使用
- 31380:监控端口(按需通过
NodePort暴露)
说明:
- 文档中提到的
30011、30012、31380等端口,均指 Kubernetes Service 的NodePort - 如果集群、云防火墙、安全组或前置网关限制了对应
NodePort访问,需要提前放通 - 如使用负载均衡、Nginx 或其他网关统一入口,仍需保证其后端能够访问节点 IP 和对应
NodePort
验证端口:
kubectl get svc -A
2.4.3 域名要求
如需使用域名访问,需提前准备:
- 提前申请域名
- 对接企业微信场景:必须使用域名
2.4.4 SSL 证书要求
如需使用 HTTPS 访问,需提前准备 SSL 证书:
- 证书需来自可信 CA
- 证书链完整
- 匹配域名且未过期
- 准备 key 文件和 crt 文件
2.4.5 前置网关
提前确认是否需要以下前置网关设备:
- 防火墙
- Nginx 反向代理
- 负载均衡(LB)
这些设备会影响服务访问方式。如需统一入口,通常由这些设备对外提供访问地址,并将流量转发到 Kubernetes 节点 IP 对应的 NodePort 端口。
2.4.6 NTP 服务器
提供可用的 NTP 服务器,用于配置时间同步服务:
- 确保服务器的时间和时区正确
- 所有节点时间同步
2.4.7 DNS 要求
- CoreDNS 或 kube-dns 正常运行
- Pod 内部能够正常解析集群 Service 域名与外部依赖域名
2.4.8 外部依赖连通性
计划承载 ONES 的节点或 Pod,需要根据实际部署方式具备以下网络连通性:
- 镜像仓库:能够访问
DEST_IMAGE_REGISTRY - 对象存储:如使用 S3 兼容对象存储,能够访问对象存储 Endpoint
- NFS/共享存储:如使用 RWX 共享存储,所有相关节点均可访问底层存储服务
如集群启用了严格的防火墙、安全组、NetworkPolicy 或出口代理,请提 前验证这些依赖的连通性。
2.5 节点规划
⚠️ 重要建议:
建议为 ONES 部署独立分配集群节点,原因如下:
- ONES 包含 DaemonSet 类型资源,会部署到集群所有节点
- 建议这批节点资源仅供 ONES 使用,或仅分配给 ONES 独享可见的节点资源
- 目前 ONES 编排层面尚未全面支持基于 Label 的调度策略,建议在集群层面进行节点隔离
- 如目标节点存在不可兼容的污点(Taint)、资源配额或准入限制,需在部署前提前处理,否则可能出现 Pod 无法调度或资源创建失败
生产环境节点规格建议:
| 节点类型 | 规格 | 数量 | 说明 |
|---|---|---|---|
| Worker 节点 | 16C 24G | ≥ 3 台 | 运行 ONES 应用和中间件 |
2.6 部署前检查清单
满足以下条件后,可基本判断当前 Kubernetes 集群满足 ONES 外置部署要求:
| 检查项 | 通过标准 |
|---|---|
| Kubernetes 版本 | 位于 v1.22 - v1.32 范围内 |
| 节点状态 | 计划承载 ONES 的节点均为 Ready |
| 节点架构 | 目标节点架构一致,且与所选安装包/镜像架构一致 |
| 权限 | 当前 kubeconfig 具备 cluster-admin 级别能力 |
| RWO 存储 | 至少 1 个 RWO StorageClass 可成功创建并绑定 PVC |
| RWX 存储 | 至少 1 个 RWX StorageClass 可成功创建并绑定 PVC |
| NodePort 能力 | 集群允许创建并访问 NodePort Service |
| DNS | CoreDNS/kube-dns 正常,Pod 能解析集群内外域名 |
| 外部依赖连通性 | 能访问镜像仓库;如启用对象存储/NFS,也已验证连通 |
| 节点资源 | 至少 3 个符合建议规格的 Worker 节点可供 ONES 使用 |
| 调度限制 | 目标节点不存在会阻塞部署的污点、配额或准入策略 |
如以上任一项不满足,建议先补齐集群条件,再执行部署。
3. 镜像仓库配置
# 镜像仓库地址
DEST_IMAGE_REGISTRY=registry.example.com
DEST_IMAGE_USER=admin
DEST_IMAGE_PASSWD=password
# 镜像同步模式
INSTALL_IMAGE_SYNC_MODE=auto # auto | syncer | skip
4. 部署流程
4.1 离线部署(推荐)
步骤 1:下载离线安装包(在有网络的机器上执行)
# 下载工具脚本
curl -O https://packages.ones.cn/release/latest/quickstart.sh
# 查看支持的版本
bash quickstart.sh --list-versions
# 下载指定版本的离线包
bash quickstart.sh --version v6.94.0 --download
# 下载完成后会提示安装包路径,如:ones_offline_pkg_v6.94.0_amd64.tar.gz
步骤 2:传输到目标服务器(离线环境)
# 将 quickstart.sh 和离线包复制到目标服务器
scp quickstart.sh ones_offline_pkg_v6.94.0_amd64.tar.gz user@target-server:/data/install/
步骤 3:执行部署
# 设置环境变量
export DEPLOY_MODE=external
export DEST_IMAGE_REGISTRY=registry.example.com
export DEST_IMAGE_USER=admin
export DEST_IMAGE_PASSWD=password
export INSTALLER_VOLUME_MODE=pvc
export INSTALLER_VOLUME_STORAGE_CLASS=<your-rwo-storageclass>
export STORAGECLASS_NAME_FOR_READ_WRITE_ONCE=<your-rwo-storageclass>
export STORAGECLASS_NAME_FOR_READ_WRITE_MANY=<your-rwx-storageclass>
# 执行安装
bash quickstart.sh --offline-file /data/install/ones_offline_pkg_v6.94.0_amd64.tar.gz
4.2 在线部署
DEPLOY_MODE=external \
DEST_IMAGE_REGISTRY=registry.example.com \
DEST_IMAGE_USER=admin \
DEST_IMAGE_PASSWD=password \
curl -sfL https://packages.ones.cn/release/latest/quickstart.sh | bash -
4.3 仅同步镜像
# 下载离线包(参考 4.1 步骤1)
# 仅同步镜像到镜像仓库
SYNC_ONLY=true \
DEST_IMAGE_REGISTRY=registry.example.com \
DEST_IMAGE_USER=admin \
DEST_IMAGE_PASSWD=password \
bash quickstart.sh --offline-file /data/install/ones_offline_pkg_v6.94.0_amd64.tar.gz
5. 初始化 ONES
5.1 验证安装器部署
# 检查 namespace
kubectl get namespaces | grep ones
5.2 进入安装器并初始化
# 拷贝配置文件
kubectl -n ones-installer cp /data/ones/ones-installer-pkg/config `kubectl get pod -A|grep -i installer-api | awk '{print $2}' `:/data/ones/ones-ai-k8s/
# 进入 ONES 操作终端
ones-ai-k8s.sh
# 执行初始化配置
make init-config
按照提示完成以下配置:
- 配置时区、语言:设置初始团队时区与语言
- 创建团队:创建第一个团队并设置团队名称
- 创建团队负责人:创建系统第一个用户(具有最高权限),请确保填写的邮箱地址能正常接收邮件
5.3 配置存储
编辑配置文件:
vi config/private.yaml
配置示例:
# StorageClass 配置(根据实际集群填写)
storageClassNameForReadWriteOnce: <your-rwo-storageclass>
storageClassNameForReadWriteOnceWithRetain: <your-rwo-retain-storageclass>
storageClassNameForReadWriteMany: <your-rwx-storageclass>
storageClassNameForReadWriteManyWithRetain: <your-rwx-retain-storageclass>
# 停用本地存储,使用 StorageClass provisioner 独立管理
localstorageForMysqlEnable: "false"
localstorageForElasticsearchEnable: "false"
localstorageForKafkaEnable: "false"
localstorageForZookeeperEnable: "false"
localstorageForClickhouseEnable: "false"
localstorageForPrometheusEnable: "false"
localstorageForTidbEnable: "false"
localstorageForMinioEnable: "false"
localstorageForApisixEtcdEnable: "false"
localstorageForDM8Enable: "false"
localstorageForOnesAipQdrantEnable: "false"
localstorageForOnesBackupInternalMinioEnable: "false"
localstorageForOnesAipEnable: "false"
localstorageForS3ProxyEnable: "false"
localstorageForOnesLoggingEnable: "false"
localstorageForOnesTelemetryCollectorEnable: "false"
# 对象存储配置(可选)
dataS3Endpoint: "https://<your-s3-endpoint>"
dataS3AccessKeyID: "<your-access-key-id>"
dataS3SecretAccessKey: "<your-access-key-secret>"
dataS3Region: "<your-s3-region>"
dataS3ForcePathStyle: false
dataS3PublicBucket: "ones-public-files"
dataS3PrivateBucket: "ones-private-files"
dataS3TmpBucket: "ones-tmp-files"
5.4 部署 ONES 服务
bash script/ones/deploy-ones.sh
首次启动过程将耗时 30 分钟不等(视实际硬件而定)。请监控终端以跟踪进度,一旦所有组件都运行起来,ONES 即可使用。
5.5 验证部署
# 检查所有组件状态
kubectl get pods -n ones
# 检查日志
kubectl logs -f deployment/installer-api -n ones-installer
5.6 登录 ONES
按照提示的访问方式,打开登录页面:
http://<node-ip>:30011
其中 <node-ip>:30011 表示某个可访问的 Kubernetes 节点 IP 与业务 Service 的 NodePort。如已配置负载均衡、反向代理或域名,也可直接使用对应的统一访问地址。
输入初始化过程设置的「团队负责人」账号密码登录系统。
6. 常见问题
6.1 镜像拉取失败
现象:Pod 状态为 ImagePullBackOff
解决:
# 检查镜像仓库 secret
kubectl get secret -n ones-system | grep registry
# 手动创建 secret
kubectl create secret docker-registry ones-registry-secret \
--namespace=ones-system \
--docker-server=registry.example.com \
--docker-username=admin \
--docker-password=password
# 验证镜像仓库访问
curl -u admin:password https://registry.example.com/v2/_catalog
6.2 PVC 绑定失败
现象:PVC 状态为 Pending
解决:
kubectl describe pvc <pvc-name> -n ones-system
kubectl get storageclass
kubectl get pv
6.3 权限不足
现象:部署时报错 Forbidden
解决:
# 验证权限
kubectl auth can-i '*' '*' --all-namespaces
# 授予 cluster-admin 权限
kubectl create clusterrolebinding ones-admin \
--clusterrole=cluster-admin \
--user=<your-user>
7. 最佳实践
7.1 节点规划(重要)
实施方案:
方案一:独立集群(推荐)
为 ONES 部署独立的 Kubernetes 集群,完全隔离资源。
优点:
-- 资源完全隔离
-- DaemonSet 不会跑到客户业务节点
-- 升级、重启、排障不会影响其他系统
-- 权限、网络、存储、监控边界清晰
-- 最符合生产交付和责任划分
缺点:
-- 成本更高
-- 客户需要多维护一个集群
方案二:独立节点池
在集群中划分独立的节点池,仅用于 ONES 工作负载:
# 为 ONES 专用节点打标签(便于识别和管理,不能单独作为强隔离手段。)
kubectl label nodes node1 node2 node3 dedicated=ones
# 查看节点
kubectl get nodes -l dedicated=ones
同时,对非 ONES 节点加 Taint,让 ONES Pod 无法调度过去。
8 生产环境建议
- 镜像仓库:使用企业级镜像仓库,若有HA需求满足HA需满足故障转移能力
- 存储:数据库使用高性能 SSD,文件使用 NFS 或 S3 兼容对象存储
- 网络:建议通过 Ingress、负载均衡器(LB)或反向代理对外提供统一入口,并将流量转发到业务 Service 对应的
NodePort(默认30011)以实现负载均衡 - 监控:完成部署 Prometheus + Grafana,配置告警
- 节点:提供独立集群
- 权限:提供 Cluster Admin 权限