基于Helm Chart实现跨Windows/Linux K8s集群的资源部署适配
解决方案
我们可以通过Helm的条件模板语法结合节点标签/显式配置参数来实现这个需求,以下是两种可行的实现方式:
方案一:通过values.yaml显式指定集群类型
这种方式需要部署时根据集群类型传入对应参数,适合集群环境明确的场景。
1. 在values.yaml中添加集群类型配置
# values.yaml cluster: osType: "windows" # 可选值:windows / linux
2. 编写主模板文件(示例:templates/workload.yaml)
{{- if eq .Values.cluster.osType "windows" }} apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "mychart.fullname" . }} labels: {{- include "mychart.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "mychart.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "mychart.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} nodeSelector: kubernetes.io/os: windows containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.containerPort }} ports: - name: http containerPort: {{ . }} protocol: TCP {{- end }} {{- else }} apiVersion: apps/v1 kind: DaemonSet metadata: name: {{ include "mychart.fullname" . }} labels: {{- include "mychart.labels" . | nindent 4 }} spec: selector: matchLabels: {{- include "mychart.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "mychart.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} nodeSelector: kubernetes.io/os: linux containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.containerPort }} ports: - name: http containerPort: {{ . }} protocol: TCP {{- end }} {{- end }}
3. 部署命令
- Windows集群:
helm install my-release ./mychart --set cluster.osType=windows
- Linux集群:
helm install my-release ./mychart --set cluster.osType=linux
方案二:自动检测集群节点OS(无需手动传参)
通过Helm的lookup函数查询集群节点标签,自动判断当前集群的OS类型,适合不想手动指定参数的场景。
1. 在_helpers.tpl中添加检测函数
{{/* Detect the operating system of the Kubernetes cluster */}} {{- define "mychart.cluster.os" -}} {{- $nodes := lookup "v1" "Node" "" "" | default (dict "items" (list)) -}} {{- range $node := $nodes.items -}} {{- if index $node.metadata.labels "kubernetes.io/os" -}} {{- index $node.metadata.labels "kubernetes.io/os" -}} {{- break -}} {{- end -}} {{- end -}} {{- end -}}
2. 修改主模板文件(示例:templates/workload.yaml)
{{- $osType := include "mychart.cluster.os" . }} {{- if eq $osType "windows" }} apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "mychart.fullname" . }} labels: {{- include "mychart.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: {{- include "mychart.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "mychart.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} nodeSelector: kubernetes.io/os: windows containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.containerPort }} ports: - name: http containerPort: {{ . }} protocol: TCP {{- end }} {{- else }} apiVersion: apps/v1 kind: DaemonSet metadata: name: {{ include "mychart.fullname" . }} labels: {{- include "mychart.labels" . | nindent 4 }} spec: selector: matchLabels: {{- include "mychart.selectorLabels" . | nindent 6 }} template: metadata: {{- with .Values.podAnnotations }} annotations: {{- toYaml . | nindent 8 }} {{- end }} labels: {{- include "mychart.selectorLabels" . | nindent 8 }} spec: {{- with .Values.imagePullSecrets }} imagePullSecrets: {{- toYaml . | nindent 8 }} {{- end }} nodeSelector: kubernetes.io/os: linux containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.containerPort }} ports: - name: http containerPort: {{ . }} protocol: TCP {{- end }} {{- end }}
注意事项
- 使用
lookup函数需要Helm版本≥3.0,且部署时的ServiceAccount具备查询Node资源的权限。 - 若集群存在混合节点(题目已说明无此情况),该函数会取第一个匹配到的节点OS,可根据需求调整逻辑。
内容的提问来源于stack exchange,提问作者hare krshn
相关产品推荐
相关产品推荐

