Закрепление компонентов за узлами#
При необходимости каждый компонент платформы и его оператор можно закрепить за выбранными рабочими узлами кластера Kubernetes.
По умолчанию планировщик Kubernetes размещает поды платформы на любых рабочих узлах. Поэтому при развертывании без доступа в интернет все образы контейнеров загружаются на каждый рабочий узел.
Закрепление компонентов необходимо в следующих случаях:
образы загружены не на все рабочие узлы, например каждый узел получает только образы тех компонентов, которые на нем работают;
отдельные компоненты платформы необходимо выделить на собственные узлы.
После выполнения инструкции поды каждого компонента и его оператора работают только на узлах своей роли, а группа контейнеров создает поды заданий Automation Controller на выбранных узлах.
Инструкция дополняет подготовку без доступа в интернет и подготовку манифестов, а само развертывание идет по общей инструкции с отличиями, описанными далее. Пример манифеста приложения построен на манифесте базовой топологии без доступа в интернет.
Примечание
Инструкция не описывает закрепление переходных узлов (AutomationControllerMeshIngress), а также расчет дискового пространства узлов, импорт образов при нехватке места, доставку контента в Private Automation Hub без импортера и обновление версии платформы.
Порядок действий#
Для закрепления компонентов за узлами выполните следующие действия:
Создайте секреты, как описано в инструкции по подготовке манифестов.
После развертывания платформы закрепите поды заданий.
Операторы необходимо устанавливать только после загрузки образов, так как под без локального образа не стартует и переходит в состояние ImagePullBackOff или ErrImagePull.
Роли и метки узлов#
Роль определяет, какие поды платформы работают на узле. Инструкция различает следующие роли:
Роль |
Поды на узле |
|---|---|
|
Шлюз платформы и оператор |
|
Поды |
|
Поды |
|
Поды Event-Driven Automation, собственные PostgreSQL и Redis Event-Driven Automation, оператор |
|
Общие PostgreSQL и Redis платформы для шлюза, Automation Controller и Private Automation Hub. |
|
Под Automation Dashboard, его собственные PostgreSQL и Redis, оператор |
Один узел может нести несколько ролей, а одну роль могут нести несколько узлов.
Например, в кластере из четырех рабочих узлов роли можно распределить так: первый узел – controller, второй – gateway и hub, третий – eda и db, четвертый – dashboard.
Роль узла задает метка вида aa.astra/<role>=true.
Название метки произвольное, однако оно должно совпадать в метках узлов, в манифестах операторов и в манифесте приложения.
Примеры далее содержат метки aa.astra/gateway, aa.astra/controller, aa.astra/hub, aa.astra/eda, aa.astra/db и aa.astra/dashboard.
Назначьте роли узлам, например:
kubectl label node worker-1.example.com aa.astra/controller=true
kubectl label node worker-2.example.com aa.astra/gateway=true aa.astra/hub=true
kubectl label node worker-3.example.com aa.astra/eda=true aa.astra/db=true
kubectl label node worker-4.example.com aa.astra/dashboard=true
Проверьте назначенные метки:
kubectl get nodes -L aa.astra/gateway,aa.astra/controller,aa.astra/hub,aa.astra/eda,aa.astra/db,aa.astra/dashboard
В столбце каждой метки значение true должно стоять у узлов соответствующей роли.
Образы для узлов каждой роли#
На каждый узел необходимо загрузить образы всех его ролей из каталога images/ комплекта поставки.
Если одну роль несут несколько узлов, образы роли необходимы каждому из них.
Роль |
Образы |
Примечания |
|---|---|---|
|
|
Под шлюза состоит из контейнеров |
|
|
Образ |
|
|
У Private Automation Hub собственный Redis.
Под |
|
|
У Event-Driven Automation собственные PostgreSQL и Redis, которые создает |
|
|
Общие PostgreSQL и Redis платформы обслуживают шлюз, Automation Controller и Private Automation Hub. |
|
|
У Automation Dashboard собственные PostgreSQL и Redis.
Под оператора |
Образ kube-rbac-proxy необходим на каждом узле, где работает оператор aa-operator, ac-operator, pah-operator или eda-operator, так как под каждого из этих операторов содержит контейнер kube-rbac-proxy.
Образ ubi18 входит в набор образов операторов Automation Controller и Private Automation Hub: ac-operator указывает его для init-контейнера постоянного тома проектов, а pah-operator – для init-контейнера подписи GPG.
В базовой топологии поды платформы этот образ не используют.
Загрузить его на узлы ролей controller и hub рекомендуется, чтобы конфигурации с этими init-контейнерами не остались без образа.
Предупреждение
Селекторы манифеста приложения не закрепляют под импортера контента Private Automation Hub (параметр offline_content_loader).
Оператор pah-operator создает этот под объектом Job без селектора узлов, правил affinity и допусков tolerations, поэтому параметр hub.node_selector на него не действует.
Планировщик предпочитает узлы, на которых образ уже загружен, однако это предпочтение не гарантирует размещение.
Поэтому при включенном импортере образ k8s-hub-content-importer необходимо загрузить на все рабочие узлы, на которых планировщик может разместить этот под.
Этот образ – самый большой в комплекте поставки.
Сценарий tools/load-containerd-images.yml загружает все образы каталога images/ на все узлы инвентаря.
Для загрузки только образов роли скопируйте на узел файлы нужных образов и импортируйте каждый из них в containerd:
sudo ctr -n k8s.io images import <image_name>_<version>.tar
Здесь:
<image_name>– название образа из таблицы выше;<version>– версия Astra Automation, например2.1.
Проверьте состав образов на узле:
sudo ctr -n k8s.io images ls -q | grep '/aa/'
В выводе должны присутствовать все образы ролей узла.
Закрепление операторов#
Каждый оператор работает в поде, созданном объектом Deployment из манифеста каталога operators/ комплекта поставки.
В этих объектах селектор узлов не задан, поэтому команда kubectl apply -f operators/ из инструкции по развертыванию размещает операторы на любых узлах.
Объект Deployment находится в одном файле с определениями собственных ресурсов (CRD) и объектами управления доступом, поэтому манифест оператора необходимо изменить до применения, добавив в Deployment параметр nodeSelector.
Соответствие операторов ролям:
Файл манифеста |
Объект |
Метка узла |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Если Automation Dashboard не развертывают, роль dashboard и ее оператор пропускают.
Для установки операторов с закреплением выполните следующие действия:
В каталоге комплекта поставки создайте каталог для измененных манифестов и скопируйте в него манифесты пяти операторов:
mkdir operators-pinned cp operators/aa-operator-deploy.yaml operators/ac-operator-deploy.yaml \ operators/pah-operator-deploy.yaml operators/eda-operator-deploy.yaml \ operators/dashboard-operator-deploy.yaml operators-pinned/
Исходные манифесты в каталоге
operators/остаются без изменений.В каждом скопированном файле найдите объект с
kind: Deploymentи добавьте в его разделspec.template.specпараметрnodeSelectorс меткой роли оператора. Например, дляaa-operator-deploy.yaml:kind: Deployment metadata: name: aa-operator-aa-manager spec: template: spec: nodeSelector: aa.astra/gateway: "true"
Здесь приведены только поля, которые определяют место вставки. Параметр
nodeSelectorнеобходимо добавить на одном уровне с параметромcontainers, остальное содержимое объекта остается прежним. Значение"true"необходимо заключить в кавычки, так как значение метки – строка.Убедитесь, что селектор добавлен во все пять файлов:
grep -A1 'nodeSelector:' operators-pinned/*.yaml
Ожидаемый результат: команда выводит для каждого файла строку
nodeSelector:и следующую за ней метку роли.Примените измененные манифесты:
kubectl apply -f operators-pinned/
Проверьте, что селекторы попали в объекты
Deploymentи что поды операторов работают на узлах своих ролей:kubectl -n astra-automation get deployments \ -o custom-columns=NAME:.metadata.name,NODE_SELECTOR:.spec.template.spec.nodeSelector kubectl -n astra-automation get pods -o wide
Поды операторов
aa-operator,ac-operator,pah-operatorиeda-operatorдолжны находиться в состоянии2/2 Running, а подdashboard-operator– в состоянии1/1 Running, так как он содержит один контейнер. СтолбецNODEдолжен содержать узлы соответствующих ролей.
Селекторы в манифесте приложения#
Для размещения компонентов платформы предназначены параметры node_selector в манифесте AstraAutomation.
Оператор aa-operator передает их в ресурсы компонентов, а операторы компонентов – в объекты Deployment и StatefulSet.
Блок spec.dashboard целиком становится разделом spec отдельного ресурса Dashboard (dashboard.astra-automation.ru/v1alpha1), который создает aa-operator.
Параметр |
Тип значения |
Что закрепляет |
|---|---|---|
|
Словарь |
Под шлюза платформы. |
|
Словарь |
Общую PostgreSQL платформы. |
|
Словарь |
Общий Redis платформы. |
|
Строка YAML |
Поды Automation Controller. |
|
Строка YAML |
Под |
|
Строка YAML |
Под |
|
Строка YAML |
Все поды Private Automation Hub, включая его Redis, кроме пода импортера контента. |
|
Словарь |
Компонент Event-Driven Automation.
Селектор необходимо задавать отдельно для каждого компонента: |
|
Словарь |
Под Automation Dashboard.
Число реплик задает параметр |
|
Словарь |
PostgreSQL Automation Dashboard. |
|
Словарь |
Redis Automation Dashboard. |
Предупреждение
У Automation Controller и Private Automation Hub селектор задают строкой YAML в блочном скаляре |, а у шлюза, общих PostgreSQL и Redis, компонентов Event-Driven Automation и Automation Dashboard – словарем:
controller:
node_selector: |
aa.astra/controller: "true"
api:
node_selector:
aa.astra/gateway: "true"
Ошибку в типе значения обнаруживают разные проверки:
Строку вместо словаря в параметрах
api,databaseиredisсервер API Kubernetes отвергает при применении манифеста, например:The AstraAutomation "aa-demo" is invalid: spec.api.node_selector: Invalid value: "string": spec.api.node_selector in body must be of type object: "string"
Словарь вместо строки в блоках
controllerиhubсервер API принимает, так как в определении ресурсаAstraAutomationблокиcontroller,hub,edaиdashboardдопускают произвольные поля (x-kubernetes-preserve-unknown-fields). Примерно через две минуты операторaa-operatorдобавляет ресурсуAstraAutomationусловиеFailureсо значениемTrueи сообщениемunknown playbook failure. Оператор прерывает согласование: селекторы компонентов остаются прежними, а дочерние ресурсы дальше по цепочке оператор не обновляет.
Если у ресурса AstraAutomation появилось условие Failure, проверьте тип значения пробным изменением ресурса компонента на сервере, например для Automation Controller:
kubectl -n astra-automation patch acs ac-demo --type merge \
-p '{"spec":{"node_selector":{"aa.astra/controller":"true"}}}' --dry-run=server
При неверном типе значения команда выводит причину: spec.node_selector in body must be of type string: "object".
Пример манифеста приложения для базовой топологии без доступа в интернет с закреплением всех компонентов:
---
apiVersion: aa.astra-automation.ru/v1alpha1
kind: AstraAutomation
metadata:
name: aa-demo
namespace: astra-automation
spec:
image_pull_policy: IfNotPresent
# Шлюз платформы: словарь
api:
replicas: 1
node_selector:
aa.astra/gateway: "true"
# Общие PostgreSQL и Redis платформы: словари
database:
node_selector:
aa.astra/db: "true"
redis:
node_selector:
aa.astra/db: "true"
# Automation Controller: строки YAML
controller:
disabled: false
name: ac-demo
replicas: 1
image_pull_policy: IfNotPresent
ee_pull_credentials_secret: "ac-ee-pull-secret"
default_ee_image: "aa-demo.example.com/aa-2.1/aa-full-ee:latest"
control_plane_execution_environment: "aa-demo.example.com/aa-2.1/aa-control-ee:latest"
control_plane_ee_image: registry.astra.ru/aa/aa-control-ee:2.1
node_selector: |
aa.astra/controller: "true"
task_node_selector: |
aa.astra/controller: "true"
web_node_selector: |
aa.astra/controller: "true"
# Private Automation Hub: строка YAML, действует на все поды Hub
hub:
disabled: false
name: pah-demo
image_pull_policy: IfNotPresent
storage_type: File
file_storage_access_mode: ReadWriteMany
file_storage_size: "40Gi"
file_storage_storage_class: longhorn
offline_content_loader:
enabled: true
image_name: registry.astra.ru/aa/k8s-hub-content-importer:2.1
namespace: aa-2.1
node_selector: |
aa.astra/hub: "true"
api:
replicas: 1
content:
replicas: 1
web:
replicas: 1
worker:
replicas: 1
redis:
replicas: 1
# Event-Driven Automation: словарь у каждого компонента
eda:
disabled: false
name: eda-demo
image_pull_policy: IfNotPresent
default_de_image: "aa-demo.example.com/aa-2.1/aa-full-de:latest"
api:
replicas: 1
node_selector:
aa.astra/eda: "true"
ui:
replicas: 1
node_selector:
aa.astra/eda: "true"
event_stream:
replicas: 1
node_selector:
aa.astra/eda: "true"
default_worker:
replicas: 1
node_selector:
aa.astra/eda: "true"
activation_worker:
replicas: 1
node_selector:
aa.astra/eda: "true"
worker:
replicas: 1
node_selector:
aa.astra/eda: "true"
scheduler:
replicas: 1
node_selector:
aa.astra/eda: "true"
redis:
replicas: 1
node_selector:
aa.astra/eda: "true"
database:
node_selector:
aa.astra/eda: "true"
# Automation Dashboard: словарь у каждого компонента
dashboard:
ingress_type: ingress
ingress_class_name: nginx
dashboard:
replicas: 1
node_selector:
aa.astra/dashboard: "true"
database:
node_selector:
aa.astra/dashboard: "true"
redis:
node_selector:
aa.astra/dashboard: "true"
ingress_type: Ingress
ingress_class_name: nginx
# ingress_tls_secret: aa-tls-secret
# public_base_url: https://aa-demo.example.com
# hostname: aa-demo.example.com
По сравнению с исходным манифестом пример содержит следующие изменения:
селектор узлов у каждого компонента;
блок
dashboardс селекторами узлов для самого Automation Dashboard, его PostgreSQL и Redis;явное число реплик у каждого компонента (см. Число реплик);
параметр
image_pull_policy: IfNotPresentна уровне приложения и в блоках компонентов, при котором под использует образ, уже загруженный на узел;файловое хранилище Private Automation Hub вместо S3: параметры
storage_type: File,file_storage_access_mode,file_storage_sizeиfile_storage_storage_classбез параметраobject_storage_s3_secret(см. переход на файловое хранилище).
Блок dashboard не содержит параметр hostname, так как интерфейс Automation Dashboard доступен по пути /dashboard на хосте платформы.
Секрет из параметра ee_pull_credentials_secret необходимо создать в формате, описанном в разделе Секрет для доступа к образам среды исполнения.
Остальные параметры, включая параметры публикации через Ingress, необходимо заполнять так же, как в исходном манифесте.
Примените манифест, как описано в инструкции по развертыванию.
Число реплик#
Селектор ограничивает все реплики компонента узлами с меткой его роли. Поэтому реплика оказывается на узле без образа только в том случае, если метку роли несет узел, на который образы этой роли не загружены.
Селектор не распределяет реплики по разным узлам: несколько реплик могут оказаться на одном узле с меткой. Если число реплик в манифесте не задано, оператор использует значение по умолчанию, которое у части компонентов больше единицы. Поэтому в примере число реплик задано явно у каждого компонента.
Для распределения реплик компонента по нескольким узлам выполните следующие действия:
Назначьте метку роли нескольким узлам.
Загрузите образы роли на каждый из этих узлов.
Задайте в манифесте приложения нужное число реплик компонента.
Закрепление подов заданий#
Группа контейнеров default создает для каждого задания Automation Controller отдельный под.
Селекторы манифеста приложения на эти поды не действуют, поэтому без дополнительной настройки планировщик размещает под задания на любом рабочем узле.
Узел, на котором работает под задания, загружает из Private Automation Hub образ среды исполнения этого задания.
Для закрепления подов заданий за узлами выполните следующие действия:
Откройте окно Группы исполняющих узлов (Instance Groups).
В строке группы контейнеров
defaultнажмите кнопку перехода в окно изменения данных о группе.Включите настройку Настроить спецификацию пода (Customize pod spec).
В поле Переопределение спецификации пода (Pod spec override) добавьте в раздел
specпараметрnodeSelectorс меткой узлов для заданий, например:spec: nodeSelector: aa.astra/controller: "true"
Сохраните изменения.
Остальные поля спецификации пода указывать не требуется.
При создании пода задания контроллер объединяет переопределение со спецификацией пода по умолчанию, поэтому для закрепления достаточно одного параметра nodeSelector.
Для заданий можно использовать узлы роли controller или выделить им отдельную роль с собственной меткой.
Спецификацию пода можно также изменить через API в поле pod_spec_override группы контейнеров: PATCH /api/controller/v2/instance_groups/<id>/.
Важно
Под задания загружает образ среды исполнения из Private Automation Hub через Ingress, поэтому containerd на узлах заданий должен доверять сертификату Ingress.
Без настроенного доверия к сертификату корпоративного или собственного удостоверяющего центра containerd прерывает загрузку образа с ошибкой x509: certificate signed by unknown authority.
Для настройки доверия на каждом узле заданий создайте каталог /etc/containerd/certs.d/<ingress_fqdn>/ с файлами hosts.toml и ca.crt и укажите этот каталог в параметре config_path файла /etc/containerd/config.toml.
Порядок действий приведен в разделе Способ 2. Отдельный файл hosts.toml, другие способы – в разделе Доверие containerd на рабочих узлах Kubernetes.
Проверка результата#
Проверьте размещение подов платформы:
kubectl -n astra-automation get pods -o wide
Пример вывода для четырех рабочих узлов с ролями из примера выше (часть столбцов опущена):
NAME READY STATUS NODE
aa-demo-dashboard-5b9df95c69-p8whv 2/2 Running worker-4.example.com
aa-demo-dashboard-postgres-15-0 1/1 Running worker-4.example.com
aa-demo-dashboard-redis-5d64ddcbbc-ngwxc 1/1 Running worker-4.example.com
aa-demo-gateway-6bfb554c9-fzn2m 2/2 Running worker-2.example.com
aa-demo-postgres-15-0 1/1 Running worker-3.example.com
aa-demo-redis-0 1/1 Running worker-3.example.com
aa-operator-aa-manager-6d7d4799d8-zxjt2 2/2 Running worker-2.example.com
ac-demo-migration-3.1.1-h6b7p 0/1 Completed worker-1.example.com
ac-demo-task-7fcf6b647-r9smk 4/4 Running worker-1.example.com
ac-demo-web-7f797cbf94-p9jf6 3/3 Running worker-1.example.com
ac-operator-ac-manager-5fb5b566d4-bsxdm 2/2 Running worker-1.example.com
dashboard-operator-dashboard-manager-56989856cf-vlt9t 1/1 Running worker-4.example.com
eda-demo-activation-worker-8669d8c7ff-k4vhj 1/1 Running worker-3.example.com
eda-demo-api-7d5d77bb89-7j86g 3/3 Running worker-3.example.com
eda-demo-default-worker-69fcf77b45-4whdj 1/1 Running worker-3.example.com
eda-demo-event-stream-5684b9d554-8lns2 2/2 Running worker-3.example.com
eda-demo-postgres-15-0 1/1 Running worker-3.example.com
eda-demo-redis-77b785cb78-rm8hc 1/1 Running worker-3.example.com
eda-demo-scheduler-6fcf645b64-nrxjr 1/1 Running worker-3.example.com
eda-operator-eda-manager-5c9cb75df8-bl7rv 2/2 Running worker-3.example.com
pah-demo-api-75bc8bd5fb-qv564 1/1 Running worker-2.example.com
pah-demo-content-c8cd8ff8f-t2np8 1/1 Running worker-2.example.com
pah-demo-importer-6fbfe27cfa27-fkfhs 0/1 Completed worker-2.example.com
pah-demo-redis-7c5b8dcfbb-xtszd 1/1 Running worker-2.example.com
pah-demo-web-6bc9c6497f-rf949 1/1 Running worker-2.example.com
pah-demo-worker-77cf99449f-6rz7p 1/1 Running worker-2.example.com
pah-operator-pah-manager-7fb69df6c-tjjxw 2/2 Running worker-2.example.com
Каждый под должен находиться на узле своей роли.
Отдельные поды для компонентов ui и worker Event-Driven Automation в выводе отсутствуют.
Под импортера контента Private Automation Hub в примере оказался на узле роли hub, так как образ импортера загружен только на этот узел, однако инструкция закрепление этого пода не гарантирует.
Проверьте селекторы в объектах платформы:
kubectl -n astra-automation get deployments,statefulsets \
-o custom-columns=NAME:.metadata.name,NODE_SELECTOR:.spec.template.spec.nodeSelector
У каждого объекта столбец NODE_SELECTOR должен содержать метку роли компонента.
Для проверки подов заданий запустите любое задание и определите узел, на котором создан его под:
kubectl get pods -A -o wide -w | grep automation-job
Под задания должен появиться на узле с меткой, указанной в спецификации пода группы контейнеров default.
Если под находится в состоянии ImagePullBackOff или ErrImagePull, определите узел и образ командой kubectl -n astra-automation describe pod <pod_name>.
Затем проверьте метки этого узла и загрузите на него недостающий образ.