Секреты в шаблонах

Уровень: advanced ~40 мин Практика: Vikunja (AGPL-3.0)

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

  • M4.05 — CLI Nelm целиком — нужны команды chart secret из CLI для практики этого урока

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

M4 урок 2 — устройство .helm/secret-values.yaml/.helm/secret/. Этот урок — практическое руководство «когда какой подход применять» в реальных шаблонах.

Теория

.Values.password — маленькие отдельные значения

1
2
3
4
5
# .helm/secret-values.yaml (расшифрованное содержимое)
database:
  password: "supersecretpassword"
smtp:
  password: "smtp-secret-token"
1
2
3
4
5
6
7
8
# templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-app-secrets
stringData:
  DB_PASSWORD: {{ .Values.database.password | quote }}
  SMTP_PASSWORD: {{ .Values.smtp.password | quote }}

Подход через secret-values.yaml уместен, когда у вас есть набор отдельных небольших значений (пароли, токены, API-ключи) — они естественно вписываются в структуру, аналогичную обычному values.yaml, доступны через тот же .Values-объект, легко компонуются с обычными (незашифрованными) значениями в одном шаблоне.

{{ werf_secret_file "config.yaml" }} — целые файлы

1
2
3
4
5
6
7
8
9
# templates/configmap-tls.yaml
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-tls
type: kubernetes.io/tls
data:
  tls.crt: {{ werf_secret_file "tls.crt" | b64enc }}
  tls.key: {{ werf_secret_file "tls.key" | b64enc }}

Подход через .helm/secret/ + werf_secret_file уместен для целых файлов — сертификатов, приватных ключей, крупных конфигурационных файлов (например, готовый config.yaml внешнего инструмента, который приложение читает целиком, а не по отдельным значениям). Пытаться уместить содержимое сертификата как одно многострочное значение в secret-values.yaml технически возможно (YAML поддерживает multiline-строки), но неудобно для редактирования/ревью и не соответствует конвенции — .helm/secret/ явно предназначен именно для файлового случая.

Практическое правило выбора

Критерийsecret-values.yamlsecret/ + werf_secret_file
Тип данныхОтдельное значение (строка, число)Целый файл
Типичный примерПароль БД, API-токенTLS-сертификат, приватный ключ, крупный конфиг стороннего формата
Синтаксис доступа.Values.path.to.value (как обычное значение)werf_secret_file "filename" (отдельная функция)
Кодирование для data:Обычно уже готовая строкаЧасто требует `b64enc` явно

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

  • Пытаться использовать werf_secret_file для значений из secret-values.yaml. Это разные механизмы: werf_secret_file читает файлы из .helm/secret/, а не значения из secret-values.yaml — попытка передать туда имя, ожидая значение, приведёт к ошибке «файл не найден».
  • Забыть | b64enc при вставке содержимого файла в поле data: объекта Secret. Поле data: (в отличие от stringData:) Kubernetes ожидает в base64 — без явного кодирования манифест будет синтаксически валиден, но приложение получит не то, что ожидало (Kubernetes попытается интерпретировать не-base64-строку как уже закодированную и может исказить итоговое значение).
  • Хранить крупные файлы как значения в secret-values.yaml вместо .helm/secret/. Формально работает, но затрудняет редактирование через nelm chart secret values-file edit (весь файл открывается целиком в редакторе) — для отдельных крупных файлов удобнее nelm chart secret file edit <filename>.

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

Практики в кластере в этом уроке нет — фокус на паттернах шаблонизации секретов.

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

🧩 Практика урока: Vikunja · лицензия AGPL-3.0
  1. Добавьте оба типа секретов для Vikunja — пароль БД (значение) и TLS-сертификат для внутреннего сервиса (файл):
1
2
3
4
5
6
7
nelm chart secret values-file edit .helm/secret-values.yaml
# впишите:
# database:
#   password: "vikunja-secure-password"

nelm chart secret file edit .helm/secret/tls.crt
# впишите тестовый самоподписанный сертификат (или сгенерируйте: openssl req -x509 -nodes -newkey rsa:2048 -keyout /dev/null -out - -days 1 -subj "/CN=vikunja.local")
  1. Создайте оба шаблона:
1
2
3
4
5
6
7
# templates/secret-db.yaml
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-db
stringData:
  password: {{ .Values.database.password | quote }}
1
2
3
4
5
6
7
8
# templates/secret-tls.yaml
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-tls
type: kubernetes.io/tls
data:
  tls.crt: {{ werf_secret_file "tls.crt" | b64enc }}
  1. Отрендерите оба шаблона и убедитесь, что оба типа секретов появляются в открытом виде в финальном манифесте (это ожидаемо на этапе Render — расшифровка в памяти для формирования конечного манифеста, который затем применяется как обычный Kubernetes Secret):
1
nelm chart render . -r vikunja-demo | grep -A3 "kind: Secret"

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

1
2
nelm chart secret values-file edit <path>
nelm chart secret file edit <path>
{{ .Values.<path> }}                       # значение из secret-values.yaml
{{ werf_secret_file "<filename>" | b64enc }} # содержимое файла из secret/

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

Когда предпочтителен .Values.password вместо werf_secret_file?

secret-values.yaml естественно подходит для отдельных небольших значений, доступных через привычный .Values.

Источник: Deckhouse — Nelm-аннотации

Для чего конкретно предназначен werf_secret_file?

werf_secret_file читает файл целиком, в отличие от отдельных значений через .Values.

Источник: Deckhouse — Nelm-аннотации

Почему часто нужен | b64enc после werf_secret_file при вставке в поле data: объекта Secret?

data: требует base64; stringData: — открытый текст, который Kubernetes сам кодирует.

Источник: Kubernetes — Secrets

Какой командой удобнее редактировать содержимое одного крупного зашифрованного файла (например, сертификата)?

file edit работает с отдельным файлом из secret/, values-file edit — с целым secret-values.yaml.

Источник: Nelm — README на GitHub

Можно ли использовать werf_secret_file для чтения значения из secret-values.yaml?

Это два разных механизма с разными источниками данных — путать их вызовет ошибку 'файл не найден'.

Источник: Deckhouse — Nelm-аннотации

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

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

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

Книги

  • Matt Butcher, Matt Farina, Josh Dolitsky. Learning Helm. 2019. ISBN 978-1492036781.

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