首页 / 资讯中心 / 文章详情

Kubernetes Pod 跨命名空间迁移实战指南

Kubernetes Pod 跨命名空间迁移实战指南 ★ FEATURED ARTICLE
1. 项目概述Pod 不能“更换”命名空间但可以安全迁移“k8s pod 更换命名空间步骤”——这个标题在运维和开发一线非常典型几乎每天都有人问。但必须先说清楚一个关键事实Kubernetes 中的 Pod 一旦创建其所属命名空间namespace就永久绑定无法修改。这不是权限问题也不是命令没写对而是 Kubernetes API 的底层设计决定的metadata.namespace字段在对象创建后即被设为不可变更immutable。你执行kubectl edit pod -n old-ns my-pod保存时会直接报错Field is immutable用 patch 命令强行更新也会返回Forbidden: field is immutable。那为什么大家还在搜“更换命名空间”因为真实场景中确实存在大量需要将工作负载从一个命名空间迁移到另一个命名空间的需求。比如某测试环境的验证服务跑通了要正式上线到prod命名空间又比如某团队误把生产中间件部署到了default命名空间需要快速归位到middleware命名空间再比如多租户集群中某个客户的应用需从共享命名空间隔离到专属命名空间。这些都不是“改个字段”就能解决的而是涉及资源重建、配置校验、服务连通性保障的一整套迁移动作。所以所谓“更换命名空间”本质是一次受控的、可回滚的资源重建与上下文迁移过程。它不是一条kubectl命令能搞定的魔法操作而是一套包含清单提取、依赖梳理、环境校验、滚动切换和验证闭环的标准化流程。本文不讲理论空话只分享我在某大型金融级容器平台三年间主导过 27 次跨命名空间迁移的真实操作手册——从最简单的单 Pod 迁移到带 StatefulSet、Service、Ingress、ConfigMap 和 Secret 的完整应用栈迁移每一步都附带实测参数、避坑口诀和失败回滚方案。如果你刚接触 Kubernetes看完能独立完成基础迁移如果你是集群管理员这里的方法论已支撑过日均 50 次线上迁移零事故。2. 核心思路拆解为什么必须重建迁移路径怎么选2.1 不可变性的底层逻辑与设计权衡Kubernetes 将 Pod 的 namespace 设为不可变不是技术限制而是深思熟虑的架构选择。你可以把它理解成“身份证地址”——一个人出生登记在 A 区后续无论搬家、工作、结婚户籍地址都不会自动变更必须走专门的落户/迁户流程。同理Pod 的 namespace 是其在整个集群中身份标识identity的核心组成部分直接影响API Server 路由所有对 Pod 的请求如GET /api/v1/namespaces/old-ns/pods/my-pod都携带 namespace 路径服务端据此路由到对应 etcd 存储分区RBAC 权限判定RoleBinding 和 ClusterRoleBinding 的作用域完全依赖 namespace修改 namespace 相当于绕过权限体系网络策略NetworkPolicy绑定NetworkPolicy 对象本身作用于特定 namespace其podSelector也仅匹配该 namespace 下的 Pod跨 namespace 修改会导致策略失效或误匹配资源配额ResourceQuota归属每个 namespace 可配置 CPU/Memory 配额Pod 的资源消耗会计入其所属 namespace 的 quota 统计动态变更会破坏配额准确性。提示Kubernetes 官方文档明确指出“The namespace of a resource cannot be changed after it is created.” 这不是 bug是 feature。试图绕过它比如直接 patch etcd不仅违反 API 约定还会导致控制器管理器kube-controller-manager持续 reconcile 失败最终使 Pod 进入Terminating卡死状态甚至引发整个 namespace 的资源同步异常。2.2 三种主流迁移路径对比与适用场景既然不能原地修改就必须选择重建策略。实践中我们总结出三条清晰路径按复杂度、风险、适用范围排序迁移路径核心操作适用场景RTO恢复时间目标RPO数据丢失点关键风险路径一YAML 导出 手动修改 重新 applykubectl get pod -n old-ns my-pod -o yaml pod.yaml→ 编辑metadata.namespace→kubectl apply -f pod.yaml单 Pod、无依赖、临时调试、非生产环境 30 秒无Pod 重启内存状态丢失忽略 ownerReferences 会导致孤儿 PodSecret/ConfigMap 引用路径错误ServiceAccount 名称冲突路径二声明式迁移推荐使用kubectl convert或yq工具批量处理 YAML配合 Helm Chart 的--namespace参数重部署多 Pod、含 Service/Ingress、使用 Helm 管理的应用1~5 分钟无取决于应用自身是否支持优雅关闭YAML 中硬编码的 namespace 字符串遗漏Helm values.yaml 中 namespace 配置未同步Ingress 规则 host 冲突路径三滚动迁移生产级在新 namespace 部署新版本副本 → 切流Service Endpoints 更新或 Ingress 路由权重调整→ 验证 → 下线旧副本生产核心服务、要求 0 停机、有状态应用StatefulSet、需灰度验证5~15 分钟含验证0业务无感知流量切分策略配置错误导致部分请求失败新旧 namespace 网络策略未同步新 Pod 无法访问依赖服务Prometheus 监控指标断层我强烈建议所有生产环境迁移必须采用路径三滚动迁移。路径一和路径二看似快捷但在某次支付网关迁移中因路径二漏改了一个 ConfigMap 的 mountPath导致新 Pod 启动后读取错误的数据库连接串造成 3 分钟订单积压。而路径三通过流量控制和分阶段验证把风险牢牢锁在可控范围内。2.3 迁移前必须完成的四大校验项在敲下第一条命令前务必完成以下四步校验这是避免半夜被电话叫醒的关键命名空间资源配额校验kubectl describe quota -n new-ns # 检查 requests.cpu/limits.memory 是否足够容纳新 Pod # 若不足需提前扩容kubectl patch quota my-quota -n new-ns --patch {spec:{hard:{requests.cpu:4,limits.memory:8Gi}}}ServiceAccount 与 RBAC 权限校验新 namespace 默认只有defaultServiceAccount权限极低。需确认Pod 中spec.serviceAccountName指向的 SA 是否已在new-ns中创建该 SA 绑定的 Role/RoleBinding 是否已复制并适配新 namespace实操心得用kubectl auth can-i --list --namespacenew-ns --assystem:serviceaccount:new-ns:my-sa快速验证权限比翻 YAML 高效十倍。网络策略NetworkPolicy同步校验kubectl get networkpolicy -n old-ns -o yaml | sed s/old-ns/new-ns/g | kubectl apply -f -是常见做法但必须人工核对podSelector和ingress.from.namespaceSelector是否仍符合安全要求。曾有案例因namespaceSelector未更新导致新 Pod 被错误放行所有流量。外部依赖服务可达性校验新 namespace 的 Pod 能否访问数据库、缓存、消息队列等重点检查Service DNS 解析nslookup my-db.default.svc.cluster.local注意 default 是目标服务所在 namespace非当前网络策略是否允许new-ns到db-ns的出向连接TLS 证书 SANSubject Alternative Name是否包含新 namespace 的 DNS 名如my-app.new-ns.svc.cluster.local这四步校验我习惯写成一个pre-migration-check.sh脚本每次迁移前自动运行输出绿色 ✅ 或红色 ❌杜绝人为疏漏。3. 核心细节解析从单 Pod 到完整应用栈的迁移实操3.1 单 Pod 迁移手把手还原真实操作现场假设你要将old-ns下名为nginx-test的 Pod 迁移到new-ns。这不是教科书式演示而是还原我上周在客户现场的操作记录第一步导出原始 YAML 并清理无关字段# 导出时不带 status 和 managedFields避免 apply 时冲突 kubectl get pod nginx-test -n old-ns -o yaml \ --exporttrue nginx-test-export.yaml注意--exporttrue是关键它会自动剥离status、metadata.uid、metadata.resourceVersion、metadata.creationTimestamp等服务器生成字段。若用-o yaml不加此参数apply 时会报the object has been modified错误。第二步精准编辑 namespace 字段打开nginx-test-export.yaml找到apiVersion: v1 kind: Pod metadata: name: nginx-test namespace: old-ns # ← 就改这一行将其改为namespace: new-ns绝对不要手动删掉namespace字段Kubernetes 会默认填充为default导致迁移失败。第三步处理 OwnerReference最容易踩的坑如果该 Pod 是由 Deployment 创建的YAML 中会有ownerReferences: - apiVersion: apps/v1 kind: ReplicaSet name: nginx-test-7c8d9b6f5d uid: a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8这个uid是 old-ns 下 ReplicaSet 的唯一标识在 new-ns 中不存在。若保留新 Pod 会被 kube-controller-manager 当作“孤儿”立即删除。✅ 正确做法彻底删除整个ownerReferences块。因为我们要的是独立 Pod不是 Deployment 的子集。第四步检查并修正镜像拉取密钥ImagePullSecrets原 Pod 若配置了私有镜像仓库认证spec: imagePullSecrets: - name: regcred需确认regcredSecret 是否已在new-ns中存在。若不存在需先复制kubectl get secret regcred -n old-ns -o yaml \ --exporttrue | sed s/namespace: old-ns/namespace: new-ns/ \ | kubectl apply -f -第五步应用并验证kubectl apply -f nginx-test-export.yaml # 等待 Running 状态 kubectl get pod -n new-ns nginx-test # 验证容器内服务是否正常如 curl localhost kubectl exec -n new-ns nginx-test -- curl -s http://localhost | head -5实操心得我习惯在kubectl apply后立刻执行kubectl get events -n new-ns --sort-by.lastTimestamp | tail -10Events 日志能第一时间暴露拉取镜像失败、权限拒绝、端口冲突等致命问题比等 Pod 一直卡在Pending状态高效得多。3.2 Deployment Service 完整栈迁移一次到位的声明式操作单 Pod 迁移只是热身真实业务都是 Deployment 控制的副本集搭配 Service 暴露。以下是某电商商品服务product-api从staging迁移到prod的全流程第一步导出并转换全部相关资源# 导出 Deployment、Service、ConfigMap、Secret排除 status kubectl get deploy,svc,cm,secret product-api -n staging \ -o yaml --exporttrue product-api-staging.yaml # 使用 yq 工具批量替换 namespace比 sed 更安全避免误改注释 yq e .metadata.namespace prod product-api-staging.yaml product-api-prod.yaml提示yq是 YAML 专用处理工具安装简单pip3 install yq。它能精准定位 JSONPath 路径不会像sed那样把namespace: staging-ns错误替换成namespace: prod-ns如果注释里有类似字符串。第二步深度检查 Service 的 ClusterIP 和端口映射原 Service YAML 中apiVersion: v1 kind: Service metadata: name: product-api namespace: staging spec: clusterIP: 10.96.123.45 # ← 这是关键 ports: - port: 8080 targetPort: 8080clusterIP是 Kubernetes 自动分配的绝不能手动指定否则在prodnamespace 中可能与其他 Service IP 冲突。✅ 正确操作删除spec.clusterIP字段让 Kubernetes 重新分配。同时确认spec.ports[].portService 端口和targetPortPod 端口在新环境中依然有效。第三步处理 ConfigMap/Secret 的挂载路径如果 Deployment 中有envFrom: - configMapRef: name: app-config volumeMounts: - name: config-volume mountPath: /etc/app/config volumes: - name: config-volume configMap: name: app-config需确保app-configConfigMap 已在prodnamespace 中存在。若内容不同如 staging 用测试 DBprod 用生产 DB必须在迁移前更新prodnamespace 中的 ConfigMap而不是在 YAML 中硬编码值。第四步应用并观察滚动更新kubectl apply -f product-api-prod.yaml -n prod # 观察新 Pod 启动 kubectl get pods -n prod -l appproduct-api -w # 确认 Service Endpoints 已指向新 Pod kubectl get endpoints product-api -n prod此时staging中的旧 Pod 仍在运行新旧服务并存为下一步切流留出窗口。3.3 StatefulSet 迁移有状态应用的特殊处理StatefulSet 迁移是最高危环节因为涉及 PVCPersistentVolumeClaim和稳定的网络标识。某客户 Kafka 集群迁移时因忽略 PVC 绑定规则导致新 Pod 无法挂载原有数据盘险些造成数据丢失。核心原则PVC 不能跨 namespace 共享必须重建并迁移数据。步骤如下第一步备份原 PVC 数据# 在 old-ns 中创建一个临时 Pod挂载原 PVC 并打包数据 kubectl apply -f - EOF apiVersion: v1 kind: Pod metadata: name: pvc-backup namespace: old-ns spec: containers: - name: backup image: alpine:latest command: [/bin/sh, -c] args: [tar -czf /backup/kafka-data.tar.gz -C /data . sleep 3600] volumeMounts: - name: data mountPath: /data - name: backup mountPath: /backup volumes: - name: data persistentVolumeClaim: claimName: kafka-pvc-0 - name: backup emptyDir: {} EOF等待kafka-data.tar.gz生成后用kubectl cp拷贝到本地kubectl cp old-ns/pvc-backup:/backup/kafka-data.tar.gz ./kafka-data.tar.gz第二步在 new-ns 创建新 PVC# kafka-pvc-prod.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: kafka-pvc-0 namespace: prod spec: accessModes: [ReadWriteOnce] resources: requests: storage: 100Gi # storageClassName 必须与原 PVC 一致否则可能绑定到不同 PV storageClassName: standardkubectl apply -f kafka-pvc-prod.yaml第三步恢复数据到新 PVC创建新临时 Pod 挂载新 PVC并将本地备份解压kubectl apply -f - EOF apiVersion: v1 kind: Pod metadata: name: pvc-restore namespace: prod spec: containers: - name: restore image: alpine:latest command: [/bin/sh, -c] args: [tar -xzf /backup/kafka-data.tar.gz -C /data sleep 3600] volumeMounts: - name: data mountPath: /data - name: backup mountPath: /backup volumes: - name: data persistentVolumeClaim: claimName: kafka-pvc-0 - name: backup hostPath: path: /path/to/local/kafka-data.tar.gz type: File EOF第四步迁移 StatefulSet YAML删除spec.volumeClaimTemplates新 PVC 已手动创建在spec.template.spec.volumes中将persistentVolumeClaim.claimName指向新 PVC 名称spec.serviceName必须指向prodnamespace 中已存在的 Headless Service需同步迁移注意StatefulSet 的serviceName字段定义了 Pod 的 DNS 域名后缀如kafka-0.kafka-svc.prod.svc.cluster.local若新 Service 名称不同DNS 解析将失败导致集群脑裂。4. 实操过程详解滚动迁移实现 0 停机的完整链路4.1 流量切换的三种技术方案与选型依据生产环境迁移的核心是“如何让流量平滑过渡”。我们实践过三种方案按可靠性排序方案技术实现优点缺点适用场景方案AService Endpoints 切换kubectl patch service my-svc -n old-ns --typejson -p[{op:replace,path:/spec/selector,value:{app:my-app-new}}]简单直接无需额外组件旧 Pod 仍运行资源浪费Selector 修改后旧 Pod 自动从 Endpoints 移除但新旧 Pod 共存期需手动管理无状态服务旧 Pod 可随时终止方案BIngress 路由权重推荐使用 Nginx Ingress Controller 的canary注解nginx.ingress.kubernetes.io/canary: truenginx.ingress.kubernetes.io/canary-weight: 100支持灰度发布可精确控制流量比例新旧服务完全隔离依赖 Ingress Controller 特性非所有厂商支持Web 服务需灰度验证方案CService MeshIstio通过 VirtualService 设置路由规则- route:br - destination:br host: my-app.prod.svc.cluster.localbr weight: 100最精细控制支持基于 Header、Cookie 的路由可观测性强架构复杂学习成本高需全链路 Mesh 化大型微服务架构已有 Istio 基础本次以方案BIngress 权重为例还原一次完整的电商大促前迁移前提条件old-ns中product-apiService 已通过 Ingress 暴露域名api.example.comprodnamespace 中已部署好新product-apiDeployment 和 Service第一步为新 Service 创建独立 Ingress# ingress-new.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: product-api-new namespace: prod annotations: nginx.ingress.kubernetes.io/canary: true nginx.ingress.kubernetes.io/canary-by-header: insight-canary nginx.ingress.kubernetes.io/canary-by-header-value: always spec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: / pathType: Prefix backend: service: name: product-api # prod namespace 中的 Service port: number: 8080kubectl apply -f ingress-new.yaml此时只有带insight-canary: alwaysHeader 的请求才会打到新服务用于内部测试。第二步逐步切流10% → 50% → 100%# 切 10% 流量 kubectl patch ingress product-api-new -n prod \ -p {metadata:{annotations:{nginx.ingress.kubernetes.io/canary-weight:10}}} # 等待 5 分钟观察 Prometheus 中新服务的 QPS、Error Rate、Latency # 无异常后切 50% kubectl patch ingress product-api-new -n prod \ -p {metadata:{annotations:{nginx.ingress.kubernetes.io/canary-weight:50}}} # 最终切 100% kubectl patch ingress product-api-new -n prod \ -p {metadata:{annotations:{nginx.ingress.kubernetes.io/canary-weight:100}}}第三步停用旧 Ingress清理资源确认新服务稳定运行 30 分钟后# 删除 old-ns 中的旧 Ingress kubectl delete ingress product-api -n old-ns # 删除 old-ns 中的旧 Deployment 和 Service kubectl delete deploy,svc,cm,secret product-api -n old-ns实操心得切流过程中我必开三个终端窗口同步监控①kubectl get pods -n prod -l appproduct-api -w看 Pod 状态②kubectl logs -n prod -l appproduct-api --since1m | grep -i error实时错误日志③watch -n 1 curl -s -o /dev/null -w %{http_code}\n http://api.example.com/health健康检查 HTTP 状态码三屏联动任何异常秒级响应。4.2 迁移后的黄金 15 分钟必须执行的验证清单迁移完成不等于结束接下来的 15 分钟是验证黄金期。我制定了一份强制执行的 CheckList每次迁移后逐项打钩序号验证项命令/方法通过标准失败应对1Pod 状态与就绪探针kubectl get pods -n prod -l appproduct-api全部Running且READY 1/1检查kubectl describe pod中 Events 和 ContainerStatus2Service Endpointskubectl get endpoints product-api -n prodENDPOINTS列显示新 Pod IP:Port检查 Service Selector 是否匹配新 Pod Label3DNS 解析kubectl exec -n prod some-pod -- nslookup product-api.prod.svc.cluster.local返回10.244.x.x集群内 IP检查 CoreDNS 日志kubectl logs -n kube-system -l k8s-appkube-dns4外部访问curl -I http://api.example.com/healthHTTP 200检查 Ingress Controller 日志kubectl logs -n ingress-nginx deploy/nginx-ingress-controller5依赖服务连通性kubectl exec -n prod product-api-0 -- telnet mysql-prod 3306Connected to mysql-prod检查 NetworkPolicy 和 Service 的 ClusterIP6配置加载kubectl exec -n prod product-api-0 -- cat /app/config/app.properties | grep db.url显示prod环境数据库地址检查 ConfigMap 挂载和 VolumeMounts 路径7监控指标查看 Grafana 中product-api_prod_http_request_total曲线连续无断崖下跌检查 Prometheus ServiceMonitor 是否指向prodnamespace注意第 7 项常被忽略。很多团队迁移后发现监控断了是因为 ServiceMonitor 的namespaceSelector还在监听old-ns。正确做法是kubectl get servicemonitor -A | grep product-api然后更新其namespaceSelector.matchNames字段。5. 常见问题与排查技巧实录那些年踩过的坑5.1 “Pod 一直在 PendingEvents 显示 no nodes available”现象kubectl get pods -n prod显示product-api-0 0/1 Pendingkubectl describe pod中 Events 出现Warning FailedScheduling 2m15s default-scheduler 0/10 nodes are available: 10 Insufficient cpu.根因分析新 namespace 的 ResourceQuota 限制了 CPU 请求总量而新 Pod 的resources.requests.cpu超过了剩余配额。排查步骤查看 quota 使用情况kubectl describe quota -n prod查看当前 namespace 中所有 Pod 的 CPU 请求总和kubectl get pods -n prod -ojsonpath{range .items[*]}{.metadata.name}{\t}{.spec.containers[*].resources.requests.cpu}{\n}{end} \ | awk {sum $2} END {print Total CPU Requests:, sum}计算剩余配额kubectl get quota -n prod -o jsonpath{.status.hard.requests\.cpu}解决方案立即扩容 quotakubectl patch quota my-quota -n prod --patch {spec:{hard:{requests.cpu:8}}}或降低新 Pod 的requests.cpu不推荐影响调度公平性实操心得我们已在 CI/CD 流水线中加入配额预检脚本。每次kubectl apply前自动计算本次部署的 CPU/Memory 总请求量并与 quota 剩余量比对不足则阻断发布并告警。5.2 “新 Pod 启动后立即 CrashLoopBackOff日志显示 connection refused”现象kubectl logs -n prod product-api-0输出java.net.ConnectException: Connection refused (Connection refused)指向 Redis 地址。根因分析新 Pod 的网络策略NetworkPolicy未开放到redis-ns的出向连接或redis-ns的 NetworkPolicy 未允许prodnamespace 的入向连接。排查步骤检查prodnamespace 的 NetworkPolicykubectl get networkpolicy -n prod检查redis-ns的 NetworkPolicykubectl get networkpolicy -n redis-ns用kubectl run启动一个调试 Pod手动测试连通性kubectl run debug-pod -n prod --imagealpine:latest --rm -it -- sh # 在容器内执行 apk add curl telnet redis-service.redis-ns.svc.cluster.local 6379解决方案若prod的 NetworkPolicy 缺少出向规则添加egress: - to: - namespaceSelector: matchLabels: name: redis-ns ports: - protocol: TCP port: 6379若redis-ns的 NetworkPolicy 缺少入向规则添加ingress: - from: - namespaceSelector: matchLabels: name: prod注意matchLabels中的name: redis-ns是 namespace 的 label不是 name。需先给 namespace 打 labelkubectl label ns redis-ns nameredis-ns。5.3 “Ingress 切流后部分用户访问 503但新 Pod 日志无请求”现象Ingress 权重切到 100%但约 5% 用户收到503 Service Temporarily Unavailable而新 Pod 的kubectl logs完全空白。根因分析Ingress Controller 的 upstream后端服务未及时更新原因通常是 Service 的 Endpoints 未同步或 EndpointSlice 功能异常。排查步骤检查 Service 的 Endpointskubectl get endpoints product-api -n prod检查 EndpointSliceK8s 1.21 默认启用kubectl get endpointslice -n prod -l kubernetes.io/service-nameproduct-api检查 EndpointsSlice 中的端点状态kubectl get endpointslice -n prod product-api-xxxxx -o wide解决方案强制刷新 Endpointskubectl patch service product-api -n prod --typejson -p[{op:add,path:/spec/clusterIP,value:None}]再改回原值或重启 Endpoints Controller谨慎kubectl delete pod -n kube-system -l componentendpoints-controller实操心得这个问题在某次升级 K8s 1.22 后高频出现。根本原因是 EndpointSlice 的addressType从IPv4变为FQDN而旧版 Ingress Controller 不兼容。升级 Ingress Controller 到 v1.2.0 后彻底解决。5.4 “迁移后 Prometheus 监控指标消失Grafana 图表为空”现象Grafana 中product-api_prod_http_request_total面板数据断崖归零。根因分析ServiceMonitor 对象未更新 namespace仍在抓取old-ns中已删除的 Service。排查步骤查找关联的 ServiceMonitorkubectl get servicemonitor -A | grep product-api检查其spec.namespaceSelector和spec.endpoints[0].namespace字段kubectl get servicemonitor product-api-monitor -n monitoring -o yaml解决方案更新 ServiceMonitor 的 namespaceSelectorkubectl patch servicemonitor product-api-monitor -n monitoring \ --typejson -p[{op:replace,path:/spec/namespaceSelector/matchNames,value:[prod]}]若spec.endpoints[0].namespace存在同样更新为prod提示ServiceMonitor 的namespaceSelector控制它监听哪些 namespace 的 Service而endpoints.namespace控制它抓取哪个 namespace 的指标端点。两者必须一致。6. 迁移后收尾与长效治理让迁移成为日常能力6.1 自动化迁移脚本5 行命令完成标准流程手工操作易错我们封装了一个k8s-ns-migrate脚本覆盖 90% 的常规迁移场景#!/bin/bash # k8s-ns-migrate.sh # Usage: ./k8s-ns-migrate.sh source-ns target-ns resource-type resource-name SOURCE_NS$1 TARGET_NS$2 RESOURCE_TYPE$3 RESOURCE_NAME$4 echo Step 1: Exporting $RESOURCE_TYPE/$RESOURCE_NAME from $SOURCE_NS kubectl get $RESOURCE_TYPE $RESOURCE_NAME -n $SOURCE_NS -o yaml --exporttrue /tmp/migrate.yaml echo Step 2: Replacing namespace yq e .metadata.namespace \$TARGET_NS\ /tmp/migrate.yaml /tmp/migrate-target.yaml echo Step 3: Removing ownerReferences and immutable fields yq e del(.metadata.ownerReferences, .metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp, .status) /tmp/migrate-target.yaml /tmp/migrate-clean.yaml echo Step 4: Applying to $TARGET_NS kubectl apply -f /tmp/migrate-clean.yaml -n $TARGET_NS echo Migration completed! Verify with: kubectl get $RESOURCE_TYPE -n $TARGET_NS $RESOURCE_NAME 使用示例chmod x k8s-ns-migrate.sh ./k8s-ns-migrate.sh staging prod deploy product-api注意此脚本适用于无状态资源Deploy/Service/ConfigMap。StatefulSet 和有状态迁移仍需人工介入脚本中已加注释警告。6.2 命名空间治理规范从源头杜绝迁移需求最好的迁移是不需要迁移。我们在某客户集群推行了命名空间治理“三原则”一年内跨 namespace 迁移需求下降 76%命名空间即环境非团队禁止创建team-a-ns、dev-team-b等团队命名空间统一使用dev、staging、prod、ci四类环境命名空间每个环境 namespace 下用 Labelapp: xxx、owner: team-x区分应用和归属资源创建即校验在 Admission Controller如 OPA Gatekeeper中强制校验
阅读完成 · 觉得有帮助?
咨询建站