генерировать динамическую среду выполнения YAML для контейнера с секретами k8s

Я развертываю службу, которая жестко использует конфигурацию YAML, которая выглядит примерно так:

# /config/srv.yaml

#
# ...
#
tenantid: '...'
clientid: '...'
certfile: '/config/client/client.crt'
keyfile:  '/config/client/client.key'
#
# ...
#

TL;ДР; Я хочу только хранить файлы tenantid, clientid и сертификатов в k8s секретах.

Мое текущее решение хранит весь файл YAML в секрете, что кажется расточительным, а также громоздким в управлении.


По сути, у меня есть это, которое хорошо работает для двух файлов сертификатов (/config/client/client.crt и /config/client/client.key):

spec:
  containers:
    - name: my-container
      image: "my-image"
      imagePullPolicy: Always
      ports:
        - containerPort: 50100
      env:
      - name: CONF_FILE
        value: "/config/srv.yaml"
      volumeMounts:
      - name: yaml-vol
        mountPath: "/config" # KLUDGY
        readOnly: true
      - name: certs-vol
        mountPath: "/config/client"
        readOnly: true

    volumes:
    - name: yaml-vol
      secret:
        secretName: my-yamls # KLUDGY
    - name: certs-vol
      secret:
        secretName: my-certs # contains the *.crt/*.key cert files

Однако это включает в себя хранение всего /config/srv.yaml в секретах kubernetes my-yamls.

документы по секретам k8s предлагают способ создайте динамическую конфигурацию YAML для своих контейнеров, заполняя секреты именно там, где это необходимо, используя stringData, например.

stringData:
  config.yaml: |-
    apiUrl: "https://my.api.com/api/v1"
    username: {{username}}
    password: {{password}}

но документы заканчиваются очень расплывчато:

Затем ваш инструмент развертывания может заменить переменные шаблона {{username}} и {{password}} перед запуском kubectl apply.

Мне просто нужно заполнить два строковых элемента в динамическом конфиге: clientid и tenantid.

Используя только kubectl, как можно создать динамический YAML для контейнера, сохраняя неконфиденциальный шаблон YAML в deploy.yaml, и иметь только конфиденциальные элементы в k8s secrets?


person colm.anseo    schedule 26.11.2019    source источник
comment
Если вы хотите написать простое приложение (например, Python, Go), было бы тривиально передать эту задачу приложению, а не просто использовать kubectl плюс команды оболочки.   -  person Cloud    schedule 27.11.2019
comment
@Cloud Если можно изменить логику приложения, как лучше всего передать ему такие секреты? Удалить все строковые секреты из app.yaml и вместо этого передать их через ENV VAR?   -  person colm.anseo    schedule 27.11.2019
comment
Я имел в виду динамическое создание файла yaml с только частями, которые вам нужны, с помощью скрипта Python для загрузки файла yaml (его можно импортировать как объект, аналогичный данным JSON), извлечь только секреты, которые вас интересуют, и запишите только эти секреты в новый yaml файл, который можно развернуть либо через kubectl, либо внутри Python с помощью K8S Py API. Пожалуйста, избегайте использования env vars, когда это возможно, так как они уродливы (т.е. глобальные) и имеют тенденцию создавать дыры в безопасности.   -  person Cloud    schedule 27.11.2019
comment
Кроме того, env vars позволяет легко копаться в /proc и получать данные, если система не защищена должным образом.   -  person Cloud    schedule 27.11.2019
comment
Согласен насчет ENV VARс. Я следую вашему обходному пути. Но если кто-то создает службу с нуля, как лучше всего вводить секреты в указанную службу? У вас есть app.yaml для обслуживания и secrets.yaml со всеми конфиденциальными строками?   -  person colm.anseo    schedule 27.11.2019
comment
Моим внезапным ответом/подходом будет диаграмма Helm, которая создает секреты, а также определение развертывания/модуля, которое запрашивает указанные секреты по ключу/имени. Helm только что выпустил v3, поэтому, вероятно, лучше использовать его, а не v2. Это мой предпочтительный подход к развертыванию в целом, поскольку он позволяет пользователям (легко) переопределять значения стандартизированным (и удобным для автоматизации) способом.   -  person Cloud    schedule 27.11.2019


Ответы (1)


Альтернативой будет использование другого инструмента для управления секретами. Одним из решений будет использование Kamus. Kamus поддерживает шаблоны, поэтому вы можете сделать что-то вроде:

apiVersion: v1
kind: ConfigMap
metadata:
  name: encrypted-secrets-cm
data:
  tenantid: <encrypted>
  clientid: <encrypted>
  template.ejs: |
     tenantid: <%- secrets["tenantid"] %>
     clientid: <%- secrets["clientid"] %>
     certfile: '/config/client/client.crt'
     keyfile:  '/config/client/client.key'

Где значения зашифрованы с помощью Kamus.

А затем либо использовать clientSecret и хранить его таким же образом, либо создать обычный секрет и для crt, и для ключа. Стоит отметить, что (при условии, что это Azure) идентификатор клиента и идентификатор арендатора не считаются секретами и могут быть зафиксированы в частном репозитории.

Полное раскрытие: я автор Камуса.

person Omer Levi Hevroni    schedule 28.11.2019