K8s Deployment添加volumes配置后报spec.containers必填值错误
报错原因
报错核心原因是Helm模板的条件判断(if)配对范围错误,导致特定场景下渲染出的Deployment YAML中spec.template.spec.containers字段完全缺失,触发K8s API的必填字段校验失败。
具体错误点:
- 你在
volumes字段前添加的{{- if not .Values.developerMode }}判断没有在volumes配置结束后及时闭合,错误地将同级的containers、nodeSelector、tolerations字段全部纳入了该条件块的作用范围。当.Values.developerMode为true时,整个containers段不会被渲染,最终生成的Pod spec中没有容器定义,直接触发必填报错。 - 容器内部
volumeMounts前的{{- if not .Values.developerMode }}判断也没有在volumeMounts配置结束后及时闭合,错误将livenessProbe、readinessProbe纳入条件块,开启开发者模式时探针配置也会丢失。 - 添加配置前Deployment可以正常运行,是因为当时不存在这个包裹范围错误的条件判断,
containers字段始终会被渲染。
注:Go模板的条件配对和YAML缩进无关,只按{{if}}和{{end}}的出现顺序就近配对,因此缩进对齐不代表条件范围正确。
修复方法
调整条件判断的包裹范围,确保containers字段始终被渲染,仅将需要按开发者模式开关控制的volumes、volumeMounts字段单独包裹在条件块内,修正后的Deployment模板核心段如下:
apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "chart.fullname" . }} labels: {{- include "chart.labels" . | nindent 4 }} spec: selector: matchLabels: {{- include "chart.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "chart.selectorLabels" . | nindent 8 }} spec: securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }} # 仅volumes字段受开发者模式控制,块结束后立刻闭合if {{- if not .Values.developerMode }} volumes: - name: config-vol configMap: name: service-config {{- end }} # containers字段始终渲染,不放在任何条件块内 containers: - name: {{ .Chart.Name }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} image: "{{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- range .Values.env }} - name: {{ .name }} value: {{ .value | quote }} {{- end }} ports: - containerPort: {{ .Values.container.port }} resources: {{- toYaml .Values.resources | nindent 12 }} # 仅volumeMounts字段受开发者模式控制,块结束后立刻闭合if {{- if not .Values.developerMode }} volumeMounts: - mountPath: /src/config name: config-vol {{- end }} livenessProbe: httpGet: path: /health port: {{ .Values.service.targetPort }} initialDelaySeconds: 10 periodSeconds: 15 failureThreshold: 3 readinessProbe: httpGet: path: /health port: {{ .Values.service.targetPort }} initialDelaySeconds: 10 periodSeconds: 15 failureThreshold: 3 # nodeSelector、tolerations字段保持原有逻辑 {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: {{- toYaml . | nindent 8 }} {{- end }}
你的ConfigMap配置没有语法问题,不需要调整。修正后可以执行helm template命令本地渲染模板校验,确认无论developerMode为true还是false,生成的YAML中都存在containers字段,再执行部署即可。
内容的提问来源于stack exchange,提问作者Meilan
相关产品推荐
相关产品推荐

