2. K8s 核心对象回顾:Deployment、Service、ConfigMap、Secret 在迁移中的角色

跨环境迁移不仅仅是复制 YAML 文件,核心在于理解每个 K8s 对象在目标集群中的“身份”与“依赖”是否重建。Deployment、Service、ConfigMap、Secret 是迁移流水线中最常打交道的四个对象,它们在迁移中的职责各不相同。

2.1 四类核心对象迁移职责速览

对象 迁移核心关注点 是否需重建 常见迁移风险
Deployment 副本数、镜像版本、更新策略、资源配额 是(新集群无此资源) 镜像拉取策略不一致、PVC 绑定失败、节点资源不足
Service ClusterIP 是否保留、端口映射、类型(ClusterIP/NodePort/LB) 是(ClusterIP 通常变化) 依赖固定 IP 的客户端未更新、DNS 缓存未刷新
ConfigMap 键值对完整性、挂载路径、是否被多个工作负载引用 是(需重新 apply) 环境差异导致配置值错误、未同步敏感字段
Secret Base64 解码后内容、加密方式、证书有效期 是(需重新创建) 明文传输、证书过期、密钥轮换未同步
迁移原则:Deployment 和 Service 属于“有状态依赖”对象,迁移后必须验证 Pod 是否 Ready 以及 Endpoint 是否正常。ConfigMap 和 Secret 属于“数据注入”对象,迁移后必须校验挂载内容是否与源集群一致。

2.2 Deployment:工作负载的“搬家”核心

Deployment 定义了 Pod 的期望状态。迁移时,Deployment 的 YAML 几乎可以原封不动地 apply 到目标集群,但以下字段需要特别关注:

  • replicas:目标集群资源是否足够支撑原副本数?建议迁移初期先设为 1,验证通过后再恢复。
  • image:镜像仓库地址是否在目标集群可拉取?私有仓库需提前配置 imagePullSecrets。
  • strategy:滚动更新策略(maxSurge / maxUnavailable)在资源紧张时可能导致迁移失败。
  • volumes:如果引用了 PVC,目标集群必须提前创建好同名 PVC 或调整 volumeName。
# 迁移前检查 Deployment 关键字段
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: production
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    spec:
      containers:
      - name: app
        image: registry.example.com/my-app:v2.1.0
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1"
      volumes:
      - name: config
        configMap:
          name: app-config
      - name: tls
        secret:
          secretName: app-tls
迁移陷阱:如果源集群使用了 cluster-autoscaler,目标集群可能没有自动扩缩容能力。迁移后 Deployment 的 Pod 可能因节点资源不足而 Pending,务必在迁移前检查目标集群的节点容量。

2.3 Service:流量入口的“换址”挑战

Service 在迁移中最容易引发“断连”问题。因为 ClusterIP 是集群内部随机分配的,迁移后 Service 的 IP 地址必然改变。如果应用内部有硬编码 IP 或使用了 Headless Service,需要额外处理。

Service 类型 迁移影响 应对措施
ClusterIP IP 变化,内部 DNS 需重新解析 确保客户端使用 DNS 名称而非 IP
NodePort 端口号可能被占用,需重新分配 迁移时指定 port 或使用 LoadBalancer
LoadBalancer 云厂商 LB 重建,外部 DNS 需切换 提前配置 CNAME 指向新 LB DNS
Headless 无 ClusterIP,依赖 DNS 记录 确保 StatefulSet 的 Pod DNS 名称一致
迁移最佳实践:在目标集群先创建 Service,再创建 Deployment。这样 Service 的 Endpoint Controller 可以立即发现新 Pod,减少迁移窗口期的流量丢失。

2.4 ConfigMap 与 Secret:配置数据的“搬运”要点

ConfigMap 和 Secret 是纯数据对象,迁移时最容易忽略的是“数据一致性”和“引用关系”。

  • ConfigMap:使用 kubectl get configmap <name> -o yaml --export 导出时,注意 --export 已弃用,建议直接 -o yaml 并清理 resourceVersion、uid 等元数据。
  • Secret:data 字段是 Base64 编码,迁移前务必解码验证内容是否正确。如果使用了 stringData,导出时会被自动转为 data。
  • 引用检查:一个 ConfigMap 可能被多个 Deployment 引用。迁移后如果只迁移了 ConfigMap 但未更新所有引用的 Deployment,会导致 Pod 挂载旧数据。
# 导出 ConfigMap 并清理元数据
kubectl get configmap app-config -n production -o yaml | \
  grep -v 'resourceVersion\|uid\|selfLink\|creationTimestamp\|managedFields' > app-config-clean.yaml

# 在目标集群 apply
kubectl apply -f app-config-clean.yaml -n production
数据校验技巧:迁移后使用 kubectl exec 进入 Pod,检查 /etc/config 或挂载路径下的文件内容是否与源集群一致。对于 Secret,可以对比 Base64 解码后的 SHA256 值。

2.5 四类对象在迁移中的依赖关系

下图展示了 Deployment、Service、ConfigMap、Secret 在迁移时的创建顺序与依赖关系:

迁移创建顺序与依赖关系 ConfigMap 配置数据 Secret 敏感数据 Deployment 引用 ConfigMap / Secret 作为卷或环境变量 Service 通过 selector 绑定 Deployment 的 Pod 迁移顺序: 先创建 ConfigMap / Secret → 再创建 Deployment → 最后创建 Service 确保数据先就绪,工作负载再启动,流量最后接入

2.6 迁移前后对账清单

在跨环境迁移完成后,使用以下清单对四个核心对象进行对账:

  1. Deployment:kubectl get deployment -n <ns> -o wide 检查 READY 状态、镜像版本、副本数是否一致。
  2. Service:kubectl get svc -n <ns> 检查 CLUSTER-IP 是否分配、PORT(S) 是否匹配、ENDPOINTS 是否有 Pod IP。
  3. ConfigMap:kubectl get configmap <name> -n <ns> -o yaml 对比 data 字段的键值对。
  4. Secret:kubectl get secret <name> -n <ns> -o jsonpath='{.data}' | base64 -d 解码后对比内容。
自动化对账建议:在流水线中集成 kubectl diff 或 kyverno 策略引擎,在 apply 前自动对比源集群与目标集群的 YAML 差异,避免人工遗漏。