Этот раздел охватывает дополнительные аспекты интеграции Deckhouse Kubernetes Platform (DKP) с Yandex Cloud:
- подключение облачных дисков через CSI;
- автоматическое создание StorageClass;
- использование балансировщиков нагрузки;
- особенности применения изменений;
- работу с CloudStatic-узлами и bastion-хостами.
Хранилище (CSI и StorageClass)
DKP обеспечивает интеграцию с блочным хранилищем Yandex Cloud через компонент Container Storage Interface (CSI). Это даёт возможность кластерам DKP автоматически заказывать и подключать диски, а также использовать стандартные Kubernetes-ресурсы PersistentVolumeClaim для работы с хранилищем.
DKP автоматически создает ресурсы StorageClass для всех поддерживаемых типов дисков Yandex Cloud. Это делает возможным для всех пользователей сразу использовать хранилище, не создавая вручную описания классов.
Поддерживаются следующие типы дисков:
| Тип диска | Имя StorageClass | Комментарии |
|---|---|---|
network-hdd |
network-hdd |
— |
network-ssd |
network-ssd |
— |
network-ssd-nonreplicated |
network-ssd-nonreplicated |
Размер кратен 93 ГБ |
network-ssd-io-m3 |
network-ssd-io-m3 |
Размер кратен 93 ГБ |
Размеры дисков network-ssd-nonreplicated и network-ssd-io-m3 должны быть кратны 93 ГБ, иначе произойдёт ошибка при заказе тома.
Исключение ненужных StorageClass
Если в кластере не планируется использовать определённые типы дисков, можно отключить автоматическое создание соответствующих StorageClass. Это делается с помощью параметра settings.storageClass.exclude в ресурсе ModuleConfig:
settings:
storageClass:
exclude:
- network-ssd-.*
- network-hdd
В приведённом примере DKP не создаст StorageClass для всех network-ssd дисков и для network-hdd.
Назначение StorageClass по умолчанию
По умолчанию DKP выбирает StorageClass на основе аннотации storageclass.kubernetes.io/is-default-class=true.
Чтобы задать другой StorageClass по умолчанию, необходимо использовать глобальный параметр DKP global.defaultClusterStorageClass. Изменить его можно следующей командой:
d8 k edit mc global
Если параметр defaultClusterStorageClass не указан, платформа будет определять StorageClass, используемый по умолчанию, в следующем порядке:
- StorageClass с аннотацией
storageclass.kubernetes.io/is-default-class='true'(если такой имеется в кластере). - Первый StorageClass по алфавиту среди тех, что автоматически создаются облачным провайдером.
- По умолчанию значение параметра
defaultClusterStorageClass— пустая строка ("").
Изменение размера PVC
Размер существующего PVC можно увеличить путем изменения значения параметра spec.resources.requests.storage без остановки и пересоздания использующего его пода.
После изменения значения spec.resources.requests.storage CSI-драйвер последовательно:
- увеличивает размер диска в Yandex Cloud;
- обновляет размер связанного PersistentVolume;
- выполняет расширение файловой системы на узле, к которому подключён том.
Во время операции под продолжает работать, а смонтированный том остаётся доступным приложению. После завершения увеличения новый размер файловой системы становится доступен внутри контейнера без перезапуска пода.
Уменьшение размера PVC не поддерживается.
Чтобы увеличить PVC, выполните следующие действия:
-
Получите имя StorageClass, используемого PVC:
d8 k -n <НЕЙМСПЕЙС> get pvc <ИМЯ_PVC> \ -o jsonpath='{.spec.storageClassName}{"\n"}'Где:
<НЕЙМСПЕЙС>— неймспейс, в котором находится PVC;<ИМЯ_PVC>— имя PVC, размер которого необходимо увеличить.
Например:
d8 k -n production get pvc application-data \ -o jsonpath='{.spec.storageClassName}{"\n"}'Пример вывода команды:
network-ssdВ этом примере PVC
application-dataиспользует StorageClassnetwork-ssd. -
Убедитесь, что StorageClass разрешает увеличение томов:
d8 k get storageclass <ИМЯ_STORAGECLASS> \ -o jsonpath='{.allowVolumeExpansion}{"\n"}'Где
<ИМЯ_STORAGECLASS>— имя StorageClass, полученное на предыдущем шаге.Например:
d8 k get storageclass network-ssd \ -o jsonpath='{.allowVolumeExpansion}{"\n"}'Пример вывода команды:
true -
Проверьте текущее состояние и размер PVC:
d8 k -n <НЕЙМСПЕЙС> get pvc <ИМЯ_PVC>Например:
d8 k -n production get pvc application-dataПример вывода:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS application-data Bound pvc-65e92674-077c-4b4f-b65d-19e92f04e103 20Gi RWO network-ssdУбедитесь, что:
- PVC находится в состоянии
Bound; - в поле
CAPACITYуказан текущий размер PVC; - в поле
STORAGECLASSуказан StorageClass, проверенный на предыдущем шаге.
- PVC находится в состоянии
-
Увеличьте размер PVC:
d8 k -n <НЕЙМСПЕЙС> edit pvc <ИМЯ_PVC>Например:
d8 k -n production edit pvc application-dataВ поле
spec.resources.requests.storageукажите новый размер PVC:spec: resources: requests: storage: 30GiВ этом примере размер PVC увеличивается до 30Gi.
Сохраните изменения и закройте редактор.
Для StorageClass
network-ssd-nonreplicatedиnetwork-ssd-io-m3размер должен быть кратен 93Gi. -
Дождитесь увеличения PVC:
d8 k -n <НЕЙМСПЕЙС> get pvc <ИМЯ_PVC> --watchГде:
<НЕЙМСПЕЙС>— неймспейс, в котором находится PVC;<ИМЯ_PVC>— имя PVC, размер которого увеличивается.
Например:
d8 k -n production get pvc application-data --watchВо время увеличения в поле
CAPACITYможет отображаться прежний размер:NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS application-data Bound pvc-65e92674-077c-4b4f-b65d-19e92f04e103 20Gi RWO network-ssdОперация завершена, когда в поле
CAPACITYотображается новый размер PVC:NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS application-data Bound pvc-65e92674-077c-4b4f-b65d-19e92f04e103 30Gi RWO network-ssd -
Проверьте события PVC:
d8 k -n <НЕЙМСПЕЙС> describe pvc <ИМЯ_PVC>Например:
d8 k -n production describe pvc application-dataВо время увеличения могут появиться следующие события:
ExternalExpanding Resizing FileSystemResizeRequiredОб успешном увеличении файловой системы свидетельствует событие:
FileSystemResizeSuccessfulНапример:
Normal FileSystemResizeSuccessful kubelet MountVolume.NodeExpandVolume succeeded for volume "pvc-65e92674-077c-4b4f-b65d-19e92f04e103" -
Проверьте размер файловой системы внутри пода:
d8 k -n <НЕЙМСПЕЙС> exec <ИМЯ_ПОДА> -- \ df -hT <ТОЧКА_МОНТИРОВАНИЯ>Где:
<НЕЙМСПЕЙС>— неймспейс, в котором находится под;<ИМЯ_ПОДА>— имя пода, использующего PVC;<ТОЧКА_МОНТИРОВАНИЯ>— путь внутри контейнера, в который смонтирован PVC.
Например:
d8 k -n production exec application-0 -- \ df -hT /dataПример вывода:
Filesystem Type Size Used Avail Use% Mounted on /dev/vde ext4 29.4G 22M 29.4G 1% /dataФактический размер файловой системы может быть немного меньше размера PVC из-за служебных данных файловой системы.
Балансировка нагрузки
Внешний LoadBalancer
DKP автоматически подписывается на Kubernetes-объекты Service с типом LoadBalancer. При их создании в кластере, он создаёт соответствующие ресурсы:
- NetworkLoadBalancer — сетевой балансировщик нагрузки в Yandex Cloud;
- TargetGroup — группа конечных точек для балансировки трафика.
Эти ресурсы предоставляют Kubernetes-сервисам с типом LoadBalancer возможность принимать входящий трафик из интернета или внутренних сетей в зависимости от настроек.
Подробнее об архитектуре см. в в документации Kubernetes Cloud Controller Manager for Yandex Cloud.
Внутренний LoadBalancer
Чтобы создать внутренний балансировщик (INTERNAL LoadBalancer), укажите подсеть, в которой должен быть создан listener:
Для этого добавьте следующую аннотацию в объект Service:
metadata:
annotations:
yandex.cpi.flant.com/listener-subnet-id: <SubnetID>
Значение SubnetID — это ID подсети, в которой будет создан внутренний слушатель Yandex LoadBalancer. Использование этой аннотации даёт возможность контролировать сетевую доступность балансировщика, ограничивая его только внутренними адресами.
Поведение по умолчанию (внешний или внутренний LB) зависит от конфигурации кластера. Для явного выбора типа используйте аннотацию
yandex.cpi.flant.com/loadbalancer-external.
Аннотации объекта Service
В кластере заданы значения по умолчанию для размещения ресурсов балансировщиков (сеть для целевой группы и подсеть для Listener). Эти значения выставляются автоматически во время развёртывания кластера и могут быть переопределены аннотациями на уровне конкретного Service.
В Yandex Cloud Controller Manager поддерживаются следующие аннотации:
yandex.cpi.flant.com/target-group-network-id— указывает NetworkID, в котором будет создана целевая группа для данного Service. Переопределяет соответствующее значение по умолчанию.yandex.cpi.flant.com/listener-subnet-id— задаёт SubnetID для Listener’ов создаваемого LB для данного Service. Переопределяет соответствующее значение по умолчанию.yandex.cpi.flant.com/listener-address-ipv4— задаёт предопределённый IPv4-адрес для Listener’ов (поддерживаются и внутренние, и внешние LB).yandex.cpi.flant.com/loadbalancer-external— включает создание внешнего (external) LB для данного Service (используйте, если нужно явно создать внешний балансировщик). Переопределяет поведение по умолчанию.yandex.cpi.flant.com/target-group-name-prefix— задаёт префикс имени целевой группы, которую использует LoadBalancer. Аннотация на Service определяет целевую группу, но не выбирает узлы. Чтобы включить узлы в целевую группу, задайте аннотацию с тем же значением в параметреspec.nodeTemplate.annotationsресурса NodeGroup. Yandex Cloud Controller Manager включает в целевую группу все подходящие узлы с таким значением аннотации независимо от их NodeGroup. Имя целевой группы формируется как<ANNOTATION_VALUE><YANDEX_CLOUD_CLUSTER_NAME><NETWORK_ID>.
Если для control plane или master-узлов создаются отдельные целевые группы, добавьте на master-узлы лейбл node.kubernetes.io/exclude-from-external-load-balancers: "". Это предотвратит попытки контроллера автоматически добавлять master-узлы в новые целевые группы для балансировщиков.
Если вы создаёте собственный балансировщик для master-узлов и хотите, чтобы YCC также мог размещать свои балансировщики на master-узлах, заранее создайте целевую группу с именем по маске ${CLUSTER-NAME}${VPC.ID}.
Использование отдельной целевой группы для NodeGroup
По умолчанию Yandex Cloud Controller Manager добавляет все подходящие узлы кластера в целевую группу по умолчанию. Чтобы назначить узлам отдельную целевую группу, используйте аннотацию yandex.cpi.flant.com/target-group-name-prefix.
-
В NodeGroup, узлы которой должны входить в отдельную целевую группу, задайте аннотацию
yandex.cpi.flant.com/target-group-name-prefixв параметреspec.nodeTemplate.annotations. Например:spec: nodeTemplate: annotations: yandex.cpi.flant.com/target-group-name-prefix: frontend-Аннотация распространяется на объекты Node. Yandex Cloud Controller Manager добавляет в целевую группу все подходящие узлы с таким значением аннотации независимо от их NodeGroup.
-
В объекте Service типа LoadBalancer задайте ту же аннотацию с тем же значением. Например:
metadata: annotations: yandex.cpi.flant.com/target-group-name-prefix: frontend-Аннотация на Service определяет целевую группу, которую использует LoadBalancer, но не выбирает узлы.
-
Убедитесь, что значения
yandex.cpi.flant.com/target-group-name-prefixв NodeGroup и Service совпадают. В примере выше в обоих ресурсах используется значениеfrontend-. -
Целевая группа будет создана с именем, сформированным по шаблону:
<ANNOTATION_VALUE><YANDEX_CLOUD_CLUSTER_NAME><NETWORK_ID>Например, если значение аннотации —
frontend-, имя кластера —my-cluster-, а идентификатор сети —enp123456789, имя целевой группы будет следующим:frontend-my-cluster-enp123456789
Пример конфигурации:
apiVersion: deckhouse.io/v1
kind: NodeGroup
metadata:
name: frontend
spec:
nodeType: CloudEphemeral
nodeTemplate:
annotations:
yandex.cpi.flant.com/target-group-name-prefix: frontend-
---
apiVersion: v1
kind: Service
metadata:
name: nginx-frontend
annotations:
yandex.cpi.flant.com/target-group-name-prefix: frontend-
spec:
type: LoadBalancer
Yandex Cloud не позволяет одному целевому ресурсу (target), определяемому парой (SubnetID, IP), одновременно находиться в нескольких целевых группах.
При изменении целевой группы Yandex Cloud Controller Manager сначала удаляет ресурс из текущей группы, а затем добавляет в новую. Во время перемещения возможен кратковременный перерыв в обработке трафика.
Узлы, для которых задан отдельный префикс целевой группы, исключаются из целевой группы по умолчанию. Поэтому балансировщики, использующие её, перестают направлять трафик на такие узлы.
Такое автоматическое перемещение выполняется только между целевыми группами, которыми управляет Yandex Cloud Controller Manager. Если ресурс уже находится в другой целевой группе, не управляемой Yandex Cloud Controller Manager, удалите ресурс из неё перед использованием аннотации.
После изменения или удаления префикса прежняя целевая группа может остаться пустой. Если она больше не используется балансировщиками, удалите её вручную.
Проверки состояния целевой группы
Параметры healthcheck’ов (для создаваемых целевых групп балансировщика):
yandex.cpi.flant.com/healthcheck-interval-seconds— как часто запускать проверку, в секундах (по умолчанию 2).yandex.cpi.flant.com/healthcheck-timeout-seconds— сколько ждать ответа от эндпоинта, в секундах. Если за это время ответ не получен, проверка считается неуспешной (по умолчанию 1).yandex.cpi.flant.com/healthcheck-unhealthy-threshold— сколько подряд неуспешных проверок нужно, чтобы пометить эндпоинт как неработоспособный (unhealthy) и исключить его из балансировки (по умолчанию 2).yandex.cpi.flant.com/healthcheck-healthy-threshold— сколько подряд успешных проверок нужно, чтобы вернуть эндпоинт в статус работоспособный (healthy) и снова включить его в балансировку (по умолчанию 2).
Особенности применения изменений
DKP не пересоздаёт уже существующие объекты Machine при изменении параметров. Пересоздание узлов происходит только при изменении:
- параметров в секции NodeGroup;
- параметров YandexInstanceClass.
Это поведение помогает избежать лишних операций и простоя существующих узлов, однако требует ручного вмешательства при необходимости пересоздать машины.
Если вы изменили объект YandexClusterConfiguration (например, изменили параметры провайдера, схемы размещения, подсетей и т.д.), чтобы изменения вступили в силу, выполните команду:
dhctl converge
Команда инициирует пересчёт конфигурации и приводит текущее состояние кластера в соответствие с описанным в ресурсах.
Изменение networkType не пересоздаёт CloudEphemeral-узлы
В кластерах, использующих Machine Controller Manager (MCM), изменение параметра networkType в ресурсе YandexInstanceClass не приводит к автоматическому пересозданию существующих CloudEphemeral-узлов. Хотя MachineClass обновляется, тип сетевого ускорения у уже созданных виртуальных машин в Yandex Cloud не изменяется.
DKP намеренно не учитывает параметр networkType при определении необходимости пересоздания CloudEphemeral-узлов в MCM. Если бы он учитывался, обновление DKP привело бы к пересозданию CloudEphemeral-узлов во всех кластерах, где networkType уже указан, даже если его значение не изменялось.
В Cluster API параметр networkType учитывается при определении необходимости пересоздания узлов, поэтому его изменение запускает их обновление автоматически. Новые CloudEphemeral NodeGroup в Yandex по умолчанию используют CAPI.
Если вы изменили networkType в кластере на MCM и хотите, чтобы новое значение применилось к уже существующим CloudEphemeral-узлам, пересоздайте их вручную — инструкция в документации.
Интеграция вручную созданных ВМ
DKP позволяет подключать существующие виртуальные машины в Yandex Cloud к Kubernetes-кластеру в качестве узлов. Такие узлы называются CloudStatic, поскольку они не управляются напрямую модулем node-manager, но могут использоваться в составе кластера.
Чтобы вручную подключить виртуальную машину в качестве CloudStatic-узла, необходимо:
-
Узнать актуальное значение
nodeNetworkCIDRиз кластера:d8 k -n kube-system get secret d8-provider-cluster-configuration -o json | \ jq --raw-output '.data."cloud-provider-cluster-configuration.yaml"' | base64 -d | grep '^nodeNetworkCIDR'Результатом будет строка вида:
nodeNetworkCIDR: 192.168.12.13/24Это значение необходимо скопировать и указать как
valueв метаданных виртуальной машины. -
Задать параметр
node-network-cidrв метаданных ВМ:key: node-network-cidr value: <nodeNetworkCIDR из кластера>Параметр
node-network-cidrдолжен совпадать с тем значением, которое указано в объекте YandexClusterConfiguration, полеnodeNetworkCIDR.