Sobes.tech
Middle

What is your experience with using helm charts?

sobes.tech AI

Answer from AI

Developed and maintained Helm charts for deploying microservices and stateful applications in Kubernetes.

Main tasks:

  • Creating new charts from scratch, including templates for Deployment, Service (ClusterIP, NodePort, LoadBalancer), Ingress, ConfigMap, Secret, PersistentVolumeClaim, ServiceAccount, HorizontalPodAutoscaler, PodDisruptionBudget.
  • Parameterizing charts using .Values for flexible deployment configuration (images, ports, resources, labels, annotations, environment variables, Ingress configuration, etc.).
  • Working with chart dependencies (requirements.yaml or Chart.yaml in v3) for deploying complex applications.
  • Using hooks for performing additional actions before or after deployment (e.g., database migrations, pre-pull images).
  • Developing and applying chart tests (tests directory) to verify template and deployment correctness.
  • Integrating Helm into CI/CD pipelines (GitLab CI, Jenkins) for automatic build, linting, packaging, publishing, and deploying charts.
  • Managing Helm chart repositories (ChartMuseum, OCI registries).
  • Updating and rolling back Helm releases (helm upgrade, helm rollback), troubleshooting related issues.
  • Optimizing charts to reduce code duplication and improve readability using named templates (_helpers.tpl).
  • Managing secrets through Helm, including using third-party tools like HashiCorp Vault or secret operator injection.

Used various Helm versions, mainly working with v3. Familiar with Helm releases, revisions, and application state management with Helm. Experienced in creating complex charts involving multiple subcharts and configuring various system components.

Example structure of a simple Helm chart:

.
├── Chart.yaml          // Chart information
├── values.yaml         // Default values
├── templates           // Directory with Kubernetes object templates
│   ├── _helpers.tpl    // Named templates (optional)
│   ├── deployment.yaml // Deployment template
│   ├── service.yaml    // Service template
│   └── ingress.yaml    // Ingress template (if used)
└── charts              // Directory for dependent charts (optional)

Example fragment of values.yaml:

# values.yaml
replicaCount: 2

image:  
  repository: my-docker-repo/my-app  
  pullPolicy: IfNotPresent  
  # Overrides the image tag whose default is the chart appVersion.  
  tag: "latest"

service:  
  type: ClusterIP  
  port: 80

ingress:  
  enabled: false  
  className: ""  
  annotations:  
    kubernetes.io/ingress.class: nginx  
    # kubernetes.io/tls-acme: "true"  
  hosts:  
    - host: chart-example.local  
      paths:  
        - path: /  
          pathType: ImplementationSpecific  
  tls: []  
  #  - secretName: chart-example-tls  
  #    hosts:  
  #      - chart-example.local

Example fragment of deployment.yaml:

// templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-chart.fullname" . }} // Using named template for name
  labels:
    {{- include "my-chart.labels" . | nindent 4 }} // Using named template for labels
spec:
  replicas: {{ .Values.replicaCount }} // Parameterizing number of replicas
  selector:
    matchLabels:
      {{- include "my-chart.selectorLabels" . | nindent 6 }} // Using named template for selector
  template:
    metadata:
      {{- with .Values.podAnnotations }}
      annotations:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      labels:
        {{- include "my-chart.selectorLabels" . | nindent 8 }}
    spec:
      serviceAccountName: {{ include "my-chart.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 }}" // Parameterizing image and tag
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.service.port }} // Parameterizing port
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }} // Parameterizing resources