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 在迁移时的创建顺序与依赖关系:
2.6 迁移前后对账清单
在跨环境迁移完成后,使用以下清单对四个核心对象进行对账:
- Deployment:
kubectl get deployment -n <ns> -o wide检查 READY 状态、镜像版本、副本数是否一致。 - Service:
kubectl get svc -n <ns>检查 CLUSTER-IP 是否分配、PORT(S) 是否匹配、ENDPOINTS 是否有 Pod IP。 - ConfigMap:
kubectl get configmap <name> -n <ns> -o yaml对比 data 字段的键值对。 - Secret:
kubectl get secret <name> -n <ns> -o jsonpath='{.data}' | base64 -d解码后对比内容。
自动化对账建议:在流水线中集成
kubectl diff 或 kyverno 策略引擎,在 apply 前自动对比源集群与目标集群的 YAML 差异,避免人工遗漏。