Как создать уникальные файлы конфигурации для нескольких хостов? - PullRequest
0 голосов
/ 01 ноября 2018

Я изучаю k8s и пытаюсь написать диаграммы Хелма для генерации файлов конфигурации для приложения, которое я использую для развития экосистемы. Я столкнулся с интересной проблемой, когда мне нужно создать конфигурации, которые являются общими для всех узлов, а некоторые - уникальными для каждого узла. Есть идеи, как мне это сделать?

Из моего файла values.xml:

# number of nodes / replicas
nodeCount: 5
replicaCount: 3

Общая конфигурация для всех узлов, называемая node_map.xml:

              <default>
                    <node>
                        <replica>
                            <host>wild-wallaby-0</host>
                            <port>8000</port>
                        </replica>
                        <replica>
                            <host>scary-rapids-1</host>
                            <port>8000</port>
                        </replica>
                    </node>
                    <node>
                        <replica>
                            <host>wild-wallaby-1</host>
                            <port>8000</port>
                        </replica>
                        <replica>
                            <host>scary-rapids-2</host>
                            <port>8000</port>
                        </replica>
                    </node>
                    <node>
                        <replica>
                            <host>wild-wallaby-2</host>
                            <port>8000</port>
                        </replica>
                        <replica>
                            <host>scary-rapids-0</host>
                            <port>8000</port>
                        </replica>
                    </node>
              </default>

Вышеуказанное достаточно просто для генерации, и эта конфигурация готова для каждого модуля, который является отдельным контейнером, но теперь для каждого модуля также должен быть написан дополнительный файл конфигурации, позволяющий этому модулю знать, какой узел и реплика у этого экземпляра, называется instance.xml. Обратите внимание, что файл не обязательно должен называться instance.xml ... У меня есть возможность указывать и загружать любой именованный файл, если я знаю, какое имя включить в команду запуска.

Например ...

Два экземпляра будут работать на узле wild-wallaby-0, реплике 1 узла 0 и реплике 2 узла 2. Каждому экземпляру потребуются файлы конфигурации, сгенерированные следующим образом:

Первый экземпляр ...

    <!-- node 0 replica 1 instance.xml -->
    <id>
        <node>0</node>
        <replica>1</replica>
    </id>

И второй экземпляр ...

<!-- node 0 replica 2 instance.xml -->
    <id>
        <node>0</node>
        <replica>2</replica>
    </id>

Это, конечно, может следовать некоторым соглашениям, основанным на количестве узлов и реплик, определенных в моем файле значений. Хотя легко создать файл, общий для всех узлов, мне не ясно, как я могу сгенерировать настраиваемый файл конфигурации для каждого узла из рулевой диаграммы для файлов instance.xml.

Есть идеи или указатели?

1 Ответ

0 голосов
/ 01 ноября 2018

Вы можете развернуть его как StatefulSet и использовать initContainers: для создания файла конфигурации до того, как действительно будет запущена основная задача модуля.

Документация Kubernetes содержит довольно подробный пример этого , ориентированного на реплицируемый кластер MySQL, но с той же необходимой настройкой: есть главный узел и некоторое количество реплик, каждая из которых должна знать свою собственный идентификатор и файлы конфигурации различаются на главном компьютере и репликах.

Похоже, важная деталь, с которой вы можете работать, состоит в том, что hostname модуля (как в команде оболочки) имеет значение statefulsetname-123, где числа являются последовательными, и отдельные модули гарантированно запускаются по порядку. Та же самая деталь содержится в метке "statefulset.kubernetes.io/pod-name" , которую можно получить с помощью нисходящего API .

Я мог бы создать ConfigMap, например:

version: v1
kind: ConfigMap
metadata:
  name: config-templates
data:
  config.xml.tmpl: >-
    <id>
      <node>NODE</node>
      <replica>REPLICA</replica>
    </id>

И тогда моя спецификация StatefulSet может выглядеть частично:

version: apps/v1
kind: StatefulSet
...
spec:
  ...
  template:
    spec:
      volumes:
        - name: config
          emptyDir: {}
        - name: templates
          configMap:
            name: config-templates
      initContainers:
        - name: configfiles
          image: ubuntu:16.04
          command:
            - sh
            - -c
            - |
              POD_NUMBER=$(hostname | sed 's/.*-//')
              NODE=$(( $POD_NUMBER / 5 ))
              REPLICA=$(( $POD_NUMBER % 5 ))
              sed -e "s/NODE/$NODE/g" -e "s/REPLICA/$REPLICA/g" \
                /templates/config.xml.tmpl > /config/config.xml
          volumeMounts:
            - name: templates
              mountPath: /templates
            - name: config
              mountPath: /config
      containers:
        - name: ...
          ...
          volumeMounts:
            - name: config
              mountPath: /opt/myapp/etc/config

В этой настройке вы просите Kubernetes создать пустой временный том (config), который совместно используется контейнерами, и сделать карту конфигурации доступной также как том. Контейнер init извлекает последовательный идентификатор модуля, разбивает его на два числа и записывает фактический файл конфигурации во временный том. Затем основной контейнер монтирует общий каталог конфигурации туда, где он ожидает, чтобы его файлы конфигурации были.

...