如何通过Helm在EKS蓝绿部署中更新Deployment的route标签
解决EKS Helm蓝绿部署中切换路由时同步更新标签且不重建Pod的问题
核心需求分析
你需要在切换productionSlot时,同步更新蓝/绿两个Deployment及其Pod的route标签,但不想通过修改enabled字段触发Pod重建。
方案1:仅更新Deployment标签(无需Pod标签变更)
如果route标签仅用于标识Deployment而非Pod,可通过调整模板避免Pod重建:
步骤1:修改Deployment模板
将route标签仅保留在Deployment的元数据标签中,移除Pod模板中的route标签:
{{- define "blue-green-deploy.deployment" -}} {{- $currSlot := (pluck .currSlot .Values | first) }} {{- $isProduction := eq .currSlot .Values.productionSlot }} apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "blue-green-deploy.fullname" . }}-{{ .currSlot }} labels: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" app: {{ template "blue-green-deploy.name" . }} version: {{ $currSlot.appVersion | quote }} slot: {{ .currSlot }} route: {{ if $isProduction }}primary{{ else }}alt{{ end }} spec: replicas: {{ $currSlot.replicas | default 1 }} selector: matchLabels: app: {{ template "blue-green-deploy.name" . }} slot: {{ .currSlot }} template: metadata: labels: release: {{ .Release.Name }} app: {{ template "blue-green-deploy.name" . }} version: {{ $currSlot.appVersion | quote }} slot: {{ .currSlot }} # 移除此处的route标签,避免触发Pod重建 spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.name }}:{{ index .Values.image (printf "%s_tag" .currSlot) }}" ... {{- end }}
步骤2:保持部署槽位始终启用
首次部署后,确保values.yaml中blue.enabled和green.enabled均为true,避免Helm删除任一Deployment。
步骤3:执行路由切换
继续使用原命令切换路由:
helm upgrade test-app . --namespace test --install --set productionSlot=green --reuse-values --wait
此时Helm仅更新两个Deployment的元数据标签,不会修改Pod模板,因此不会触发Pod重建。
方案2:同步更新Pod标签(不重建Pod)
若必须更新Pod上的route标签,可通过Helm Post-Upgrade Hook执行kubectl patch修改Pod标签:
步骤1:创建标签更新Job(Hook)
在templates目录下创建patch-pod-labels.yaml:
apiVersion: batch/v1 kind: Job metadata: name: {{ include "blue-green-deploy.fullname" . }}-patch-pod-labels annotations: "helm.sh/hook": post-upgrade "helm.sh/hook-weight": "5" "helm.sh/hook-delete-policy": hook-succeeded spec: template: spec: restartPolicy: OnFailure serviceAccountName: {{ include "blue-green-deploy.fullname" . }}-patch-sa containers: - name: kubectl image: bitnami/kubectl:latest command: - /bin/sh - -c - | # 更新主槽位Pod的route标签为primary kubectl patch pods -l app={{ template "blue-green-deploy.name" . }},slot={{ .Values.productionSlot }} -p '{"metadata":{"labels":{"route":"primary"}}}' # 更新备槽位Pod的route标签为alt kubectl patch pods -l app={{ template "blue-green-deploy.name" . }},slot={{ if eq .Values.productionSlot "blue" }}green{{ else }}blue{{ end }} -p '{"metadata":{"labels":{"route":"alt"}}}'
步骤2:创建权限配置(RBAC)
在templates目录下创建rbac.yaml,赋予Job修改Pod标签的权限:
apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "blue-green-deploy.fullname" . }}-patch-sa --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ include "blue-green-deploy.fullname" . }}-patch-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["patch", "get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: {{ include "blue-green-deploy.fullname" . }}-patch-rb roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: {{ include "blue-green-deploy.fullname" . }}-patch-role subjects: - kind: ServiceAccount name: {{ include "blue-green-deploy.fullname" . }}-patch-sa namespace: {{ .Release.Namespace }}
步骤3:调整Deployment模板(初始标签)
确保首次部署时Pod的route标签正确:
{{- define "blue-green-deploy.deployment" -}} {{- $currSlot := (pluck .currSlot .Values | first) }} {{- $isProduction := eq .currSlot .Values.productionSlot }} apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "blue-green-deploy.fullname" . }}-{{ .currSlot }} labels: release: {{ .Release.Name }} chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" app: {{ template "blue-green-deploy.name" . }} version: {{ $currSlot.appVersion | quote }} slot: {{ .currSlot }} route: {{ if $isProduction }}primary{{ else }}alt{{ end }} spec: template: metadata: labels: release: {{ .Release.Name }} app: {{ template "blue-green-deploy.name" . }} version: {{ $currSlot.appVersion | quote }} slot: {{ .currSlot }} route: {{ if $isProduction }}primary{{ else }}alt{{ end }} ... {{- end }}
步骤4:执行路由切换
运行原helm upgrade命令,Hook会自动触发Job修改Pod标签,全程无需重建Pod。
内容的提问来源于stack exchange,提问作者CodeChimp
相关产品推荐
相关产品推荐

