Kubernetes 默认命名空间迁移的零停机工程方法
来源:17golang原创
时间:2026-10-02 17:49:09 490浏览 收藏
Kubernetes 官方文档明确建议生产集群不要长期使用 default 命名空间。真正迁移时,最稳妥的做法不是修改现有对象的 namespace,也不是先删旧资源再建新资源,而是在目标命名空间并行重建一套可独立运行的应用,完成身份、配置、网络、DNS、存储和容量验收后,在入口层受控切流,并保留旧环境作为短期回滚路径。
官方文档:https://kubernetes.io/docs/
这个结论来自 Kubernetes 的对象模型:Deployment、Service、ConfigMap、Secret、ServiceAccount 等对象是命名空间级资源,对象身份包含 API 资源类型、namespace 和 name。把应用从 default 搬到 app-prod,本质上是在新作用域创建新对象,而不是给原对象换一个目录。
一、三种迁移路线怎么选
命名空间迁移常见有三种做法。它们表面上都能得到“资源出现在新 namespace”这个结果,但可用性和回滚能力完全不同。

| 路线 | 可用性 | 主要风险 | 适用场景 |
|---|---|---|---|
| 先删旧资源,再在新命名空间创建 | 必然出现窗口期 | 新 Pod 启动、探针、镜像拉取或权限失败时无法快速恢复 | 允许停机的测试环境 |
| 导出清单,批量修改 namespace 后直接应用 | 可能并行,但不可控 | 遗漏 ServiceAccount、RoleBinding、Secret、PVC、DNS 和入口配置 | 依赖很少的临时服务 |
| 从版本库重建新环境,并行验收后切流 | 可以做到业务无感 | 需要额外容量和明确的入口切换机制 | 生产环境默认选择 |
推荐第三种路线还有一个原因:旧环境保持不动,新环境的每项修正都可以单独验证。若切流后错误率、延迟或业务指标异常,只需恢复入口路由,不必在故障现场重新拼装旧资源。
二、先做资源与依赖盘点
不要把 kubectl get all 当成完整清单。它不会覆盖 Secret、ConfigMap、Role、RoleBinding、NetworkPolicy、PodDisruptionBudget、HorizontalPodAutoscaler、Ingress、PVC 以及 CRD 实例等全部对象。更可靠的做法是先区分命名空间级和集群级资源,再围绕应用标签盘点。
# 查看当前集群中哪些 API 资源属于命名空间作用域 kubectl api-resources --namespaced=true # 按应用标签盘点核心工作负载和服务,避免把 default 中无关对象一起迁移 kubectl get deploy,sts,ds,svc,ingress,pdb,hpa \ -n default -l app.kubernetes.io/part-of=my-app # 单独检查配置、身份、策略和存储引用 kubectl get configmap,secret,serviceaccount,role,rolebinding,networkpolicy,pvc \ -n default -l app.kubernetes.io/part-of=my-app
这一步至少要把对象分成三类:
- 需要在新命名空间重建:Deployment、Service、ConfigMap、Secret、ServiceAccount、RoleBinding、NetworkPolicy、PDB、HPA、Ingress 等。
- 可能继续共享:Node、StorageClass、PersistentVolume、ClusterRole、CRD 等集群级资源,但要重新检查绑定和授权范围。
- 必须单独设计迁移:PVC、单写数据库、本地盘、队列消费者位点、定时任务和依赖固定 DNS 名称的组件。
Kubernetes 官方文档指出,PersistentVolume 是集群级资源,而 PersistentVolumeClaim 是命名空间级资源,Pod 会在自己的命名空间查找 PVC。不能因为 PV 仍在集群里,就假设把相同 PVC 清单复制到新 namespace 后会自动、安全地接管原数据。单写存储要先设计快照恢复、数据复制、只读窗口或应用级切换。
三、在新命名空间按依赖顺序重建
我通常按“命名空间策略 → 身份与权限 → 配置与凭据 → 网络策略 → 服务发现 → 工作负载 → 自动伸缩与中断预算 → 入口”的顺序创建。这样失败会尽量暴露在流量进入之前。
# 创建目标命名空间;名称应使用稳定、可读的 DNS 标签 kubectl create namespace app-prod # 先应用命名空间级基础对象,再部署工作负载 kubectl apply -n app-prod -f base/identity-and-policy.yaml kubectl apply -n app-prod -f base/config-and-secrets.yaml kubectl apply -n app-prod -f workload/ # 等待新 Deployment 达到可用状态,但此时仍不切生产入口 kubectl rollout status deployment/my-app -n app-prod --timeout=10m
这里不建议把从集群导出的完整 YAML 直接作为迁移源。实时对象通常包含 status、resourceVersion、uid、ownerReferences 等服务端字段,也可能把不应落盘的 Secret 暴露到临时文件。更好的方式是从 GitOps 或版本库中的声明式清单渲染目标环境,只把确实属于新命名空间的差异参数化。
ServiceAccount 和 RBAC 必须重新绑定
ServiceAccount 是命名空间级身份。每个 namespace 都有各自的 default ServiceAccount,自定义 ServiceAccount 也不会因为同名就继承旧 namespace 的权限。RoleBinding 只在它所在的命名空间授予权限,因此需要在 app-prod 重建,并检查 subject 中引用的 ServiceAccount namespace。
迁移时不要为了“先跑起来”临时改成 ClusterRoleBinding 或授予 cluster-admin。更宽的权限会掩盖原有依赖问题,也会扩大 Secret 和 API 访问范围。应保留最小权限,并在切流前用目标 ServiceAccount 验证真实调用。
短 DNS 名称会改变解析目标
Service 的完整 DNS 形式通常是 。Pod 只写 orders 时,会优先解析本命名空间中的同名 Service。因此,新旧命名空间并行期间,应用内部依赖可能自然切到新 namespace 的同名 Service,也可能因为缺少该 Service 而失败。
迁移前应把依赖分为“应随应用一起迁移”和“继续跨 namespace 访问”。后者在过渡期应使用命名空间限定名,例如 orders.default,或者完整 FQDN;等依赖也迁完后再切回目标地址。不要同时改 namespace 和大量业务配置,却不给每项依赖留下独立验证点。
四、切流前需要通过哪些验收
Pod 处于 Running 不等于应用能够接流量。Kubernetes 的 readiness probe 失败时,Pod 会从匹配 Service 的 EndpointSlice 可用端点中移除,这正是并行迁移时的核心门禁。新环境至少要有两个副本,并把 readiness 检查绑定到真实依赖是否可用,而不是只判断进程存在。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2 # 零停机需要并行容量,单副本无法抵御启动和切流抖动
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0 # 更新时不主动减少可用副本
maxSurge: 1 # 允许额外创建一个副本完成替换
template:
spec:
containers:
- name: app
image: registry.example.com/my-app:stable
readinessProbe:
httpGet:
path: /ready # 只在缓存、数据库等关键依赖可用时返回成功
port: 8080
periodSeconds: 5
failureThreshold: 3
上线前应逐项确认:
- 新 Deployment 的期望副本、就绪副本和可用副本一致。
- 新 Service 的 EndpointSlice 只包含已 Ready 的新 Pod。
- Pod 使用的是目标 namespace 的 ConfigMap、Secret 与 ServiceAccount。
- NetworkPolicy 允许必要的入口、DNS、数据库和外部 API 流量。
- 应用内短 DNS、FQDN、回调地址和消息队列消费者组符合并行期设计。
- 新旧环境同时运行时,不会重复执行 CronJob、一次性 Job、账务扣减或其他非幂等任务。
PodDisruptionBudget 可以约束一部分自愿中断,但不能把它当作此次迁移的兜底。官方文档明确说明,直接删除 Deployment 或 Pod 会绕过 PDB,而且 Deployment 自身滚动升级的可用性由工作负载策略控制。迁移的真正保障仍然是副本、探针、入口切换和回滚路径。
五、切流时保留一个明确的回滚窗口

切流点应该位于业务入口,而不是通过删除旧 Pod“逼迫”流量进入新环境。可选择的入口取决于现有架构:
- Ingress 或 Gateway:在目标 namespace 创建对应入口对象,再通过 DNS、Gateway 路由或控制器支持的权重能力切换。传统 Ingress 的 Service 后端通常与 Ingress 同 namespace,不能只修改一个跨 namespace 的 Service 名字。
- 外部负载均衡器:让新旧入口同时注册,先小比例观察,再完成切换。
- 服务网格:可做细粒度权重或按请求特征切流,但必须把控制面配置也纳入回滚方案。
- 纯 ClusterIP 内部服务:调用方需要显式更换 FQDN,或通过稳定的上层代理保持入口不变。
切流完成后不要立刻删除 default 中的旧资源。先将旧环境保留为热回滚路径,但暂停会产生重复副作用的 CronJob、消费者或写任务;观察一个能覆盖高峰流量和关键业务链路的窗口。回滚动作应只是恢复入口指向,而不是临时重新部署旧环境。
六、哪些情况不能承诺零停机
“零停机”不是修改几个 YAML 字段就自动获得的属性。下面这些情况要先完成额外改造:
- 应用只有一个副本,且启动时间长或没有 readiness probe。
- 新旧实例不能同时写同一份数据,数据库或文件系统也没有复制能力。
- PVC 绑定、访问模式或底层存储不允许在两个 namespace 的工作负载间并行使用。
- 消费者组、定时任务、回调注册或领导者选举在双跑时会产生重复操作。
- 入口控制器不支持平滑权重切换,而 DNS TTL 和客户端缓存又无法满足恢复时间目标。
- 容量不足,无法让新旧副本在同一集群同时运行。
对这些系统,更准确的目标是“可控停机”或“业务级双写与切换”,而不是把无状态服务的并行迁移步骤生搬过去。
七、最终决策表
| 约束 | 推荐做法 | 不建议做法 |
|---|---|---|
| 无状态 HTTP 服务,有多副本和稳定入口 | 新 namespace 并行部署、探针验收、入口切流 | 先删旧 Deployment |
| 跨 namespace 依赖较多 | 先使用限定 DNS,按依赖逐项迁移 | 只批量替换 YAML 中的 namespace 字符串 |
| 自定义 ServiceAccount 与最小权限 | 在目标 namespace 重建 ServiceAccount 和 RoleBinding | 临时授予 cluster-admin |
| 单写 PVC 或内嵌数据库 | 单独设计数据复制、快照恢复或停写窗口 | 复制 PVC 清单后假设自动接管数据 |
| 需要分钟级回滚 | 观察期内保留旧副本和旧路由 | 切流后立即清理 default |
这套方法的重点不是“把资源复制过去”,而是把迁移拆成两次独立决策:先证明新命名空间具备完整运行能力,再决定何时让流量进入。只要旧环境在观察期内保持可恢复、入口切换可逆、数据写入策略明确,命名空间整理就不必和业务中断绑定在一起。
-
214 收藏
-
478 收藏
-
484 收藏
-
151 收藏
-
396 收藏
-
151 收藏
-
345 收藏
-
107 收藏
-
232 收藏
-
386 收藏
-
355 收藏
-
293 收藏
-
137 收藏
-
146 收藏
-
113 收藏
-
369 收藏
-
102 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习