Перейти к содержанию

7. Лучшие практики чартов


Устойчивые чарты в production опираются на соглашения об именах, предсказуемые лейблы и аннотации, вынос общей логики в templates/_helpers.tpl и принцип DRY (не копировать одно и то же в десять файлов). Ниже — ориентиры Helm/Kubernetes, примеры define / include и чеклист.


Именование

Объект Практика
Chart name Короткое имя в нижнем регистре, без пробелов (как в Chart.yamlname)
Ресурсы в кластере Стабильный префикс Release.Name или fullname (см. helper ниже), обрезка до 63 символов для имён DNS
Шаблоны файлов deployment.yaml, service.yaml — одна сущность Kubernetes на файл, когда возможно

Рекомендации Helm: conventions.


Лейблы и аннотации

Рекомендуемые лейблы (согласованность с экосистемой)

Используйте метки из Kubernetes / Helm recommended labels:

Лейбл Назначение
app.kubernetes.io/name Логическое имя приложения
app.kubernetes.io/instance Уникальный идентификатор релиза (Release.Name)
app.kubernetes.io/version Версия приложения или образа (из appVersion / values)
app.kubernetes.io/managed-by Обычно Helm ({{ .Release.Service }})
helm.sh/chart chartname-version для связи с chart’ом

Аннотации для отслеживания Helm

Полезно на Deployments/StatefulSets (если не генерирует ваш инструмент автоматически):

meta.helm.sh/release-name: {{ .Release.Name }}
meta.helm.sh/release-namespace: {{ .Release.Namespace }}

_helpers.tpl: переиспользуемые фрагменты

Файлы templates/*.tpl не рендерятся как отдельные манифесты — в них объявляют именованные шаблоны через define и подключают через include.

Пример templates/_helpers.tpl

{{/*
Полное имя релиза (короткий учебный вариант; в `helm create` — более полная логика).
*/}}
{{- define "my-app.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- end }}

{{/*
Имя chart для лейбла helm.sh/chart
*/}}
{{- define "my-app.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" -}}
{{- end }}

{{/*
Общий набор лейблов
*/}}
{{- define "my-app.labels" -}}
helm.sh/chart: {{ include "my-app.chart" . }}
{{ include "my-app.selectorLabels" . }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

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

Использование в deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-app.fullname" . }}
  labels:
    {{- include "my-app.labels" . | nindent 4 }}
spec:
  selector:
    matchLabels:
      {{- include "my-app.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "my-app.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: app
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"

include возвращает строку; nindent добавляет отступ — типичный DRY-паттерн.


DRY: что выносить в helpers

Повтор Куда
Одинаковые лейблы на Deployment/Service/Ingress define "chart.labels"
fullname / service account name отдельный define
Образ repository:tag опционально define "chart.image"
Сложный probe или securityContext define "chart.defaultSecurityContext" + nindent

Не превращайте helpers в «всё в одном файле на 500 строк» — группируйте по смыслу.


Production checklist

# Практика
1 Лейблы согласованы с дашбордами и селекторами NetworkPolicy
2 app.kubernetes.io/version не содержит секретов и не ломает кардинальность
3 Имена ресурсов уникальны между релизами в одном namespace
4 _helpers.tpl покрыт ревью при изменении Chart.Name / переезде chart’а
5 Документация в README.md: обязательные values и пример helm install

Дополнительные материалы