Концепции
dhctl
Чтобы установить Deckhouse Kubernetes Platform вручную, используют утилиту dhctl. На вход она принимает три набора данных:
- Конфигурацию SSH-подключения к машине, которая станет первым мастер-узлом. Конфигурация
используется в виде ключей командной строки dhctl (есть возможность задать в виде YAML). Будем
далее ссылаться на него под именем
SSHConfig
. - Инфраструктурная и базовая конфигурация кластера в виде yaml-файла, будем
далее ссылаться на него под именем
config.yaml
. - Необязательный набор ресурсов который нужно создать на последнем шаге установки, будем далее
ссылаться на него под именем
resources.yaml
.
Соответствие имен файлов и их содержимое приведено только для наглядности и совместимости со старыми версиями dhctl. Современные версии dhctl не ограничивают пользователя количеством и именами конфигурационных файлов для установки.
Какие логические части содержатся в этих данных?
SSHConfig
- Имя пользователя, пароль и ключ для подключения к существующей машине или той, которая будет создана в процессе создания кластера (возможность задать пароль для sudo в разработке).
- IP-адрес машины, если кластер разворачивается на заранее созданных машинах («статический» тип кластера)
- Остальные параметры можно посмотреть в справке команды dhctl, в данной документации дополнительные детали несущественны
InitConfiguration
— конфигурация доступа в реестр контейнеров (dockerconfig)ClusterConfiguration
— конфигурация Kubernetes: версия, подсетей подов, сервисов и т.п.- Параметры размещения в инфраструктуре
<Provider>ClusterConfiguration
— параметры размещения кластера в облаке или API виртуализации, если Deckhouse Kubernetes Platform устанавливается не на статические ресурсы;- или
StaticClusterConfiguration
для статического кластера
- Параметры размещения в инфраструктуре
resources.yaml
— произвольная конфигурация Deckhouse Kubernetes Platform в виде манифестов Kubernetes
Все эти данные в разных комбинациях используются для создания, изменения и удаления кластеров. Эти же данные используются в Deckhouse Commander, а dhctl используется как внутренний компонент.
Deckhouse Commander
Deckhouse Commander использует тот же набор данных для конфигурации кластеров, что и dhctl. Однако Deckhouse Commander добавляет возможность автоматически синхронизировать полную желаемую конфигурацию с кластером.
Вид конфигурации | Часть конфигурации | Установка | Изменение | Удаление |
---|---|---|---|---|
Доступ | SSH-подключение к мастер-узлу | ✓ | ✓ | |
Доступ | Реестр контейнеровInitConfiguration |
✓ | ||
Инфраструктура/Доступ | Размещение<Provider>ClusterConfiguration |
✓ | ✓ | ✓ |
Инфраструктура/Kubernetes | KubernetesClusterConfiguration |
✓ | ✓ | |
Kubernetes | Операционная конфигурация платформы | ✓ | ✓ |
- Для создания и удаления кластера требуется SSH-доступ к мастер-узлу, а для изменений не требуется.
- Доступ в реестр контейнеров настраивается только во время установки (в будущем будет возможность управлять изменением параметров реестр)
- Базовая инфраструктурная конфигурация управляется с помощью доступа в API облака, в то время как операционная конфигурация используется с помощью commander-agent (далее — «агент») — вспомогательного модуля, который включается в кластере в процессе его создания или присоединения к Deckhouse Commander.
Deckhouse Commander — источник истины конфигурации. Deckhouse Commander отслеживает, что конфигурация кластера соответствует заданной. Если Deckhouse Commander обнаруживает расхождение, он принимает попытку привести кластер к заданной конфигурации. Далее для этого мы будем использовать «синхронизация».
- Синхронизация инфраструктуры проводится компонентом cluster-manager, который использует dhctl.
- Синхронизация операционной конфигурации проводится компонентом агентом.
Deckhouse Commander делит конфигурацию Deckhouse Kubernetes Platform по принципу отслеживаемости. Причем пользователь решает какую часть конфигурации синхронизировать, а какую задать один раз при создании кластера. Как эта конфигурация выглядит с точки зрения Deckhouse Commander:
Вид конфигурации | Часть конфигурации | Актуализирующий компонент |
---|---|---|
Доступ | SSH-подключение к мастер-узлу | — |
Доступ | Реестр контейнеровInitConfiguration |
— |
Инфраструктура/Доступ | Размещение<Provider>ClusterConfiguration |
cluster-manager |
Инфраструктура/Kubernetes | KubernetesClusterConfiguration |
cluster-manager |
Kubernetes | Операционная конфигурация платформы | commander-agent |
Шаблоны
Идея
Deckhouse Commander создан для того, чтобы управлять типовыми кластерами. Так как все виды конфигурации в Deckhouse Commander представлены в формате YAML, шаблонизация кластеров представляет собой шаблоны YAML-конфигурации и описание схемы этих входных параметров шаблона. Для шаблонизации YAML используется синтаксис go template и набор функций sprig. Для описания схемы входных параметров используется собственный синтаксис для полей.
Секция | Тип | Назначение |
---|---|---|
Входные параметры | Схема | Схема входных параметров шаблона |
Kubernetes | Шаблон YAML | Конфигурация KubernetesClusterConfiguration |
Размещение | Шаблон YAML | Конфигурация размещения<Provider>ClusterConfiguration или StaticClusterConfiguration |
Параметры SSH | Шаблон YAML | SSH-подключение к мастер-узлу |
Ресурсы | Шаблон YAML | Ресурсы кластера, включая любые ModuleConfig кроме системных |
Первичные ресурсы | Шаблон YAML | Ресурсы кластера, включая любые ModuleConfig кроме системных |
Установка | Шаблон YAML | Конфигурация установкиInitConfiguration и системные ModuleConfig |
Конфигурация кластера создается за счет подстановки входных параметров в шаблоны секций. Входные параметры валидируются заданной для них схемой.
Версии шаблона
Важная черта шаблона — эволюция. Недостаточно создать парк кластеров на основе шаблонов. Шаблоны совершенствуются и актуализируются под новые версии ПО и новые требования эксплуатации кластеров. Обновленный шаблон позволяет не только создавать новые кластера, отвечающие современным требованиям, но и для того, чтобы актуализировать уже существующие кластеры.
Для эволюции шаблонов в Deckhouse Commander предусмотрен механизм версионирования. Когда шаблон получает обновления, для него создается новая версия. Версия может быть сопровождена комментарием. На основе версии шаблона можно создать кластер и протестировать его работоспособность. Если версия шаблона не подходит для того, чтобы ею пользовались, ее можно отметить недоступной для использования. Тогда администраторы кластеров не смогут перевести кластер на версию шаблона.
В Deckhouse Commander каждый кластер привязан к определенной версии шаблона. Однако технически кластер можно перевести на любой другой шаблон и любую доступную версию шаблона с точностью до невалидной конфигурации, которую Deckhouse Commander не позволит сохранить. Когда кластер переводится на новую версию или шаблон, необходимо актуализировать входные параметры, чтобы для кластера создалась обновленная конфигурация. Deckhouse Commander обнаружит, что целевая конфигурация не совпадает с последней примененной конфигурацией и создаст задание на синхронизацию кластера.
Сложность шаблона
Создание и тестирование шаблона — это инженерная задача, в то время как создание кластеров на основании шаблона не требует глубокого погружения в технические особенности в общем случае.
Входные параметры шаблона представлены для пользователя в виде онлайн-формы, в которой пользователь набирает или выбирает параметры, необходимые для создания кластера. Весь набор входных параметров определяется автором шаблона: какие параметры доступны, какие обязательны, в каком порядке заполняются, каким тестом сопровождены и как отформатированы для удобства восприятия конечным пользователем.
Только автор шаблона определяет, насколько будет просто или тяжело использовать шаблон конечному пользователю, и какие решения необходимо пользователю принять, чтобы успешно создать кластер. Чем сложнее шаблон, тем сложнее шаблонизирующий его код и тем сложнее форма параметров шаблона. Пользователи Deckhouse Commander сами определяют соотношение сложности шаблона и количества шаблонов для разных сценариев. Deckhouse Commander — достаточно гибкий инструмент. С ним можно сделать как один шаблон на все случаи жизни, так и множество шаблонов для каждого отдельного сценария использования.
Создание шаблона
Добавить шаблон в Deckhouse Commander можно двумя способами: импортировать существующий (например, созданный ранее в другой инсталляции Deckhouse Commander) или создать с нуля. В конечном счете шаблонизированная конфигурация должна будет удовлетворять особенностями dhctl и Deckhouse Kubernetes Platform той версии, которая будет устанавливаться с помощью шаблона.
Где почерпнуть документацию для видов конфигурации
- Входные параметры
- Размещение
- Kubernetes
- Доступ в реестр контейнеров
- Параметры SSH
- См. примеры ниже
Специальные переменные
В шаблонах кластеров есть несколько специальных переменных.
Переменная | Назначение |
---|---|
dc_sshPublicKey |
Публичная часть SSH-ключа. Пара SSH-ключей создается для каждого кластера. Можно использовать для cloud-init облачных кластеров. |
dc_sshPrivateKey |
Приватная часть SSH-ключа. Пара SSH-ключей создается для каждого кластера. Можно использовать для доступа к мастер-узлам облачных кластеров. |
dc_clusterUUID |
UUID текущего кластера. Генерируется для каждого кластера. Можно использовать для тегирования метрик и логов кластера. |
dc_domain |
Домен, на котором размещен Deckhouse Commander. Общий для всего приложения. Пример: commander.example.com |
dc_caBundle |
Сертификат Deckhouse Commander, закодированный в base64. Используется агентом для верификации подключений к серверу Deckhouse Commander. |
Параметры SSH для облачного кластера
Для облачного кластера можно использовать приватный ключ, созданный Deckhouse Commander, если вы не предоставляете заранее определенный ключ в образе ОС. Также в образах виртуальных машин будет создан пользователь, под которым Deckhouse Commander подключится к созданной машине, чтобы завести ее как master-узел.
1apiVersion: dhctl.deckhouse.io/v1
2kind: SSHConfig
3# имя пользователя для SSH, определяется образом ОС в разделе «Размещение»
4sshUser: ubuntu
5sshPort: 22
6# приватный ключ, который будет использовать для подключения к ВМ по SSH
7sshAgentPrivateKeys:
8- key: |
9 {{- .dc_sshPrivateKey | nindent 4 }}
Параметры SSH и ресурсы для статического кластера
Так как машины созданы заранее, и на них настроен сервер SSH, пользователь и ключ, то эти данные необходимо сообщить во входных параметрах кластера. В отличие от облачной конфигурации выше, мы используем не встроенный параметр, а явно переданный пользователем. Часть данных всегда можно задать внутри шаблона, если их параметризация не представляется целесообразной.
Обратите внимание на манифесты SSHHost
. Они объявляют IP-адреса, к которому у Deckhouse Commander есть
доступ. В данном примере предполагается, что входной параметр .masterHosts
— это список
IP-адресов, на основании которых в конфигурации будет набор SSH-хостов. Так как это мастера, их
следует указывать в количестве 1 или 3.
1apiVersion: dhctl.deckhouse.io/v1
2kind: SSHConfig
3# имя пользователя и порт для SSH, сконфигурированные на машинах
4sshUser: {{ .sshUser }}
5sshPort: {{ .sshPort }}
6# приватный ключ, используемый на машинах, передается как входной параметр в кластер
7sshAgentPrivateKeys:
8- key: |
9 {{- .sshPrivateKey | nindent 4 }}
10
11{{- range $masterHost := .masterHosts }}
12---
13apiVersion: dhctl.deckhouse.io/v1
14kind: SSHHost
15host: {{ $masterHost.ext_ip }}
16{{- end }}
Deckhouse Commander подключится только к одному SSH-хосту в переданном списке, будет пробовать хосты по
порядку до первого успешного подключения. Первый подключенный хост станет мастер-узлом кластера.
Когда Deckhouse установится на первом мастер-узле, он сможет сам добавить два оставшихся мастер-узла
в кластер, если они заявлены в шаблоне. Для этого нужно сообщить Deckhouse, что машины существуют,
как на них попасть, и что их нужно добавить в кластер. Для этого необходимо для двух мастеров
создать StaticInstance, определить для них SSHCredentials, а также явно прописать группу узлов
master с параметром spec.staticInstances.count=2
, чтобы два статических мастер-узла не только были
известны Deckhouse, но и были востребованы как master-узлы. Эту часть шаблона целесообразно
определить в «Ресурсах». Ниже представлен код шаблона для этой задачи:
1---
2apiVersion: deckhouse.io/v1alpha1
3kind: SSHCredentials
4metadata:
5 name: commander-ssh-credentials
6 labels:
7 heritage: deckhouse-commander
8spec:
9 sshPort: {{ .sshPort }}
10 user: {{ .sshUser }}
11 privateSSHKey: {{ .sshPrivateKey | b64enc }}
12
13{{- if gt (len .masterHosts) 1 }}
14{{- range $masterInstance := slice .masterHosts 1 }}
15---
16apiVersion: deckhouse.io/v1alpha1
17kind: StaticInstance
18metadata:
19 labels:
20 type: master
21 heritage: deckhouse-commander
22 name: {{ $masterInstance.hostname | quote }}
23spec:
24 address: {{ $masterInstance.ip | quote }}
25 credentialsRef:
26 apiVersion: deckhouse.io/v1alpha1
27 kind: SSHCredentials
28 name: commander-ssh-credentials
29{{- end }}
30{{- end }}
31
32{{- if gt (len .masterHosts) 1 }}
33---
34apiVersion: deckhouse.io/v1
35kind: NodeGroup
36metadata:
37 name: master
38 labels:
39 heritage: deckhouse-commander
40spec:
41 disruptions:
42 approvalMode: Manual
43 nodeTemplate:
44 labels:
45 node-role.kubernetes.io/control-plane: ""
46 node-role.kubernetes.io/master: ""
47 taints:
48 - effect: NoSchedule
49 key: node-role.kubernetes.io/master
50 - effect: NoSchedule
51 key: node-role.kubernetes.io/control-plane
52 nodeType: Static
53 staticInstances:
54 count: 2
55 labelSelector:
56 matchLabels:
57 type: master
58{{- end }}
Ресурсы: модуль commander-agent
Deckhouse Commander синхронизирует ресурсы с помощью модуля commander-agent. Этот модуль устанавливается в целевом кластере. Приложение commander-agent запрашивает актуальный список ресурсов для кластера и актуализирует их в кластере, в котором работает. настроен, в ресурсах необходимо создать манифест, включающий модуль.
Обратите внимание на commanderUrl
. Вам предстоит уточнить схему этого адреса: HTTP или HTTPS.
1apiVersion: deckhouse.io/v1alpha1
2kind: ModuleConfig
3metadata:
4 name: commander-agent
5 labels:
6 heritage: deckhouse-commander
7spec:
8 enabled: true
9 version: 1
10 settings:
11 commanderUrl: "https://{{ .dc_domain }}/agent_api/{{ .dc_clusterUUID }}"
Схема параметров кластера и записи инвентаря
Есть две формы, которые пользователь собирает с помощью схемы:
- форма параметров кластера (входные параметры шаблона кластера),
- форма записи.
Схема определяет объект. Всегда есть возможность редактировать ее в визуальном редакторе формы.
Общедоступные поля
Ввод строки
Строка со значением по умолчанию
1- key: something
2 type: string
3 title: Некое значение
4 default: Ввода нет
Необязательный параметр, его разрешено не заполнять (optional
)
1- key: something
2 type: string
3 title: Некое значение
4 optional: true
Параметр заполняется один раз при создании записи или кластера, и далее его нельзя редактировать
(immutable
)
1- key: something
2 type: string
3 title: Некое значение
4 immutable: true
Пароль и пояснение к нему (см format
и description
)
1- key: password
2 type: string
3 format: password
4 minLength: 8
5 span: 2
6 title: Пароль
7 description: |
8 Придумайте нормальный пароль.
9
10 Пароль должен содержать то-то и то-то и обновляться каждые N дней.
Ввод числа
Можно задать максимум и необязательность
1- key: ordinarySize
2 type: number
3 optional: true
4 max: 13
Можно задать минимум и сделать поле ввода на 4 колонки (максимальная ширина)
1- key: eliteSize
2 type: number
3 description: In cm
4 min: 18
5 span: 4
Можно задать максимум и минимум
1- key: elephantSize
2 type: number
3 description: In meters
4 min: 0.7
5 max: 2.5
6 span: 1
Ввод предопределенных значений
Простые значения
Выбор из заранее заданных значений. В интерфейсе пользователь видит то значение, которое выбирает
1- key: kubeVersion
2 type: string
3 title: Версия Kubernetes
4 enum:
5 - Automatic
6 - "1.25"
7 - "1.26"
8 - "1.27"
Сложные значения
Выбор из заранее заданных объектных значений. В интерфейсе пользователь видит значение из text
, в
то время как для шаблона технически выбирается value
. Обратите внимание, что в value
доступны
только значения типа object (ключ-значение). Это значение не описывается схемой, структура объекта
произвольна.
1- key: kubeVersion
2 title: Версия Kubernetes
3 select:
4 - text: По умолчанию
5 value:
6 version: Automatic
7 isSupported: true
8 - text: 1.25 (поддержка закончится в марте)
9 value:
10 version: 1.25.8
11 isSupported: true
12 - text: 1.26
13 value:
14 version: 1.26.4
15 isSupported: true
16 - text: 1.27
17 value:
18 version: 1.27.3
19 isSupported: true
20 - text: 1.28 (экспериментальная)
21 value:
22 version: 1.28.0
23 isSupported: false
Поля, доступные в шаблоне кластера
Выбор одной записи из каталога
Каталоги имеют неизменяемое техническое имя (slug). Оно указывается в свойстве catalog
:
1- key: slot
2 catalog: yandex-cloud-slot
3 title: Слот для кластера
4 immutable: true
5 description: >
6 Выберите букву. Она определит домен, префикс в облаке и IP-адрес. Этот слот
7 уникален для всех кластеров независимо от шаблона.
8
9 Допустим вы выбрали `N`. Шаблон домена будет `%s.X.kube.example.com`. Рекомендуем назвать кластер `dev-X`
10
11 Логин и пароль — всегда `admin@example.com`
Выбор нескольких записей
Множественный выбор обеспечивается парой свойств: minItems
и maxItems
. Любое поле можно сделать
списком данных, если указать оба этих поля.
1- key: slot
2 catalog: virtual-machines
3 title: Воркер-узлы
4 description: Сколько угодно воркеров, можно редактировать
5 minItems: 0
6 maxItems: 10000
Автовыбор
Иногда пользователю неважно, какая именно запись будет выбрана из каталога. Поэтому авто-выбор делает подстановку свободной записи автоматически. Автоматически выбранную запись можно заменить вручную на другой.
1- key: publicAddressesForFrontendNodes
2 title: Публичные адреса
3 catalog: public-ip-addresses
4 minItems: 3
5 maxItems: 3
6 autoselect: true
Составные части
Разделитель
header
- Тип: string
Единственный тип разделителя — заголовок. Он поддерживает только текст. Других свойств у него нет.
1- header: Доступ к образам
Свойства полей ввода
key
- Тип: string
Значение поля ввода нужно идентифицировать в шаблоне. Поэтому всегда должно быть свойство поля key
— это имя поля будет использоваться в шаблоне во время рендеринга конфигурации.
- Обязательное поле
В схеме:
1- key: podSubnet
2 title: Подсеть подов
3 type: string
В шаблоне:
1podSubnet: {{.podSubnet | quote }}
type
- Тип: string
- Обязательное поле
- Допустимые значения:
string
number
boolean
У значения есть заранее заданный тип: строка, число или булевый.
title
- Тип: string
- Обязательное поле
У поля есть название, передающее смысл. Это одна строка текста. Оно отображается в форме параметров и в аудите.
description
- Тип: string
У поля может быть комментарий, раскрывающий смысл, объясняющий граничные условия, формат записи или исключения. Может быть несколько строк текста.
default
- Тип: зависит от
type
Значение по умолчанию заполняется, если поле отмечено необязательным. Также это значение показано
пользователю, например, в виде подсказки. Тип значения этого свойства должен совпадать с type
.
format
- Тип: string
У строк может быть формат, который определит особенности отображения и особенности валидации значений.
- Допустимые значения:
password
date-time
url
email
uuid
cuid
cuid2
ulid
emoji
span
- Тип: number
- Допустимые значения:
1
,2
,3
,4
- По умолчанию:
1
Это декоративное свойство, которое указывает, какую ширину занять на экране в долях: от 1 до 4. Поля ввода заполняют форму построчно по горизонтали, как текст. При этом ширина «строки» формы — это 4 элемента.
optional
- Тип: boolean
- По умолчанию:
false
Этот флаг говорит о том, что поле необязательное. Пустое значение будет проигнорировано, и свойство не будет передано в шаблон.
immutable
- Тип: boolean
- По умолчанию:
false
Этот флаг говорит о том, что поле заполняется только один раз, когда появляется во входных параметрах. Это поле становится недоступным для редактирования, если оно было уже заполнено. Это означает, что при обновлении кластера на новый шаблон с immutable-полем, его можно заполнить. Иммутабельность зависит от жизненного цикла параметра в форме, а не кластера.
enum
- Тип: array
Перечисляет допустимые значения, которое принимает поле. Поле представляет собой селект независимо
для типа значения, выбранного в type
.
selector
- Тип: array
Это более сложный вариант enum
. В нем заложено строковое представление объекта (text
) и
произвольно сложное значение в value
, которое будет выбрано для шаблона. Текст указывают для
людей, а значения — для шаблона.
Пример:
1- key: kubeVersion
2 title: Версия Kubernetes
3 select:
4 - text: По умолчанию
5 value:
6 version: Automatic
7 isSupported: true
8 - text: 1.25 (поддержка закончится в марте)
9 value:
10 version: 1.25.8
11 isSupported: true
12 - text: 1.26
13 value:
14 version: 1.26.4
15 isSupported: true
16 - text: 1.27
17 value:
18 version: 1.27.3
19 isSupported: true
20 - text: 1.28 (экспериментальная)
21 value:
22 version: 1.28.0
23 isSupported: false
catalog
- Тип: string
Выбор одного значения из каталога. В значение вписать slug каталога. Поле type
указывать не нужно, потому что фактически это object
, схема которого описана в указанном каталоге.
Чтобы выбрать несколько значений (и получить список записей на входе в шаблон), используйте
minItems
и maxItems
.
Пример:
1- key: workerMachine
2 title: Виртуальная машина
3 catalog: virtual-machines
4
5- key: workerMachines
6 title: Виртуальные машины
7 catalog: virtual-machines
8 minItems: 1
9 maxItems: 10
maxLength
(для строки)
- Тип: number
Для type: string
это поле добавляет валидацию на длину строки
minItems
, maxItems
(для выбора записей)
- Тип: number
Валидация количества элементов выбранных из каталога. Эта пара полей необязательна, но использовать их порознь запрещено: если использовать, то оба сразу.
autoselect
(для выбора записей)
- Тип: boolean
- По умолчанию:
false
Иногда пользователю не столь важно, какая именно запись будет выбрана. Тогда форма выбирает сама за пользователя доступные записи. Но у пользователя при этом всегда есть возможность их изменить.
Пример:
1- key: publicAddressesForFrontendNodes
2 title: Публичные адреса
3 catalog: public-ip-addresses
4 minItems: 3
5 maxItems: 3
6 autoselect: true
identifier
- Тип: boolean
- По умолчанию: зависит от заполнения
Запись — это плоский объект. У записи есть компактное представление в одну строку, составленное из
значений полей записи (без ключей). Значения записи указаны через запятую в порядке, заданной
схемой. Это компактное представление можно видеть как в перечне записей внутри каталога, так и в
выборе записи в форме кластера (выпадающие списки). Чтобы выбрать ограниченный набор полей для
компактного отображения записи, используйте свойство identifier
.
Например, рассмотрим запись и возможные варианты ее схемы
1## Запись
2login: anatoly
3password: E3xE#%DH@hW
4age: 42
Использовать все поля | Спрятать | Показывать явно | |
---|---|---|---|
Схема |
|
|
|
Представление |
|
|
|
Поведение |
По умолчанию для всех полей |
По умолчанию для всех полей |
Если явно указано |
unique
- Тип: boolean
- По умолчанию:
false
Этим флагом помечаются поля записи, которые должны быть уникальными в рамках каталога. Неуникальные данные запрещено создавать, восстанавливать из архива или импортировать.
Также этим флагом помечаются поля кластера, которые должны быть уникальными среди всех кластеров. Неуникальные данные запрещено сохранять: создание и редактировать кластера завершится с ошибкой валидации.
Выбор из каталога для кластеров уникален настолько, насколько уникальны записи. Выбор из каталога не требуется отмечать этим флагом.
1- key: subnetCIDR
2 type: string
3 title: CIDR подсети
4 unique: true