Лейблы, аннотации и taints в Cluster API

В платформе «Штурвал» на странице узла доступно присвоение лейблов и аннотаций для Cluster API, инфраструктуры и узла, а на вкладке Taints можно управлять taints конкретного Node.

Чтобы лейблы или taints применялись ко всем узлам группы, возможно задавать не вручную на каждой ноде, а в CAPI-ресурсах группы узлов в кластере управления:

  • для Worker-групп — в MachineDeployment;
  • для группы Control Plane — в KubeadmControlPlane.

Так параметры попадают в Machine, а затем, если выполняются правила Cluster API, синхронизируются на соответствующие Kubernetes-узлы - Nodes.

Для части лейблов дополнительная настройка не нужна. Например, роли групп узлов в платформе задаются лейблом node-role.kubernetes.io/<role>, а префикс node-role.kubernetes.io/ входит в список лейблов, которые Cluster API всегда синхронизирует с Machine на Node (официальная документация Cluster API). При настройке кастомных лейблов, аннотаций и taints через CAPI-ресурсы важно учитывать отдельные правила синхронизации: не все значения автоматически попадают с Machine на Node, а для taints требуется дополнительный параметр.

Ручное изменение лейблов или taints на Node может быть перезаписано контроллерами или потеряно при пересоздании узла.


Лейблы

Cluster API переносит на Node не все лейблы из Machine, а только лейблы, разрешённые правилами синхронизации.

Всегда синхронизируются лейблы, которые соответствуют хотя бы одному условию:

  • имеют префикс node-role.kubernetes.io/;
  • относятся к домену node-restriction.kubernetes.io;
  • относятся к домену node.cluster.x-k8s.io.

Например, лейбл node-role.kubernetes.io/infra будет перенесен с Machine на Node без дополнительной настройки. По этой же причине роли групп узлов, заданные в формате node-role.kubernetes.io/<role>, попадают под стандартное правило Cluster API.

Кастомные лейблы по умолчанию не синхронизируются. Чтобы разрешить их перенос, в аргументах manager контроллера Cluster API нужно добавить --additional-sync-machine-labels.

Аргумент синхронизации

  • --additional-sync-machine-labels — список регулярных выражений для лейблов, которые нужно дополнительно синхронизировать с Machine на Node.

Лейбл синхронизируется, если совпадает хотя бы с одним регулярным выражением из списка. Значения в списке разделяются запятыми:

args:
  - --additional-sync-machine-labels=^env$,^role$,^topology\.kubernetes\.io/zone$

Чтобы разрешить синхронизацию всех лейблов, используйте регулярное выражение .*.

Использовать аргумент синхронизации стоит только после оценки рисков, поскольку на узлы могут попасть служебные или временные лейблы, которые не должны влиять на планирование нагрузок.

Для настройки аргумента используйте ShturvalServicePatch для shturval-capi.

Общий сценарий

  1. Подготовьте манифест ShturvalServicePatch для shturval-capi.
  2. В кластере управления загрузите манифест через импорт манифестов.
  3. Дождитесь применения ShturvalServicePatch. На странице сервиса shturval-capi статус сервиса сменится на Patched, а загруженный ShturvalServicePatch появится на вкладке Примененные ShturvalServicePatch.

Пример манифеста:

apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServicePatch
metadata:
  name: shturval-capi-sync-labels
spec:
  shturvalServiceConfigName: shturval-capi
  patchOrder: 11000
  customvalues:
    capiControllerManager:
      extraArgs:
        - --additional-sync-machine-labels=.*

Где задавать лейблы

Для узлов Worker-групп добавьте лейблы в spec.template.metadata.labels ресурса MachineDeployment:

apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
  name: <machine-deployment-name>
  namespace: <namespace>
spec:
  template:
    metadata:
      labels:
        env: prod
        role: app
        topology.kubernetes.io/zone: az1

Для узлов Control Plane группы добавьте лейблы в spec.machineTemplate.metadata.labels ресурса KubeadmControlPlane:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
  name: <kubeadm-control-plane-name>
  namespace: <namespace>
spec:
  machineTemplate:
    metadata:
      labels:
        env: prod
        role: control-plane
        topology.kubernetes.io/zone: az1

Цепочка применения:

MachineDeployment.spec.template.metadata.labels
  или KubeadmControlPlane.spec.machineTemplate.metadata.labels
    -> Machine.metadata.labels
      -> Node.metadata.labels

На последнем шаге с Machine на Node попадут только лейблы, разрешённые правилами Cluster API или аргументом --additional-sync-machine-labels.

Примеры команд проверки лейблов

Проверьте лейблы на Machine в кластере управления:

kubectl get machines -n <namespace> --show-labels

Проверьте лейблы на узлах кластера:

kubectl get nodes --show-labels

Аннотации

Для аннотаций по умолчанию Cluster API синхронизирует с Machine на Node только аннотации из домена node.cluster.x-k8s.io. Остальные аннотации нужно разрешить аргументом --additional-sync-machine-annotations.

Аргумент синхронизации

  • --additional-sync-machine-annotations — список регулярных выражений для аннотаций, которые нужно дополнительно синхронизировать с Machine на Node.

Аннотация синхронизируется, если совпадает хотя бы с одним регулярным выражением из списка. Значения в списке разделяются запятыми:

args:
  - --additional-sync-machine-annotations=^example\.com/owner$,^ops\.shturval\.tech/maintenance-window$

Чтобы разрешить синхронизацию всех аннотаций, используйте регулярное выражение .*.

Не расширяйте список аннотаций без необходимости: аннотации узла могут читать другие контроллеры и интеграции.

Для настройки аргумента используйте ShturvalServicePatch для сервиса shturval-capi.

Общий сценарий

  1. Подготовьте манифест ShturvalServicePatch для shturval-capi.
  2. В кластере управления загрузите манифест через импорт манифестов.
  3. Дождитесь применения ShturvalServicePatch. На странице сервиса shturval-capi статус сервиса сменится на Patched, а загруженный ShturvalServicePatch появится на вкладке Примененные ShturvalServicePatch.

Пример манифеста:

apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServicePatch
metadata:
  name: shturval-capi-sync-annotations
spec:
  shturvalServiceConfigName: shturval-capi
  patchOrder: 11000
  customvalues:
    capiControllerManager:
      extraArgs:
        - --additional-sync-machine-annotations=^example\.com/owner$

Где задавать аннотации

Для Worker-группы добавьте аннотации в spec.template.metadata.annotations ресурса MachineDeployment:

apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
  name: <machine-deployment-name>
  namespace: <namespace>
spec:
  template:
    metadata:
      annotations:
        example.com/owner: platform-team

Для Control Plane добавьте аннотации в spec.machineTemplate.metadata.annotations ресурса KubeadmControlPlane:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
  name: <kubeadm-control-plane-name>
  namespace: <namespace>
spec:
  machineTemplate:
    metadata:
      annotations:
        example.com/owner: platform-team

Цепочка применения:

MachineDeployment.spec.template.metadata.annotations
  или KubeadmControlPlane.spec.machineTemplate.metadata.annotations
    -> Machine.metadata.annotations
      -> Node.metadata.annotations

На последнем шаге с Machine на Node попадут только аннотации из домена node.cluster.x-k8s.io или аннотации, разрешённые аргументом --additional-sync-machine-annotations.

Примеры команд проверки аннотаций

Проверьте аннотации на Machine:

kubectl get machines -n <namespace> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.annotations}{"\n"}{end}'

Проверьте аннотации на узлах:

kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.annotations}{"\n"}{end}'

Taints

Taints в Cluster API задаются в спецификации Machine. Контроллер переносит taints с Machine на связанный Node и применяет их согласно полю propagation.

Поддерживаются два режима:

  • Always — taint постоянно поддерживается на Node. Если удалить такой taint с узла вручную, Cluster API добавит его снова при реконсиляции. Если удалить taint из Machine, контроллер удалит его с Node.
  • OnInitialization — taint добавляется на Node один раз при инициализации. Если позже удалить его с Node, Cluster API не добавит его повторно.

Taints, заданные в MachineDeployment или KubeadmControlPlane, передаются в управляемые Machine без rollout узлов. После этого они синхронизируются на Node по правилам propagation.

Как включить синхронизацию taints

Для синхронизации taints требуется включение feature gate MachineTaintPropagation контроллера Cluster API.

Чтобы включить feature gate, используйте ShturvalServicePatch для сервиса shturval-capi.

Общий сценарий

  1. Подготовьте манифест ShturvalServicePatch для shturval-capi.
  2. В кластере управления загрузите манифест через импорт манифестов.
  3. Дождитесь применения ShturvalServicePatch. На странице сервиса shturval-capi статус сервиса сменится на Patched, а загруженный ShturvalServicePatch появится на вкладке Примененные ShturvalServicePatch.

Пример манифеста:

apiVersion: ops.shturval.tech/v1beta2
kind: ShturvalServicePatch
metadata:
  name: shturval-capi-taint-propagation
spec:
  shturvalServiceConfigName: shturval-capi
  patchOrder: 11000
  customvalues:
    capiControllerManager:
      featureGates:
        MachineTaintPropagation: true

Где задавать taints

Для Worker-группы добавьте taints в spec.template.spec.taints ресурса MachineDeployment:

apiVersion: cluster.x-k8s.io/v1beta1
kind: MachineDeployment
metadata:
  name: <machine-deployment-name>
  namespace: <namespace>
spec:
  clusterName: <cluster-name>
  template:
    spec:
      taints:
        - key: dedicated
          value: db
          effect: NoSchedule
          propagation: Always

Для Control Plane в CAPI v1beta1 taints могут задаваться в spec.machineTemplate.taints ресурса KubeadmControlPlane, если это поле поддерживается установленной CRD:

apiVersion: controlplane.cluster.x-k8s.io/v1beta1
kind: KubeadmControlPlane
metadata:
  name: <kubeadm-control-plane-name>
  namespace: <namespace>
spec:
  clusterName: <cluster-name>
  version: <kubernetes-version>
  machineTemplate:
    metadata: {}
    taints:
      - key: custom-taint-key
        effect: NoSchedule
        propagation: Always
  kubeadmConfigSpec: {}

Также поле taints может располагаться в spec.machineTemplate.spec.taints. Перед применением проверьте CRD в кластере управления:

kubectl explain kubeadmcontrolplane.spec.machineTemplate --api-version controlplane.cluster.x-k8s.io/v1beta1

Цепочка применения управляемых CAPI taints:

MachineDeployment.spec.template.spec.taints
  или KubeadmControlPlane.spec.machineTemplate.taints
    -> Machine.spec.taints
      -> Node.spec.taints

Ограничения и зарезервированные ключи

Для CAPI taints действуют ограничения API:

  • в списке может быть не более 64 taints;
  • key обязателен, value опционален;
  • effect обязателен и может быть NoSchedule, PreferNoSchedule или NoExecute;
  • propagation указывайте явно: Always или OnInitialization.

Рекомендуется не использовать системные ключи и префиксы, которыми управляют Kubernetes:

  • node.cluster.x-k8s.io/uninitialized;
  • node.cluster.x-k8s.io/outdated-revision;
  • префикс node.kubernetes.io/, кроме node.kubernetes.io/out-of-service;
  • префикс node.cloudprovider.kubernetes.io/;
  • node-role.kubernetes.io/control-plane на Worker-узлах;
  • node-role.kubernetes.io/master.

Эти ограничения не отменяют обычные правила Kubernetes: чтобы под мог быть запланирован на узел с taints, в спецификации пода должны быть соответствующие tolerations. Подробнее на странице Taints, Tolerations и Affinity.

Примеры команд проверки taints

Проверьте taints на Machine:

kubectl get machines -n <namespace> -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.taints}{"\n"}{end}'

Проверьте taints на узлах:

kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.taints}{"\n"}{end}'

См. также