Files
2025-11-30 09:05:12 +08:00

8.5 KiB

Helm Chart Templates

Complete template library. Load sections as needed. {{ CN }} = {{ CHART_NAME }} (abbreviated).

Chart.yaml

apiVersion: v2
name: {{ CHART_NAME }}
description: A Helm chart for {{ APP_DESCRIPTION }}
type: application
version: 0.1.0
appVersion: "1.0.0"

values.yaml

replicaCount: 1
image:
  repository: {{ IMAGE_REPO }}
  pullPolicy: IfNotPresent
  tag: "{{ IMAGE_TAG }}"
serviceAccount:
  create: true
  automount: true
podSecurityContext:
  runAsNonRoot: true
  runAsUser: 1000
  fsGroup: 1000
securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  capabilities:
    drop: [ALL]
service:
  type: ClusterIP
  port: {{ SERVICE_PORT }}
  targetPort: {{ CONTAINER_PORT }}
resources:
  limits: {cpu: 500m, memory: 256Mi}
  requests: {cpu: 50m, memory: 64Mi}
livenessProbe:
  httpGet: {path: /health, port: http}
  initialDelaySeconds: 30
readinessProbe:
  httpGet: {path: /ready, port: http}
  initialDelaySeconds: 5
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80

_helpers.tpl

{{- define "{{ CN }}.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "{{ CN }}.fullname" -}}
{{- if .Values.fullnameOverride }}{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}{{- end }}{{- end }}{{- end }}

{{- define "{{ CN }}.labels" -}}
helm.sh/chart: {{ include "{{ CN }}.chart" . }}
{{ include "{{ CN }}.selectorLabels" . }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- define "{{ CN }}.selectorLabels" -}}
app.kubernetes.io/name: {{ include "{{ CN }}.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{- define "{{ CN }}.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}{{- default (include "{{ CN }}.fullname" .) .Values.serviceAccount.name }}
{{- else }}{{- default "default" .Values.serviceAccount.name }}{{- end }}{{- end }}

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "{{ CN }}.fullname" . }}
  labels: {{- include "{{ CN }}.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}replicas: {{ .Values.replicaCount }}{{- end }}
  selector:
    matchLabels: {{- include "{{ CN }}.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels: {{- include "{{ CN }}.labels" . | nindent 8 }}
    spec:
      serviceAccountName: {{ include "{{ CN }}.serviceAccountName" . }}
      securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
      - name: {{ .Chart.Name }}
        securityContext: {{- toYaml .Values.securityContext | nindent 12 }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - name: http
          containerPort: {{ .Values.service.targetPort }}
        livenessProbe: {{- toYaml .Values.livenessProbe | nindent 12 }}
        readinessProbe: {{- toYaml .Values.readinessProbe | nindent 12 }}
        resources: {{- toYaml .Values.resources | nindent 12 }}

StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: {{ include "{{ CN }}.fullname" . }}
  labels: {{- include "{{ CN }}.labels" . | nindent 4 }}
spec:
  serviceName: {{ include "{{ CN }}.fullname" . }}-headless
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels: {{- include "{{ CN }}.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels: {{- include "{{ CN }}.labels" . | nindent 8 }}
    spec:
      serviceAccountName: {{ include "{{ CN }}.serviceAccountName" . }}
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        volumeMounts:
        - name: data
          mountPath: /data
  volumeClaimTemplates:
  - metadata: {name: data}
    spec:
      accessModes: [{{ .Values.persistence.accessMode | quote }}]
      storageClassName: {{ .Values.persistence.storageClass | quote }}
      resources:
        requests:
          storage: {{ .Values.persistence.size | quote }}

Add to values: persistence: {storageClass: standard, accessMode: ReadWriteOnce, size: 10Gi}

Job

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ include "{{ CN }}.fullname" . }}
  labels: {{- include "{{ CN }}.labels" . | nindent 4 }}
spec:
  backoffLimit: {{ .Values.job.backoffLimit | default 3 }}
  completions: {{ .Values.job.completions | default 1 }}
  template:
    metadata:
      labels: {{- include "{{ CN }}.labels" . | nindent 8 }}
    spec:
      restartPolicy: OnFailure
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

Add to values: job: {backoffLimit: 3, completions: 1, parallelism: 1}

CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: {{ include "{{ CN }}.fullname" . }}
  labels: {{- include "{{ CN }}.labels" . | nindent 4 }}
spec:
  schedule: {{ .Values.cronjob.schedule | quote }}
  successfulJobsHistoryLimit: {{ .Values.cronjob.successfulJobsHistoryLimit | default 3 }}
  failedJobsHistoryLimit: {{ .Values.cronjob.failedJobsHistoryLimit | default 1 }}
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: {{ .Chart.Name }}
            image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

Add to values: cronjob: {schedule: "0 2 * * *", successfulJobsHistoryLimit: 3, failedJobsHistoryLimit: 1}

Service

apiVersion: v1
kind: Service
metadata:
  name: {{ include "{{ CN }}.fullname" . }}
  labels: {{- include "{{ CN }}.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
  - port: {{ .Values.service.port }}
    targetPort: http
    name: http
  selector: {{- include "{{ CN }}.selectorLabels" . | nindent 4 }}

ServiceAccount

{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ include "{{ CN }}.serviceAccountName" . }}
  labels: {{- include "{{ CN }}.labels" . | nindent 4 }}
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
{{- end }}

Ingress

{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "{{ CN }}.fullname" . }}
  labels: {{- include "{{ CN }}.labels" . | nindent 4 }}
spec:
  {{- if .Values.ingress.className }}ingressClassName: {{ .Values.ingress.className }}{{- end }}
  rules:
  {{- range .Values.ingress.hosts }}
  - host: {{ .host | quote }}
    http:
      paths:
      {{- range .paths }}
      - path: {{ .path }}
        pathType: {{ .pathType }}
        backend:
          service: {name: {{ include "{{ CN }}.fullname" $ }}, port: {number: {{ $.Values.service.port }}}}
      {{- end }}
  {{- end }}
{{- end }}

HPA

{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: {{ include "{{ CN }}.fullname" . }}
spec:
  scaleTargetRef: {apiVersion: apps/v1, kind: Deployment, name: {{ include "{{ CN }}.fullname" . }}}
  minReplicas: {{ .Values.autoscaling.minReplicas }}
  maxReplicas: {{ .Values.autoscaling.maxReplicas }}
  metrics:
  - type: Resource
    resource: {name: cpu, target: {type: Utilization, averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}}}
{{- end }}

NOTES.txt

Thank you for installing {{ .Chart.Name }}!
Release: {{ .Release.Name }}
{{- if .Values.ingress.enabled }}
URL: http{{ if $.Values.ingress.tls }}s{{ end }}://{{ (index .Values.ingress.hosts 0).host }}
{{- else }}
Port forward: kubectl port-forward svc/{{ include "{{ CN }}.fullname" . }} {{ .Values.service.port }}
{{- end }}

.helmignore

.DS_Store
.git/
*.swp
.idea/
.vscode/

README.md

# {{ CHART_NAME }}

## Installation
helm install {{ CN }} .

## Testing
helm lint .
helm template {{ CN }} .
helm install {{ CN }} . --dry-run

Environment Values

values-dev.yaml:

replicaCount: 1
resources: {limits: {cpu: 200m, memory: 128Mi}, requests: {cpu: 25m, memory: 32Mi}}

values-prod.yaml:

replicaCount: 3
resources: {limits: {cpu: 1000m, memory: 512Mi}, requests: {cpu: 100m, memory: 128Mi}}
autoscaling: {enabled: true, minReplicas: 3, maxReplicas: 10}