Контекст Helm/Nelm-шаблонов Application

Уровень: advanced ~55 мин Практика: Umami (MIT)

Что нужно знать перед уроком

  • M5.03 — Контракт настроек: обе схемы — нужен values-контракт перед изучением того, как шаблоны получают доступ к его значениям

Что нужно знать перед уроком

M4 урок 1 — встроенные объекты Helm (.Release/.Chart/.Values/.Capabilities/.Files). M5 урок 3 — контракт значений. Здесь — дополнительные, специфичные для Application объекты контекста, которых нет в ванильном Helm.

Теория

.Application.* — надстройка платформы поверх стандартного контекста Helm

Помимо стандартных .Release/.Chart/.Values/.Capabilities/.Files (M4 урок 1), шаблоны Application-пакета получают доступ к объекту .Application, специфичному именно для платформы Deckhouse:

ПутьЧто содержит
.Application.Instance.Nameимя конкретного установленного инстанса (значение metadata.name ресурса Application)
.Application.Settings.*пользовательские настройки из spec.settings (после валидации по config-values.yaml, M5 урок 3)
.Application.Package.Images "<key>"ссылка на конкретный собранный образ пакета по ключу (соответствует image:-блокам werf.yaml, M3 урок 2)
.Application.Package.Registry.dockercfgучётные данные для доступа к registry, откуда пакет был установлен — нужны для формирования imagePullSecrets

Использование в шаблонах

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Application.Instance.Name }}-backend
  labels:
    app.kubernetes.io/instance: {{ .Application.Instance.Name }}
spec:
  replicas: {{ .Application.Settings.replicas | default 1 }}
  selector:
    matchLabels:
      app.kubernetes.io/instance: {{ .Application.Instance.Name }}
      component: backend
  template:
    metadata:
      labels:
        app.kubernetes.io/instance: {{ .Application.Instance.Name }}
        component: backend
    spec:
      imagePullSecrets:
        - name: {{ .Application.Instance.Name }}-registry
      containers:
        - name: backend
          image: {{ .Application.Package.Images "backend" }}
          env:
            - name: APP_HOSTNAME
              value: {{ .Application.Settings.hostname | quote }}
---
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Application.Instance.Name }}-registry
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: {{ .Application.Package.Registry.dockercfg }}

Ключевое отличие от стандартного .Release.Name: .Application.Instance.Name — семантически специфичное имя для конкретного установленного инстанса Application, тогда как .Release.Name — более общее понятие Helm-релиза. На практике для Application-пакетов оба значения обычно совпадают, но использование именно .Application.Instance.Name в шаблонах — принятая конвенция, делающая явной привязку к модели Application, а не к нейтральной модели Helm-релиза.

.Application.Package.Images — связь с werf.yaml

.Application.Package.Images "<key>" — механизм, связывающий шаблоны с образами, собранными на этапе werf (M3): ключ соответствует имени image:-блока в werf.yaml (например, backend, frontend), а само значение — полный адрес собранного и опубликованного образа (registry + repo + content-based тег, M8 урок 3). Это заменяет ручное управление тегами образов в values.yaml — платформа сама подставляет правильный адрес актуально собранного образа для текущей версии пакета.

.Application.Package.Registry.dockercfg — доступ к приватному registry

Поскольку Application-пакет может быть установлен из приватного PackageRepository (M2 урок 3), контейнерам внутри установленного Application нужны учётные данные для скачивания образов из того же приватного registry — .Application.Package.Registry.dockercfg предоставляет уже подготовленные платформой (Base64-закодированные, в формате .dockerconfigjson) учётные данные, которые шаблон встраивает в Secret типа kubernetes.io/dockerconfigjson и ссылается на него через imagePullSecrets контейнеров.

Построчный разбор на реальных примерах

При сверке всех 9 примеров Applications/* видно устойчивую конвенцию именования ресурсов и лейблов: {{ .Application.Instance.Name }}-<component> для имён ресурсов (Deployment/Service/ConfigMap), стандартные лейблы app.kubernetes.io/instance: {{ .Application.Instance.Name }} и app.kubernetes.io/name: <package-name> (по конвенции Kubernetes recommended labels, знакомой из M1 урока 5) — эта конвенция обеспечивает изоляцию ресурсов между множественными инстансами одного пакета, детально разбираем в M5 уроке 7.

Частые ошибки и подводные камни

  • Использовать .Release.Name вместо .Application.Instance.Name в шаблонах Application. Хотя технически оба могут совпадать, конвенция платформы явно рекомендует .Application.Instance.Name — использование не той конвенции затрудняет чтение шаблона теми, кто ожидает стандартный Application-контекст.
  • Хардкодить адрес образа вместо .Application.Package.Images "<key>". Это ломает связь между собранным werf образом и его использованием в шаблоне — при пересборке/публикации новой версии пакета адрес не обновится автоматически.
  • Забыть imagePullSecrets, если пакет устанавливается из приватного registry. Без ссылки на Secret, сформированный из .Application.Package.Registry.dockercfg, Pod получит ImagePullBackOff при попытке скачать образ из приватного репозитория.

Практика в кластере

Практики в кластере в этом уроке нет — фокус на синтаксисе шаблонов, первая установка — в конце модуля M5.

Практика разработки

🧩 Практика урока: Umami · лицензия MIT
  1. Перепишите templates/deployment.yaml пакета Umami, используя специфичный для Application контекст вместо обычного .Release/.Values:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Application.Instance.Name }}-backend
  labels:
    app.kubernetes.io/name: umami
    app.kubernetes.io/instance: {{ .Application.Instance.Name }}
spec:
  replicas: {{ .Application.Settings.replicas | default 1 }}
  selector:
    matchLabels:
      app.kubernetes.io/name: umami
      app.kubernetes.io/instance: {{ .Application.Instance.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: umami
        app.kubernetes.io/instance: {{ .Application.Instance.Name }}
    spec:
      containers:
        - name: backend
          image: {{ .Application.Package.Images "backend" }}
          env:
            - name: APP_URL
              value: "https://{{ .Application.Settings.hostname }}"
  1. Проверьте, что рендер шаблона (в тестовом режиме, без реального .Application-объекта в кластере — с подстановкой тестовых значений через --set) работает синтаксически корректно:
1
nelm chart lint .
  1. Сопоставьте своё именование ресурсов с конвенцией из теории ({{ .Application.Instance.Name }}-<component>) для всех остальных ресурсов пакета (Service, ConfigMap).

Шпаргалка команд урока

{{ .Application.Instance.Name }}
{{ .Application.Settings.<field> }}
{{ .Application.Package.Images "<image-key>" }}
{{ .Application.Package.Registry.dockercfg }}

Вопросы для самопроверки

Чем .Application.Instance.Name отличается от стандартного .Release.Name?

На практике значения обычно совпадают, но конвенция платформы явно рекомендует использовать Application-специфичный путь для ясности намерения.

Источник: Deckhouse — Разработка Application-пакета

Что возвращает .Application.Package.Images "backend"?

Это связывающий механизм между werf-сборкой (M3) и шаблонами — платформа сама подставляет актуальный адрес образа.

Источник: Deckhouse — Разработка Application-пакета

Зачем нужен .Application.Package.Registry.dockercfg?

Без этих учётных данных Pod получит ImagePullBackOff при попытке скачать образ из приватного registry.

Источник: Deckhouse — Package-repository

Откуда шаблон получает значения через .Application.Settings.*?

Settings — это уже провалидированные пользовательские значения, соответствующие JSON Schema из M5 урока 3.

Источник: Deckhouse — Разработка Application-пакета

Какая конвенция именования ресурсов устойчиво встречается во всех 9 реальных примерах Applications/*?

Эта конвенция обеспечивает изоляцию ресурсов между множественными инстансами одного пакета (M5 урок 7).

Источник: Deckhouse — *

Рекомендуемая литература

Официальная документация

Статьи и блоги

Книги

  • Marko Lukša. Kubernetes in Action. 2nd ed., 2022. ISBN 978-1617297618.

Связанные материалы