Gráficos do Helm: Gerenciamento de Pacotes do Kubernetes

Implantações do Kubernetes com gerenciamento de pacotes Helm

Helm revolucionou a implantação de aplicações no Kubernetes ao introduzir conceitos de gestão de pacotes familiares dos sistemas operacionais tradicionais.

À medida que a adoção do Kubernetes cresce, gerenciar aplicações complexas com dezenas de arquivos YAML torna-se desafiador. Os Helm Charts resolvem esse problema agrupando todos os recursos em pacotes versionados e configuráveis.

software-developer na natureza Esta imagem agradável foi gerada pelo modelo AI Flux 1 dev.

Entendendo o Helm: O Gestor de Pacotes do Kubernetes

O Helm é ao Kubernetes o que o apt é ao Debian, o yum ao RedHat ou o Homebrew ao macOS. Ele empacota aplicações Kubernetes em Charts – coleções de arquivos que descrevem recursos relacionados do Kubernetes. Um único Chart pode implantar uma pilha completa de aplicações: servidores web, bancos de dados, camadas de cache, regras de entrada e componentes de monitoramento. Para aqueles novos ao Kubernetes, uma Folha de Dicas do Kubernetes fornece comandos e conceitos essenciais para começar.

Por que o Helm importa no DevOps moderno

Redução da complexidade: Em vez de gerenciar 20+ arquivos YAML, você gerencia um único Chart com valores personalizáveis.

Reprodutibilidade: Implantar configurações idênticas em desenvolvimento, staging e produção com substituições de valores específicas do ambiente. Isso é especialmente valioso ao implantar arquiteturas complexas de microserviços onde a consistência importa.

Controle de versão: Os Charts são versionados, permitindo fácil rollback e rastreamento de atualizações.

Ecosistema da comunidade: Milhares de Charts pré-construídos estão disponíveis através do Artifact Hub (anteriormente Helm Hub) para aplicações populares como PostgreSQL, Redis, NGINX, Prometheus e mais.

Poder de modelagem: Templates Go permitem a geração dinâmica de recursos com base em valores de entrada, reduzindo a duplicação.

Arquitetura do Helm e Conceitos Principais

Arquitetura do Helm 3

A arquitetura do Helm 3 foi simplificada ao remover o Tiller, o componente problemático do lado do servidor do Helm 2:

  • Cliente Helm: Ferramenta CLI que interage diretamente com a API do Kubernetes
  • Chart: Formato de pacote contendo modelos e metadados
  • Lançamento: Uma instância de um Chart em execução em um cluster Kubernetes
  • Repositório: Local de armazenamento para Charts (servidor HTTP ou repositório OCI)

Componentes Principais de um Chart do Helm

my-app-chart/
├── Chart.yaml          # Metadados e versão do Chart
├── values.yaml         # Valores de configuração padrão
├── charts/             # Charts dependentes
├── templates/          # Modelos de recursos do Kubernetes
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── _helpers.tpl    # Funções de modelo
│   └── NOTES.txt       # Notas pós-instalação
├── .helmignore         # Arquivos a serem ignorados ao empacotar
├── README.md
└── LICENSE

Criando seu Primeiro Chart do Helm

Inicializar um Novo Chart

helm create my-application
cd my-application

Isso gera um Chart inicial com modelos de exemplo para implantação, serviço e entrada.

Chart.yaml: Definindo Metadados

apiVersion: v2
name: my-application
description: Um chart de aplicação pronto para produção
type: application
version: 1.0.0        # Versão do Chart
appVersion: "2.4.1"   # Versão da aplicação

maintainers:
  - name: Sua Equipe
    email: team@company.com

dependencies:
  - name: postgresql
    version: "12.x.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled

values.yaml: Gestão de Configuração

O arquivo values.yaml define configurações padrão que os usuários podem substituir. Esta abordagem separa a configuração dos modelos, tornando fácil gerenciar diferentes ambientes (desenvolvimento, staging, produção) e personalizar implantações sem modificar os arquivos de modelo.

replicaCount: 3

image:
  repository: myapp/backend
  tag: "1.0.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 10
  targetCPUUtilizationPercentage: 80

Modelos: Manifestos Dinâmicos do Kubernetes

Os modelos usam a sintaxe de modelagem Go para gerar dinamicamente recursos do Kubernetes. Esses modelos podem gerar qualquer tipo de recurso do Kubernetes, desde simples Deployments até complexos StatefulSets para aplicações que exigem armazenamento persistente. Para aplicações que precisam de identidades estáveis e volumes persistente, você desejará usar StatefulSets em vez de Deployments, conforme detalhado no nosso guia sobre StatefulSets e Armazenamento Persistente no Kubernetes.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-application.fullname" . }}
  labels:
    {{- include "my-application.labels" . | nindent 4 }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      {{- include "my-application.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "my-application.selectorLabels" . | nindent 8 }}
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: 8080
          protocol: TCP
        resources:
          {{- toYaml .Values.resources | nindent 10 }}

Funções de Modelo (_helpers.tpl)

Crie funções de modelo reutilizáveis para evitar repetição:

{{/*
Expanda o nome do chart.
*/}}
{{- define "my-application.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Crie um nome completo de aplicação padrão.
*/}}
{{- define "my-application.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}

{{/*
Rótulos comuns
*/}}
{{- define "my-application.labels" -}}
helm.sh/chart: {{ include "my-application.chart" . }}
{{ include "my-application.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

Gerenciando Charts do Helm: Instalação e Operações

Instalando um Chart

# Instale de um repositório
helm install my-release bitnami/postgresql

# Instale de um diretório local
helm install my-app ./my-application

# Instale com valores personalizados
helm install my-app ./my-application -f values-production.yaml

# Instale com substituições de valores inline
helm install my-app ./my-application \
  --set replicaCount=5 \
  --set image.tag=2.0.0

Atualizando Lançamentos

# Atualize com novos valores
helm upgrade my-app ./my-application -f values-production.yaml

# Atualize com rollback automático em caso de falha
helm upgrade my-app ./my-application --atomic --timeout 5m

# Forçar atualização de recursos
helm upgrade my-app ./my-application --force

Rollback e Histórico

# Visualize o histórico do lançamento
helm history my-app

# Rollback para a versão anterior
helm rollback my-app

# Rollback para uma revisão específica
helm rollback my-app 3

Teste e Depuração

# Executar uma simulação para ver os manifestas gerados
helm install my-app ./my-application --dry-run --debug

# Renderização de modelo sem instalação
helm template my-app ./my-application

# Verifique o chart para problemas
helm lint ./my-application

# Teste o lançamento com hooks de teste
helm test my-app

Recursos Avançados do Helm

Dependências do Chart

Charts do Helm podem depender de outros Charts, permitindo que você compõe aplicações complexas a partir de componentes reutilizáveis. Isso é particularmente útil ao implantar microserviços que precisam de bancos de dados, filas de mensagens ou outros serviços de suporte. Defina dependências em Chart.yaml:

dependencies:
  - name: redis
    version: "17.x.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled
  - name: postgresql
    version: "12.x.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: postgresql.enabled

Atualize dependências:

helm dependency update ./my-application

Hooks do Helm para Gerenciamento de Ciclo de Vida

Hooks são executados em pontos específicos no ciclo de vida do lançamento:

apiVersion: batch/v1
kind: Job
metadata:
  name: {{ include "my-application.fullname" . }}-db-migration
  annotations:
    "helm.sh/hook": pre-upgrade,pre-install
    "helm.sh/hook-weight": "5"
    "helm.sh/hook-delete-policy": before-hook-creation
spec:
  template:
    spec:
      containers:
      - name: db-migrate
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        command: ["python", "manage.py", "migrate"]
      restartPolicy: Never

Tipos de hook incluem:

  • pre-install: Antes que os recursos sejam instalados
  • post-install: Após a instalação de todos os recursos
  • pre-upgrade: Antes da atualização
  • post-upgrade: Após a atualização
  • pre-delete: Antes da exclusão
  • post-delete: Após a exclusão
  • pre-rollback: Antes do rollback
  • post-rollback: Após o rollback

Lógica Condicional e Controle de Fluxo

{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "my-application.fullname" . }}
  {{- with .Values.ingress.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
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 "my-application.fullname" $ }}
            port:
              number: {{ $.Values.service.port }}
      {{- end }}
  {{- end }}
{{- end }}

Suporte a Registries OCI: Distribuição Moderna de Charts

Desde o Helm 3.8, o suporte a registries OCI (Open Container Initiative) está estável, permitindo que Charts sejam armazenados junto com imagens de contêiner.

Publicando em um Registro OCI

# Faça login no registro
helm registry login registry.example.com

# Empacote o chart
helm package ./my-application

# Envie para o registro OCI
helm push my-application-1.0.0.tgz oci://registry.example.com/charts

# Instale a partir do registro OCI
helm install my-app oci://registry.example.com/charts/my-application --version 1.0.0

Benefícios de Registries OCI

  • Armazenamento Unificado: Charts e imagens em um só lugar
  • Ferramentas Padrão: Use a infraestrutura existente de registro
  • Melhor Segurança: Aproveite a autenticação e varredura do registro
  • Gerenciamento Simples: Não é necessário um servidor de repositório de Charts separado

Boas Práticas para Charts do Helm em Produção

1. Estrutura e Documentação dos Valores

Documente todos os valores com comentários:

# -- Número de réplicas para a aplicação
replicaCount: 3

# -- Configuração da imagem
image:
  # -- Repositório da imagem
  repository: myapp/backend
  # -- Política de puxar a imagem
  pullPolicy: IfNotPresent
  # -- Tag da imagem (padrão para a versão do chart appVersion)
  tag: ""

2. Gestão de Recursos

Sempre defina limites e solicitações de recursos:

resources:
  limits:
    cpu: 1000m
    memory: 1Gi
  requests:
    cpu: 500m
    memory: 512Mi

3. Contextos de Segurança

Defina contextos de segurança para contêineres:

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  fsGroup: 1000
  capabilities:
    drop:
    - ALL
  readOnlyRootFilesystem: true

4. Verificações de Saúde

Inclua verificações de saúde (liveness e readiness):

livenessProbe:
  httpGet:
    path: /health
    port: 8080
  initialDelaySeconds: 30
  periodSeconds: 10

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

5. Gestão de ConfigMap e Secret

O gerenciamento adequado de segredos é crítico para implantações em produção. Use gerenciadores de segredos externos (Sealed Secrets, External Secrets Operator ou Vault) em vez de armazenar segredos em arquivos de valores. Isso garante que dados sensíveis, como senhas de banco de dados, chaves de API e certificados, sejam tratados com segurança:

envFrom:
- secretRef:
    name: {{ include "my-application.fullname" . }}-secrets
- configMapRef:
    name: {{ include "my-application.fullname" . }}-config

6. Validação de Esquema

Crie values.schema.json para validar entradas do usuário:

{
  "$schema": "https://json-schema.org/draft-07/schema#",
  "properties": {
    "replicaCount": {
      "type": "integer",
      "minimum": 1
    },
    "image": {
      "type": "object",
      "properties": {
        "repository": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      },
      "required": ["repository"]
    }
  },
  "required": ["image"]
}

7. NOTES.txt para Orientação do Usuário

Forneça instruções pós-instalação:

1. Obtenha a URL da aplicação executando:
{{- if .Values.ingress.enabled }}
  https://{{ (index .Values.ingress.hosts 0).host }}
{{- else if contains "NodePort" .Values.service.type }}
  export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "my-application.fullname" . }})
  export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT
{{- end }}

2. Monitore a implantação:
  kubectl --namespace {{ .Release.Namespace }} get pods -l "app.kubernetes.io/name={{ include "my-application.name" . }}"

Teste de Chart do Helm e Integração com CI/CD

Teste de Chart com chart-testing (ct)

# Instale chart-testing
brew install chart-testing

# Valide os charts
ct lint --config ct.yaml

# Instale e teste os charts
ct install --config ct.yaml

Exemplo de GitHub Actions

name: Helm Chart CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Configurar Helm
        uses: azure/setup-helm@v3
        with:
          version: 3.12.0

      - name: Configurar chart-testing
        uses: helm/chart-testing-action@v2

      - name: Validação de charts
        run: ct lint --config ct.yaml

      - name: Criar cluster kind
        uses: helm/kind-action@v1

      - name: Instalar charts
        run: ct install --config ct.yaml

GitOps com Helm: ArgoCD e Flux

Ferramentas GitOps como ArgoCD e Flux se integram de forma seamles com Charts do Helm, permitindo implantações declarativas e automatizadas. Essas ferramentas monitoram seu repositório Git para alterações e sincronizam automaticamente os lançamentos do Helm, tornando a implantação contínua simples. Para arquiteturas complexas de microserviços, considere como padrões de transação distribuída, como o padrão Saga, podem ajudar a gerenciar a consistência entre serviços implantados via Helm.

Aplicação ArgoCD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-application
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/myorg/my-app-chart
    targetRevision: main
    path: charts/my-application
    helm:
      valueFiles:
        - values-production.yaml
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

HelmRelease Flux

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: my-application
  namespace: flux-system
spec:
  interval: 5m
  chart:
    spec:
      chart: my-application
      version: '1.x.x'
      sourceRef:
        kind: HelmRepository
        name: my-charts
  values:
    replicaCount: 5
    image:
      tag: "2.0.0"

Solução de Problemas com Problemas Comuns do Helm

Problema: Atualização Falha em Pendente

# Verifique o status do lançamento
helm list --all-namespaces

# Obtenha detalhes do lançamento
helm status my-app -n namespace

# Exclua forçadamente se necessário (use com cuidado)
kubectl delete secret -n namespace -l owner=helm,name=my-app

Problema: Erros de Renderização de Modelo

# Depurar a renderização do modelo
helm template my-app ./my-application --debug

# Valide contra o Kubernetes
helm template my-app ./my-application | kubectl apply --dry-run=client -f -

Problema: Valores Não Aplicados

# Verifique os valores mesclados
helm get values my-app

# Mostre todos os valores calculados
helm get values my-app --all

Ecosistema e Ferramentas do Helm

O ecosistema do Helm inclui diversas ferramentas que ampliam suas capacidades e se integram com outras tecnologias do Kubernetes. Ao implantar aplicações que exigem recursos de rede avançados, como comunicação serviço-serviço, gerenciamento de tráfego e políticas de segurança, considere integrar-se com uma Malha de Serviços com Istio e Linkerd, que podem ser implantadas e gerenciadas por meio de Charts do Helm.

Ferramentas Essenciais

  • Helmfile: Especificação declarativa para implantar Charts do Helm
  • Helm Diff: Visualizar mudanças antes da atualização
  • Helm Secrets: Gerenciar segredos com SOPS
  • Nova: Encontrar Charts do Helm obsoletos
  • Pluto: Detectar APIs do Kubernetes obsoletas

Exemplo de Helmfile

repositories:
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: postgresql
    namespace: database
    chart: bitnami/postgresql
    version: 12.x.x
    values:
      - postgresql:
          auth:
            database: myapp
            username: appuser

  - name: my-app
    namespace: production
    chart: ./charts/my-application
    values:
      - values-production.yaml
    needs:
      - database/postgresql

O Futuro do Helm

O ecosistema do Helm continua evoluindo:

  • OCI-Nativo: Transição completa para registries OCI como padrão
  • Melhor Segurança: Melhor gerenciamento de segredos e capacidades de assinatura
  • Desempenho: Renderização e instalação mais rápidas para Charts grandes
  • Suporte a WASM: WebAssembly para plugins e extensões de Chart
  • Melhor Validação: Validação de esquema e aplicação de políticas aprimorada

Conclusão

O Helm tornou-se o padrão de fato para o gerenciamento de pacotes do Kubernetes, e dominar esse é essencial para práticas modernas de DevOps. Ao compreender a estrutura do Chart, modelagem, gestão de valores e boas práticas, você pode criar implantações do Kubernetes mantíveis, seguras e escaláveis.

Comece com Charts simples, gradualmente incorpore recursos avançados como hooks e dependências, e integre-se com ferramentas GitOps para infraestrutura de produção. A comunidade do Helm oferece milhares de Charts pré-construídos, mas o verdadeiro poder vem de criar Charts personalizados adaptados às necessidades da sua organização. Seja ao implantar aplicações stateless ou cargas de trabalho stateful que exigem armazenamento persistente, o Helm simplifica a complexidade do gerenciamento de recursos do Kubernetes. Para equipes configurando novos clusters Kubernetes, considere instalar o Kubernetes com Kubespray ou explorar distribuições do Kubernetes como k3s ou MicroK8s para ambientes de desenvolvimento. Se você está avaliando qual distribuição se encaixa nas necessidades do seu homelab ou cluster pequeno, veja nossa comparação abrangente das distribuições do Kubernetes para análise detalhada.