Kubernetes несколько идентичных приложений и баз данных с разными конфигурациями - PullRequest
0 голосов
/ 23 января 2020

Дилемма : развертывание нескольких пар контейнеров приложений и баз данных с одинаковым docker изображением и кодом, но с другой конфигурацией (разные клиенты используют субдомены).

Какие логические способы подойти к этому, поскольку кажется, что kubernetes не имеет интеграции, которая бы поддерживала такой тип настройки?

Возможные подходы

  1. Используйте одну службу приложения для всех развертываний приложения, одну службу базы данных для всех развертываний базы данных. Запустите одну файловую службу и развертывание Nginx stati c, которая будет обслуживать файлы stati c с тома stati c, который используется совместно для развертываний приложений (все используют один и тот же набор файлов stati c) ). Всякий раз, когда требуется новое развертывание, попросите сценарий bash скопировать файлы развертывания приложения и базы данных .yaml, а текст sed заменить именем клиента, указать правильный конфигурационный файл (который, конечно, написан вручную) и применить kubectl. , Основной вход nginx будет обрабатывать входящий трафик c и указывать на правильный модуль через службу развертывания приложения
  2. Аналогично приведенному выше, за исключением использования StatefulSet вместо отдельных развертываний и контейнера init для копирования разные конфиги для подключенных томов (единственный недостаток - вы не можете удалить элемент в середине набора состояний, что может быть в случае, если вам больше не нужен специфицированный контейнер c для клиента, а также это выглядит как очень хакерский подход).

В идеале, если StatefulSet может использовать нисходящий API для динамического выбора имени configmap на основе индекса набора с сохранением состояния, который решит проблему (где вы в основном создадите свои файлы конфигурации вручную с указателем в имени, и он будет выбран соответствующим образом). Что-то вроде:

env:
- name: POD_NAME
  valueFrom:
    fieldRef:
      fieldPath: metadata.name

envFrom:
- configMapRef:
  name: $(POD_NAME)-config

Однако эта функциональность недоступна в kubernetes.

Ответы [ 2 ]

1 голос
/ 23 января 2020

Шаблонный движок типа Helm может помочь с этим. (Я полагаю, что Kustomize , который поставляется с нынешними Kubernetes, тоже может это сделать, но я гораздо лучше знаком с Helm.) Основная идея c заключается в том, что у вас есть диаграмма который содержит файлы YAML Kubernetes, но может использовать язык шаблонов (библиотека Go text/template) для динамического заполнения содержимого.

В этой настройке обычно используется Helm создать как ConfigMap, так и соответствующее Deployment; в описанной вами настройке вы устанавливаете его отдельно (Helm release ) для каждого арендатора. Скажем, конфигурации Nginx были настолько разными, что вы хотели сохранить их во внешних файлах 1015 *; основные части вашей диаграммы будут включать

values.yaml (изменяемая конфигурация, helm install --set nginxConfig=bar.conf):

# nginxConfig specifies the name of the Nginx configuration
# file to embed.
nginxConfig: foo.conf

templates / configmap.yaml :

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}-config
data:
  nginx.conf: |-
{{ .Files.Get .Values.nginxConfig | indent 4 }}

deploy.yaml :

apiVersion: v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}-nginx
spec:
  ...
    volumes:
      - name: nginx-config
        configMap:
          name: {{ .Release.Name }}-{{ .Chart.Name }}-config

{{ .Release.Name }}-{{ .Chart.Name }} - это типичное соглашение, позволяющее устанавливать несколько копий диаграммы в одном Пространство имен; первая часть - это имя, которое вы даете команде helm install, а вторая часть - это имя самой диаграммы. Вы также можете напрямую указать содержимое ConfigMap, ссылаясь на другие настройки .Values... из файла values.yaml, использовать ConfigMap в качестве переменных среды вместо файлов и т. Д.

1 голос
/ 23 января 2020

В то время как Dynami c структурный замена невозможна (плюс или минус, смотрите всю историю ниже) , я полагаю, вы были в правильном поле с вашим initContainer: мысль; вы можете использовать serviceAccount для извлечения configMap из API в initContainer:, а затем отправлять эту среду при запуске из основного контейнера:

initContainers:
- command:
  - /bin/bash
  - -ec
  - |
       curl -o /whatever/env.sh \
       -H "Authorization: Bearer $(cat /var/run/secret/etc/etc)" \
       https://${KUBERNETES_SERVICE_HOST}/api/v1/namespaces/${POD_NS}/configmaps/${POD_NAME}-config
  volumeMounts:
  - name: cfg  # etc etc
containers:
- command:
  - /bin/bash
  - -ec
  - "source /whatever/env.sh; exec /usr/bin/my-program"
  volumeMounts:
  - name: cfg  # etc etc
volumes:
- name: cfg
  emptyDir: {}

Здесь мы получаем ConfigMap выборку встроенный в PodSpec, но если бы у вас был docker контейнер, специально предназначенный для извлечения ConfigMap s и сериализации их в формат, который могли бы использовать ваши основные контейнеры, я бы не ожидал, что фактическое решение будет почти таким многословным


Отдельный и гораздо более сложный (но, возможно, элегантный) подход - Mutating Admission Webhook , и похоже, что они даже недавно формализовали ваш самый вариант использования с Pod Presets , но из документации не было ясно, в какой версии эта функциональность появилась впервые, и нет ли каких-либо флагов apiserver, которые нужно использовать, чтобы воспользоваться ею.

...