适用范围
适用范围:本文面向已完成立项、容量规划、硬件与网络准备、版本选型及安全审批的 ARM64 信创内网项目。文中的“72 小时”仅指现场实施、验证与交接窗口,不包含产品选型、国产化兼容适配、软件采购、等保测评、业务迁移和变更审批。
核心观点:离线 Kubernetes 的难点不是执行一次 kubeadm init,而是让每一个输入可验证、每一步操作可复现、每一项验收可签字、每一种故障可恢复。
客户给了三天窗口:在无法访问公网的政企机房,交付承载 Spring Cloud、Nacos 和 Kafka 的 Kubernetes 平台。服务器运行国产 ARM64 操作系统;所有 RPM、镜像、Chart 和证书都必须经过审批、扫描和摆渡;上线前还要证明,失去一个控制平面、一个工作节点或一个 API 入口后,平台不会立刻失去服务能力。
这种项目最容易踩的坑,就是把“集群 Ready”当成“生产可交付”。一个节点全绿的集群,仍然可能隐藏不少问题:镜像缺失导致扩容失败、Harbor 故障后无法发布、etcd 快照无法恢复、入口单点、PVC 无法重挂、CNI 对目标内核不兼容,或者验收时根本没有证据证明这些风险已经排除。
本文给的是一套以交付闭环为中心的实施框架。它不是某个厂商的安装说明,也不要求读者复制一组固定版本;它是一份可以用于方案评审、实施计划、验收设计和交接的工程化方法。
1. 先定义“交付完成”:四条红线与一个边界
在动手前,项目组应共同签署以下交付边界。
- 版本已冻结:Kubernetes、OS、内核、容器运行时、CNI、CSI、Harbor、Helm、Nacos、Kafka 及镜像 digest 均已有确定基线;现场不进行首次适配。
- 制品已闭环:所需包、镜像、Chart、配置、文档与许可证已经在联网制作区完成收集、验签、扫描和 ARM64 预演。
- 基础条件已就绪:服务器、IP、DNS、NTP、VIP、负载均衡、磁盘、网络策略、存储服务和账号权限全部可用。
- 恢复目标已批准:平台组、应用组和安全组已经确认 RTO、RPO、故障演练范围与验收责任人。
边界同样要说清楚:三天可以完成的是经过预演的既定版本部署、故障验证和交接;但不能可信地承诺在三天内完成技术选型、国产化首次适配、等保三级认证和全量业务迁移。等保也不是安装审计插件后自动获得的结论,仍然需要基于系统边界、制度、技术措施和测评结果来判定。
2. 设计不是画拓扑:冻结六类不可变输入
2.1 硬件、OS 与内核基线
记录每类节点的 CPU 架构、型号、内存、磁盘类型与 IOPS、网卡与驱动、OS 发行版及补丁、内核版本、SELinux 状态、时间源和安全加固策略。尤其在 ARM64 信创环境里,镜像带有 linux/arm64 标签,并不代表目标宿主机一定满足 eBPF、iptables/nftables、overlayfs、cgroup v2 或存储插件所需的内核依赖。
要把“能启动”和“可生产”分开验证:在与生产等效的节点上检查内核模块、sysctl、容器运行时、CNI 连通性、NetworkPolicy、PVC 读写和节点重启后的恢复行为。产品白皮书只能缩小候选范围,目标 OS 上的预演结果才是准入证据。
2.2 网络与时间基线
冻结管理网、业务网、Pod CIDR、Service CIDR、DNS、NTP、API 虚拟地址、负载均衡地址、内部镜像仓库地址,以及每一类节点的端口矩阵。Pod 与 Service 网段必须和现有数据中心路由、VPN、分支网段不重叠。
离线不等于不需要可信时间。证书有效期、etcd、日志关联和审计取证都依赖内网 NTP;如果 NTP 不可达,应把这项作为入口检查失败,而不是在安装时临时绕过。CNI 的封装模式与最小链路 MTU 必须在预演中实测,不能仅因为网卡标称 10Gbps 就启用巨帧。
2.3 高可用拓扑:多数派、共同入口与故障域
推荐的最小生产拓扑是 3 个控制平面节点 + 堆叠式 3 成员 etcd + 2 个独立 API 入口或客户现有高可用负载均衡服务。controlPlaneEndpoint 应指向 VIP 或内部 DNS,而不是首台控制平面的地址。
三个 etcd 成员可以在失去一个成员后继续保持多数派;两个成员不行。两个 API 入口应跨主机故障域,并且负载均衡健康检查只把真正可用的 kube-apiserver 加入后端。单台 Harbor、单个 NFS 服务或同机部署的双 LB,仍然可能形成单点,应在方案中明确:是建设冗余、使用现有基础设施,还是接受故障期不可发布/不可扩容的业务限制。
2.4 版本矩阵:把“兼容”变成可审计事实
不要在正文或脚本里只写“最新稳定版”。项目应以一次审批日期为边界,建立版本矩阵,并离线保存对应官方文档、安装包哈希和预演报告。
| 类别 |
必填字段 |
准入判据 |
回退信息 |
| OS/内核 |
发行版、补丁、内核、SELinux 策略 |
ARM64 节点完成 CNI/CSI/重启验证 |
上一已验证补丁集 |
| Kubernetes |
kubeadm/kubelet/kubectl 版本、配置 API |
仍在组织支持窗口,升级路径明确 |
上一受支持基线 |
| 运行时 |
containerd、runc、CRI 配置、cgroup 驱动 |
与 kubelet 一致,pause 可离线拉取 |
已验证配置快照 |
| 网络与存储 |
CNI/CSI 版本、内核依赖、镜像 digest |
跨节点、策略、PVC、故障恢复通过 |
替代插件及切换条件 |
| 平台组件 |
Harbor、Helm、CoreDNS、监控与备份工具 |
内网 TLS、RBAC、镜像闭环通过 |
备份与安装包 |
| 中间件 |
Nacos、Kafka、数据库与 operator/Chart |
数据持久化、恢复与升级演练通过 |
数据恢复步骤 |
配置 API 必须与实际 kubeadm 主版本匹配。例如,如果项目采用 Kubernetes v1.28,就应使用该版本支持的 kubeadm 配置 API;不要把更高版本文档中的 v1beta4 配置直接复制到旧版本。历史版本只应作为迁移或既有系统说明,不应该被表述成新的生产推荐。
2.5 存储与中间件边界
CSI 不能只在计划中写“已安装”。在设计阶段就要明确存储类型(块、文件或本地盘)、动态供给方式、访问模式、卷扩容、快照、可用区/机架拓扑、回收策略、性能等级和故障域。验收必须覆盖 PVC 创建、挂载、卸载、重挂、节点故障后的恢复与备份还原。
Kubernetes 只能保证工作负载调度,不会替 Nacos 或 Kafka 保证数据一致性。Nacos 需要明确集群模式、外部数据库、认证、备份和恢复责任;Kafka 需要明确 KRaft 或 ZooKeeper 模式、副本因子、分区、min.insync.replicas、控制器/代理的反亲和、PVC 拓扑和滚动升级条件。任何一个关键参数没有业务负责人签字,就不应该被称为“生产级中间件交付”。
2.6 责任边界
平台组负责集群、入口、镜像仓库、备份工具、监控与交接;中间件组负责 Nacos/Kafka 数据可靠性与恢复演练;网络组负责 VIP、DNS、路由、ACL 和端口;安全组负责制品审批、证书、账号、审计和测评证据;业务组负责容量、SLO、RTO/RPO 与业务验证。责任矩阵应随交付包归档。
3. 离线制品不是“拷贝文件”,而是一条供应链
真正物理隔离的环境中,双网卡跳板机不能同时连接内外两个网络。制品应在联网制作区完成收集,经过来源核验、许可证核验、恶意代码扫描、签名/哈希检查与审批后,使用批准的离线介质、单向导入设备或合规摆渡流程进入隔离区。导入完成后还要重新计算哈希。
SHA256 能证明两次计算的字节一致,但它不能证明来源可信。来源可信仍要依赖上游签名、受控下载记录、审批单和制品账本;传输加密、介质保管和签名策略应遵从客户制度。密码、Token、私钥与解密材料不可明文打入交付包,更不能与备份文件放在同一故障域。
建议把一个冻结版本组织为如下结构:
release-2026Q4-arm64/
manifest.yaml # 组件、来源、架构、版本、digest、许可证、批准与预演结果
SHA256SUMS # 不含自身;导入后复算与校验
packages/ # OS 软件包、依赖闭包、离线仓库元数据
images/ # OCI 归档或受控仓库同步结果
charts/ # Chart、values、渲染后 YAML 与镜像清单
configs/ # containerd、kubeadm、CNI、CSI、LB、证书模板
scripts/ # 幂等安装、健康检查、备份恢复与验收脚本
evidence/ # 扫描报告、签名、审批、预演、变更和验收记录
3.1 镜像闭包:不要靠 grep values.yaml
Chart 的模板、hook、initContainer、sidecar、Job、多架构 manifest 与运行时 pause 镜像,都可能导致清单遗漏。正确的流程是:
- 对每个 Chart 执行
helm show values,确认所有镜像覆写字段;
- 以目标 values 执行
helm template,从渲染结果中提取每一个 image:;
- 加入 kubeadm、CNI、CSI、监控、备份、Harbor 及中间件的非 Chart 镜像;
- 将镜像同步到内网 Harbor,记录源 digest 与目标仓库实际 digest;
- 在目标 ARM64 节点使用 CRI 进行抽检拉取并启动验证;
- 结合预演和安装期间实际拉取日志做最终核对。
跨仓库复制可能重写 manifest,因此不能盲目把源仓库 digest 当作目标引用。应确认 manifest list 中包含 linux/arm64,并记录内网仓库返回的 digest。
# 在已冻结的 release 根目录执行;清单不包含自身和临时目录
find . -type f ! -name SHA256SUMS ! -path './tmp/*' -print0 | sort -z \
| xargs -0 sha256sum > SHA256SUMS
sha256sum -c SHA256SUMS
# 验证目标节点的 CRI、TLS、仓库连通性和 ARM64 pause 镜像
crictl --runtime-endpoint unix:///run/containerd/containerd.sock \
pull harbor.internal/k8s/pause:3.9
4. 72 小时现场计划:每一段都必须有止损点
时间表不是工期保证,而是把风险前移的检查框架。任一退出条件不满足,就停止扩大变更范围,回到预演矩阵和变更流程;不要为了赶工把一个未验证缺陷带入下一阶段。
| 阶段 |
时间预算 |
工作内容 |
退出条件 / 止损条件 |
| 入口检查 |
0–8 h |
核对制品、硬件、OS、DNS/NTP、IP/CIDR、VIP、端口、磁盘和权限 |
哈希全通过;时间偏差符合基线;网络/存储任一前置项缺失则暂停 |
| 基础设施 |
8–20 h |
配置离线软件源,安装运行时与 kubelet,分发 CA,部署 Harbor 与入口 |
每台 ARM64 节点可通过 TLS 拉取 pause;cgroup、CRI、内核模块与 sysctl 检查通过 |
| 控制平面 |
20–36 h |
建立 API 入口,初始化首控制面,加入其余两个控制面,备份 etcd |
三个 etcd 成员健康;VIP 可访问;完成首次快照并在隔离环境验证可恢复 |
| 数据平面 |
36–52 h |
部署经预演 CNI/CSI/CoreDNS,加入工作节点,完成网络与存储测试 |
节点 Ready;跨节点 Pod、DNS、Service、NetworkPolicy、PVC 重挂均通过 |
| 中间件与验收 |
52–72 h |
部署中间件、监控、告警和备份,实施故障演练、交接 |
节点/入口故障、恢复、断网无外连、告警和证据链通过;遗留项有书面风险接受 |
5. 三处最容易把集群拖入“假可用”的配置
5.1 containerd:CRI、cgroup、证书与 pause 镜像必须同时正确
以 containerd 1.7 为例,应从当前安装包生成完整默认配置,再修改必要字段;containerd 2.x 的插件配置路径不同,不能机械复用。检查 CRI 插件未禁用,kubelet 与运行时采用一致的 cgroup 驱动,内部 CA 已加入信任链,并通过 certs.d/hosts.toml 配置私有仓库,而不是跳过 TLS 校验。
version = 2
[plugins."io.containerd.grpc.v1.cri"]
sandbox_image = "harbor.internal/k8s/pause:3.9"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
Pod 处于 ContainerCreating 并不等于 cgroup 出错。先看 kubectl describe pod 的事件,再检查 journalctl -u kubelet -u containerd、crictl info、crictl images。若出现 exec: "/pause": stat /pause: no such file,应优先验证镜像平台、镜像配置的入口程序、二进制实际存在性,以及重打 tag 后正在运行的 digest;只修改 sandbox_image 往往无法修复有缺陷的镜像。
5.2 kubeadm:共同入口先可用,版本配置再谈初始化
先检查负载均衡的 TCP 6443 健康检查、VIP/DNS 解析与故障切换,再执行初始化。--upload-certs 仅用于在限时窗口安全共享控制平面加入所需的证书,不会自动形成高可用;join 输出和临时证书材料应按密钥管理制度保护、过期和销毁。
以下仅为 v1.28 兼容配置 API 的结构示例,地址、版本、镜像路径和数据目录必须取自项目矩阵:
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.10.11
bindPort: 6443
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: v1.28.5
controlPlaneEndpoint: "api.internal:6443"
imageRepository: harbor.internal/k8s
networking:
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
etcd:
local:
dataDir: /data/etcd
执行前运行 kubeadm config images list --config,逐项确认内网仓库存在对应路径。三个控制面加入后,使用带 TLS 参数的 etcdctl endpoint health 和 endpoint status 验证三个成员,并计划性摘除一个控制平面,确认 API 入口与业务控制面仍可用。
5.3 CNI:内核能力与回退路径比“性能宣传”重要
不要用“某 CNI 吞吐提升百分之多少”或“ARM64 一定更兼容”替代现场证据。以 Cilium 为例,内核要求随版本和启用功能而变化;是否开启 kube-proxy replacement、BPF masquerade、Hubble 或带宽管理,应分别评审依赖、收益、监控方式和回退动作。
先完成基础网络能力验证:节点加入、跨节点 Pod、Service、DNS、NetworkPolicy、节点重启、入口流量和故障恢复。然后再启用高级 eBPF 特性。如果目标内核不满足需求,应回到同样完成预演的替代 CNI;选型不能被口号绑死。使用 helm template 生成最终 YAML 后,复查每个 image: 均指向内网。
6. 把故障排查做成证据树
现场排障最忌讳“根据经验改参数”。建议在 Runbook 中固化以下证据树:
| 现象 |
首要证据 |
常见分支 |
收敛动作 |
Pod 长期 ContainerCreating |
Pod Events、kubelet/containerd 日志、CRI 镜像列表 |
镜像平台/入口、证书、CNI、卷挂载、cgroup |
用实际错误信息定位,不做盲改 |
节点 NotReady |
Node Conditions、CNI DaemonSet、路由与 MTU |
CNI 未就绪、内核依赖、DNS/路由、证书 |
对照预演基线逐项恢复 |
| etcd 慢或配额告警 |
DB 大小、碎片率、fsync/commit 指标、磁盘延迟 |
事件增长、慢盘、碎片、配额 |
先压缩/评估;逐成员整理;不得同时操作三成员 |
| 镜像拉取失败 |
containerd 日志、CA 链、仓库权限、实际 digest |
TLS 信任、DNS、凭据、路径不一致 |
修复信任/引用,不跳过 TLS |
| Kafka/Nacos 重启异常 |
StatefulSet 事件、PVC 状态、应用日志、数据库/副本状态 |
存储、探针、配置、复制与认证 |
按中间件恢复手册,不把 StatefulSet 当成数据恢复 |
etcd 的默认后端存储配额常被误称为“默认 2GB keyspace”。更准确地说,它是后端数据库配额上限;提高配额无法修复慢盘。快照恢复必须先在隔离环境完成验证,碎片整理需遵循逐成员操作原则,绝不可同时处理全部生产成员。
7. 验收不是截图:把“可用”翻译成可测量标准
所有阈值应由业务等级和已批准的 SLO 决定,下面是验收表应包含的字段,而不是通用承诺值。
| 验收域 |
测试动作 |
必须记录的证据 |
验收阈值示例字段 |
| API 高可用 |
摘除一个控制平面或一个 LB 后访问 VIP |
时间戳、健康检查、API 请求结果、恢复记录 |
最大切换时长、允许失败请求数 |
| etcd 恢复 |
从快照在隔离环境恢复并校验集群对象 |
快照 ID、恢复日志、对象比对、耗时 |
平台 RTO、控制面 RPO |
| 网络 |
跨节点 Pod、Service、DNS、策略阻断/放通 |
用例结果、延迟/丢包、策略 YAML |
连通率、解析时延、允许丢包 |
| 存储 |
PVC 创建、重挂、节点故障后的恢复 |
PVC/PV 事件、数据校验、耗时 |
恢复时间、数据完整性 |
| 离线能力 |
在断开外网条件下扩缩容并拉取镜像 |
出口 ACL、拉取日志、镜像 digest |
零外连、镜像命中率 |
| 告警与审计 |
注入节点、磁盘、证书或仓库故障 |
告警时间线、工单、审计日志 |
告警时限、留存期限 |
| 中间件 |
按业务手册进行副本/节点故障与恢复 |
应用状态、数据校验、恢复日志 |
业务 RTO/RPO、允许数据丢失 |
完成演练后,要把被摘除的节点、入口和冗余能力恢复到完整状态。验收报告不仅记录“通过”,还需记录执行人、时间、制品版本、环境差异、实际耗时、遗留风险、风险接受人和下一步变更窗口。
8. 交接包:让下一班人也能恢复系统
一个合格的交接包至少包含以下附件:
- 版本矩阵与软件物料清单(SBOM/镜像清单);
- 网络、端口、DNS、VIP、负载均衡与存储拓扑;
- 节点资产表、容量基线、账号与责任矩阵;
- kubeadm、containerd、CNI、CSI、Harbor、监控和中间件的最终配置;
- 离线制品 manifest、哈希、签名、扫描与审批证据;
- 日常巡检、证书轮换、补丁升级、扩容和回退 Runbook;
- etcd、Harbor、证书、Nacos/Kafka 数据的备份与恢复 Runbook;
- 本次故障演练与验收记录、遗留问题、联系人及下一补丁窗口。
恢复文档必须分别覆盖证书、etcd 快照、Harbor 数据和中间件数据;不同恢复对象的备份介质与解密密钥应放在不同故障域。否则“有备份”很容易在真正故障时变成不可恢复。
结语:可复制的是闭环,不是一条命令
离线信创 Kubernetes 的交付能力,来自将 OS、内核、架构、镜像、网络、存储、备份和恢复动作提前逐项验证。72 小时现场窗口的价值,不是制造一次冒险式安装,而是验证一套早已准备好的工程系统。
当输入确定、制品可追溯、过程可复现、验收可量化、故障可恢复时,集群才值得被称为生产级。断网环境会放大每一个遗漏,但也迫使团队把依赖互联网临时补救的经验,沉淀为真正可靠的交付机制。
参考资料
- Kubernetes:kubeadm 高可用集群
- Kubernetes:容器运行时与 cgroup 驱动
- Kubernetes:kubeadm 配置 API
- containerd:Registry hosts 配置
- Cilium:系统要求
- etcd:运维指南