Ниже представлены несколько примеров описания NodeGroup, а также установки плагина cert-manager для kubectl и задания параметра sysctl.

Примеры описания NodeGroup

Облачные узлы

1apiVersion: deckhouse.io/v1
2kind: NodeGroup
3metadata:
4  name: test
5spec:
6  nodeType: CloudEphemeral
7  cloudInstances:
8    zones:
9      - eu-west-1a
10      - eu-west-1b
11    minPerZone: 1
12    maxPerZone: 2
13    classReference:
14      kind: AWSInstanceClass
15      name: test
16  nodeTemplate:
17    labels:
18      tier: test

Статические узлы

Для виртуальных машин на гипервизорах или физических серверов используйте статические узлы, указав nodeType: Static в NodeGroup.

Пример:

1apiVersion: deckhouse.io/v1
2kind: NodeGroup
3metadata:
4  name: worker
5spec:
6  nodeType: Static

Узлы в такую группу добавляются вручную с помощью подготовленных скриптов.

Также можно использовать способ добавления статических узлов с помощью Cluster API Provider Static.

Системные узлы

1apiVersion: deckhouse.io/v1
2kind: NodeGroup
3metadata:
4  name: system
5spec:
6  nodeTemplate:
7    labels:
8      node-role.deckhouse.io/system: ""
9    taints:
10      - effect: NoExecute
11        key: dedicated.deckhouse.io
12        value: system
13  nodeType: Static

Добавление статического узла в кластер

Добавление статического узла можно выполнить вручную или с помощью Cluster API Provider Static.

Вручную

Чтобы добавить новый статический узел (выделенная ВМ, bare-metal-сервер и т. п.) в кластер вручную, выполните следующие шаги:

  1. Для CloudStatic-узлов в облачных провайдерах, перечисленных ниже, выполните описанные в документации шаги:
  2. Используйте существующий или создайте новый ресурс NodeGroup (пример NodeGroup с именем worker). Параметр nodeType в ресурсе NodeGroup для статических узлов должен быть Static или CloudStatic.
  3. Получите код скрипта в кодировке Base64 для добавления и настройки узла.

    Пример получения кода скрипта в кодировке Base64 для добавления узла в NodeGroup worker:

    1NODE_GROUP=worker
    2kubectl -n d8-cloud-instance-manager get secret manual-bootstrap-for-${NODE_GROUP} -o json | jq '.data."bootstrap.sh"' -r
    
  4. Выполните предварительную настройку нового узла в соответствии с особенностями вашего окружения. Например:
    • добавьте необходимые точки монтирования в файл /etc/fstab (NFS, Ceph и т. д.);
    • установите необходимые пакеты;
    • настройте сетевую связность между новым узлом и остальными узлами кластера.
  5. Зайдите на новый узел по SSH и выполните следующую команду, вставив полученную в п. 3 Base64-строку:

    1echo <Base64-КОД-СКРИПТА> | base64 -d | bash
    

С помощью Cluster API Provider Static

Простой пример добавления статического узла в кластер с помощью Cluster API Provider Static (CAPS):

  1. Подготовьте необходимые ресурсы.

    • Выделите сервер (или виртуальную машину), настройте сетевую связность и т. п., при необходимости установите специфические пакеты ОС и добавьте точки монтирования которые потребуются на узле.

    • Создайте пользователя (в примере — caps) с возможностью выполнять sudo, выполнив на сервере следующую команду:

      1useradd -m -s /bin/bash caps 
      2usermod -aG sudo caps
      
    • Разрешите пользователю выполнять команды через sudo без пароля. Для этого на сервере внесите следующую строку в конфигурацию sudo (отредактировав файл /etc/sudoers, выполнив команду sudo visudo или другим способом):

      1caps ALL=(ALL) NOPASSWD: ALL
      
    • Сгенерируйте на сервере пару SSH-ключей с пустой парольной фразой:

      1ssh-keygen -t rsa -f caps-id -C "" -N ""
      

      Публичный и приватный ключи пользователя caps будут сохранены в файлах caps-id.pub и caps-id в текущей директории на сервере.

    • Добавьте полученный публичный ключ в файл /home/caps/.ssh/authorized_keys пользователя caps, выполнив в директории с ключами на сервере следующие команды:

      1mkdir -p /home/caps/.ssh 
      2cat caps-id.pub >> /home/caps/.ssh/authorized_keys 
      3chmod 700 /home/caps/.ssh 
      4chmod 600 /home/caps/.ssh/authorized_keys
      5chown -R caps:caps /home/caps/
      

    В операционных системах семейства Astra Linux, при использовании модуля мандатного контроля целостности Parsec, сконфигурируйте максимальный уровень целостности для пользователя caps:

    1  pdpl-user -i 63 caps
    
  2. Создайте в кластере ресурс SSHCredentials.

    В директории с ключами пользователя на сервере выполните следующую команду для получения закрытого ключа в формате Base64:

    1base64 -w0 caps-id
    

    На любом компьютере с kubectl, настроенным на управление кластером, создайте переменную окружения со значением закрытого ключа созданного пользователя в Base64, полученным на предыдущем шаге:

    1 CAPS_PRIVATE_KEY_BASE64=<ЗАКРЫТЫЙ_КЛЮЧ_В_BASE64>
    

    Выполните следующую команду, для создания в кластере ресурса SSHCredentials (здесь и далее также используйте kubectl, настроенный на управление кластером):

    1kubectl create -f - <<EOF
    2apiVersion: deckhouse.io/v1alpha1
    3kind: SSHCredentials
    4metadata:
    5  name: credentials
    6spec:
    7  user: caps
    8  privateSSHKey: "${CAPS_PRIVATE_KEY_BASE64}"
    9EOF
    
  3. Создайте в кластере ресурс StaticInstance, указав IP-адрес сервера статического узла:

    1kubectl create -f - <<EOF
    2apiVersion: deckhouse.io/v1alpha1
    3kind: StaticInstance
    4metadata:
    5  name: static-worker-1
    6  labels:
    7    role: worker
    8spec:
    9  # Укажите IP-адрес сервера статического узла.
    10  address: "<SERVER-IP>"
    11  credentialsRef:
    12    kind: SSHCredentials
    13    name: credentials
    14EOF
    

    Поле labelSelector в ресурсе NodeGroup является неизменным. Чтобы обновить labelSelector, нужно создать новую NodeGroup и перенести в неё статические узлы, изменив их лейблы (labels).

  4. Создайте в кластере ресурс NodeGroup:

    1kubectl create -f - <<EOF
    2apiVersion: deckhouse.io/v1
    3kind: NodeGroup
    4metadata:
    5  name: worker
    6spec:
    7  nodeType: Static
    8  staticInstances:
    9    count: 1
    10    labelSelector:
    11      matchLabels:
    12        role: worker
    13EOF
    

С помощью Cluster API Provider Static для нескольких групп узлов

Пример использования фильтров в label selector StaticInstance, для группировки статических узлов и использования их в разных NodeGroup. В примере используются две группы узлов (front и worker), предназначенные для разных задач, которые должны содержать разные по характеристикам узлы — два сервера для группы front и один для группы worker.

  1. Подготовьте необходимые ресурсы (3 сервера или виртуальные машины) и создайте ресурс SSHCredentials, аналогично п.1 и п.2 примера.

  2. Создайте в кластере два ресурса NodeGroup (здесь и далее используйте kubectl, настроенный на управление кластером):

    Поле labelSelector в ресурсе NodeGroup является неизменным. Чтобы обновить labelSelector, нужно создать новую NodeGroup и перенести в неё статические узлы, изменив их лейблы (labels).

    1kubectl create -f - <<EOF
    2apiVersion: deckhouse.io/v1
    3kind: NodeGroup
    4metadata:
    5  name: front
    6spec:
    7  nodeType: Static
    8  staticInstances:
    9    count: 2
    10    labelSelector:
    11      matchLabels:
    12        role: front
    13---
    14apiVersion: deckhouse.io/v1
    15kind: NodeGroup
    16metadata:
    17  name: worker
    18spec:
    19  nodeType: Static
    20  staticInstances:
    21    count: 1
    22    labelSelector:
    23      matchLabels:
    24        role: worker
    25EOF
    
  3. Создайте в кластере ресурсы StaticInstance, указав актуальные IP-адреса серверов:

    1kubectl create -f - <<EOF
    2apiVersion: deckhouse.io/v1alpha1
    3kind: StaticInstance
    4metadata:
    5  name: static-front-1
    6  labels:
    7    role: front
    8spec:
    9  address: "<SERVER-FRONT-IP1>"
    10  credentialsRef:
    11    kind: SSHCredentials
    12    name: credentials
    13---
    14apiVersion: deckhouse.io/v1alpha1
    15kind: StaticInstance
    16metadata:
    17  name: static-front-2
    18  labels:
    19    role: front
    20spec:
    21  address: "<SERVER-FRONT-IP2>"
    22  credentialsRef:
    23    kind: SSHCredentials
    24    name: credentials
    25---
    26apiVersion: deckhouse.io/v1alpha1
    27kind: StaticInstance
    28metadata:
    29  name: static-worker-1
    30  labels:
    31    role: worker
    32spec:
    33  address: "<SERVER-WORKER-IP>"
    34  credentialsRef:
    35    kind: SSHCredentials
    36    name: credentials
    37EOF
    

Cluster API Provider Static: перемещение узлов между NodeGroup

В данном разделе описывается процесс перемещения статических узлов между различными NodeGroup с использованием Cluster API Provider Static (CAPS). Процесс включает изменение конфигурации NodeGroup и обновление лейблов у соответствующих StaticInstance.

Исходная конфигурация

Предположим, что в кластере уже существует NodeGroup с именем worker, настроенный для управления одним статическим узлом с лейблом role: worker.

NodeGroup worker:

1apiVersion: deckhouse.io/v1
2kind: NodeGroup
3metadata:
4  name: worker
5spec:
6  nodeType: Static
7  staticInstances:
8    count: 1
9    labelSelector:
10      matchLabels:
11        role: worker

StaticInstance static-0:

1apiVersion: deckhouse.io/v1alpha1
2kind: StaticInstance
3metadata:
4  name: static-worker-1
5  labels:
6    role: worker
7spec:
8  address: "192.168.1.100"
9  credentialsRef:
10    kind: SSHCredentials
11    name: credentials

Шаги по перемещению узла между NodeGroup

В процессе переноса узлов между NodeGroup будет выполнена очистка и повторный бутстрап узла, объект Node будет пересоздан.

1. Создание новой NodeGroup для целевой группы узлов

Создайте новый ресурс NodeGroup, например, с именем front, который будет управлять статическим узлом с лейблом role: front.

1kubectl create -f - <<EOF
2apiVersion: deckhouse.io/v1
3kind: NodeGroup
4metadata:
5  name: front
6spec:
7  nodeType: Static
8  staticInstances:
9    count: 1
10    labelSelector:
11      matchLabels:
12        role: front
13EOF
2. Обновление лейбла у StaticInstance

Измените лейбл role у существующего StaticInstance с worker на front. Это позволит новой NodeGroup front начать управлять этим узлом.

1kubectl label staticinstance static-worker-1 role=front --overwrite
3. Уменьшение количества статических узлов в исходной NodeGroup

Обновите ресурс NodeGroup worker, уменьшив значение параметра count с 1 до 0.

1kubectl patch nodegroup worker -p '{"spec": {"staticInstances": {"count": 0}}}' --type=merge

Пример описания NodeUser

1apiVersion: deckhouse.io/v1
2kind: NodeUser
3metadata:
4  name: testuser
5spec:
6  uid: 1100
7  sshPublicKeys:
8  - "<SSH_PUBLIC_KEY>"
9  passwordHash: <PASSWORD_HASH>
10  isSudoer: true

Пример описания NodeGroupConfiguration

Установка плагина cert-manager для kubectl на master-узлах

1apiVersion: deckhouse.io/v1alpha1
2kind: NodeGroupConfiguration
3metadata:
4  name: add-cert-manager-plugin.sh
5spec:
6  weight: 100
7  bundles:
8  - "*"
9  nodeGroups:
10  - "master"
11  content: |
12    if [ -x /usr/local/bin/kubectl-cert_manager ]; then
13      exit 0
14    fi
15    curl -L https://github.com/cert-manager/cert-manager/releases/download/v1.7.1/kubectl-cert_manager-linux-amd64.tar.gz -o - | tar -zxvf - kubectl-cert_manager
16    mv kubectl-cert_manager /usr/local/bin

Задание параметра sysctl

1apiVersion: deckhouse.io/v1alpha1
2kind: NodeGroupConfiguration
3metadata:
4  name: sysctl-tune.sh
5spec:
6  weight: 100
7  bundles:
8  - "*"
9  nodeGroups:
10  - "*"
11  content: |
12    sysctl -w vm.max_map_count=262144

Добавление корневого сертификата в хост

Данный пример приведен для ОС Ubuntu.
Способ добавления сертификатов в хранилище может отличаться в зависимости от ОС.

При адаптации скрипта под другую ОС измените параметры bundles и content.

Для использования сертификата в containerd (в т.ч. pull контейнеров из приватного репозитория) после добавления сертификата требуется произвести рестарт сервиса.

1apiVersion: deckhouse.io/v1alpha1
2kind: NodeGroupConfiguration
3metadata:
4  name: add-custom-ca.sh
5spec:
6  weight: 31
7  nodeGroups:
8  - '*'  
9  bundles:
10  - 'ubuntu-lts'
11  content: |-
12    CERT_FILE_NAME=example_ca
13    CERTS_FOLDER="/usr/local/share/ca-certificates"
14    CERT_CONTENT=$(cat <<EOF
15    -----BEGIN CERTIFICATE-----
16    MIIDSjCCAjKgAwIBAgIRAJ4RR/WDuAym7M11JA8W7D0wDQYJKoZIhvcNAQELBQAw
17    JTEjMCEGA1UEAxMabmV4dXMuNTEuMjUwLjQxLjIuc3NsaXAuaW8wHhcNMjQwODAx
18    MTAzMjA4WhcNMjQxMDMwMTAzMjA4WjAlMSMwIQYDVQQDExpuZXh1cy41MS4yNTAu
19    NDEuMi5zc2xpcC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1p
20    WLPr2c4SZX/i4IS59Ly1USPjRE21G4pMYewUjkSXnYv7hUkHvbNL/P9dmGBm2Jsl
21    WFlRZbzCv7+5/J+9mPVL2TdTbWuAcTUyaG5GZ/1w64AmAWxqGMFx4eyD1zo9eSmN
22    G2jis8VofL9dWDfUYhRzJ90qKxgK6k7tfhL0pv7IHDbqf28fCEnkvxsA98lGkq3H
23    fUfvHV6Oi8pcyPZ/c8ayIf4+JOnf7oW/TgWqI7x6R1CkdzwepJ8oU7PGc0ySUWaP
24    G5bH3ofBavL0bNEsyScz4TFCJ9b4aO5GFAOmgjFMMUi9qXDH72sBSrgi08Dxmimg
25    Hfs198SZr3br5GTJoAkCAwEAAaN1MHMwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB
26    /wQCMAAwUwYDVR0RBEwwSoIPbmV4dXMuc3ZjLmxvY2FsghpuZXh1cy41MS4yNTAu
27    NDEuMi5zc2xpcC5pb4IbZG9ja2VyLjUxLjI1MC40MS4yLnNzbGlwLmlvMA0GCSqG
28    SIb3DQEBCwUAA4IBAQBvTjTTXWeWtfaUDrcp1YW1pKgZ7lTb27f3QCxukXpbC+wL
29    dcb4EP/vDf+UqCogKl6rCEA0i23Dtn85KAE9PQZFfI5hLulptdOgUhO3Udluoy36
30    D4WvUoCfgPgx12FrdanQBBja+oDsT1QeOpKwQJuwjpZcGfB2YZqhO0UcJpC8kxtU
31    by3uoxJoveHPRlbM2+ACPBPlHu/yH7st24sr1CodJHNt6P8ugIBAZxi3/Hq0wj4K
32    aaQzdGXeFckWaxIny7F1M3cIWEXWzhAFnoTgrwlklf7N7VWHPIvlIh1EYASsVYKn
33    iATq8C7qhUOGsknDh3QSpOJeJmpcBwln11/9BGRP
34    -----END CERTIFICATE-----
35    EOF
36    )
38    # bb-event           - Creating subscription for event function. More information: http://www.bashbooster.net/#event
39    ## ca-file-updated   - Event name
40    ## update-certs      - The function name that the event will call
42    bb-event-on "ca-file-updated" "update-certs"
44    update-certs() {          # Function with commands for adding a certificate to the store
45      update-ca-certificates
46    }
48    # bb-tmp-file - Creating temp file function. More information: http://www.bashbooster.net/#tmp
49    CERT_TMP_FILE="$( bb-tmp-file )"
50    echo -e "${CERT_CONTENT}" > "${CERT_TMP_FILE}"  
52    # bb-sync-file                                - File synchronization function. More information: http://www.bashbooster.net/#sync
53    ## "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt"    - Destination file
54    ##  ${CERT_TMP_FILE}                          - Source file
55    ##  ca-file-updated                           - Name of event that will be called if the file changes.
57    bb-sync-file \
58      "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt" \
59      ${CERT_TMP_FILE} \
60      ca-file-updated   

Добавление сертификата в ОС и containerd

Данный пример приведен для ОС Ubuntu.
Способ добавления сертификатов в хранилище может отличаться в зависимости от ОС.

При адаптации скрипта под другую ОС измените параметры bundles и content.

Пример NodeGroupConfiguration основан на функциях, заложенных в скрипте 032_configure_containerd.sh.

1apiVersion: deckhouse.io/v1alpha1
2kind: NodeGroupConfiguration
3metadata:
4  name: add-custom-ca-containerd..sh
5spec:
6  weight: 31
7  nodeGroups:
8  - '*'  
9  bundles:
10  - 'ubuntu-lts'
11  content: |-
12    REGISTRY_URL=private.registry.example
13    CERT_FILE_NAME=${REGISTRY_URL}
14    CERTS_FOLDER="/usr/local/share/ca-certificates"
15    CERT_CONTENT=$(cat <<EOF
16    -----BEGIN CERTIFICATE-----
17    MIIDSjCCAjKgAwIBAgIRAJ4RR/WDuAym7M11JA8W7D0wDQYJKoZIhvcNAQELBQAw
18    JTEjMCEGA1UEAxMabmV4dXMuNTEuMjUwLjQxLjIuc3NsaXAuaW8wHhcNMjQwODAx
19    MTAzMjA4WhcNMjQxMDMwMTAzMjA4WjAlMSMwIQYDVQQDExpuZXh1cy41MS4yNTAu
20    NDEuMi5zc2xpcC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL1p
21    WLPr2c4SZX/i4IS59Ly1USPjRE21G4pMYewUjkSXnYv7hUkHvbNL/P9dmGBm2Jsl
22    WFlRZbzCv7+5/J+9mPVL2TdTbWuAcTUyaG5GZ/1w64AmAWxqGMFx4eyD1zo9eSmN
23    G2jis8VofL9dWDfUYhRzJ90qKxgK6k7tfhL0pv7IHDbqf28fCEnkvxsA98lGkq3H
24    fUfvHV6Oi8pcyPZ/c8ayIf4+JOnf7oW/TgWqI7x6R1CkdzwepJ8oU7PGc0ySUWaP
25    G5bH3ofBavL0bNEsyScz4TFCJ9b4aO5GFAOmgjFMMUi9qXDH72sBSrgi08Dxmimg
26    Hfs198SZr3br5GTJoAkCAwEAAaN1MHMwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB
27    /wQCMAAwUwYDVR0RBEwwSoIPbmV4dXMuc3ZjLmxvY2FsghpuZXh1cy41MS4yNTAu
28    NDEuMi5zc2xpcC5pb4IbZG9ja2VyLjUxLjI1MC40MS4yLnNzbGlwLmlvMA0GCSqG
29    SIb3DQEBCwUAA4IBAQBvTjTTXWeWtfaUDrcp1YW1pKgZ7lTb27f3QCxukXpbC+wL
30    dcb4EP/vDf+UqCogKl6rCEA0i23Dtn85KAE9PQZFfI5hLulptdOgUhO3Udluoy36
31    D4WvUoCfgPgx12FrdanQBBja+oDsT1QeOpKwQJuwjpZcGfB2YZqhO0UcJpC8kxtU
32    by3uoxJoveHPRlbM2+ACPBPlHu/yH7st24sr1CodJHNt6P8ugIBAZxi3/Hq0wj4K
33    aaQzdGXeFckWaxIny7F1M3cIWEXWzhAFnoTgrwlklf7N7VWHPIvlIh1EYASsVYKn
34    iATq8C7qhUOGsknDh3QSpOJeJmpcBwln11/9BGRP
35    -----END CERTIFICATE-----
36    EOF
37    )
38    CONFIG_CONTENT=$(cat <<EOF
39    [plugins]
40      [plugins."io.containerd.grpc.v1.cri".registry.configs."${REGISTRY_URL}".tls]
41        ca_file = "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt"
42    EOF
43    )
45    mkdir -p /etc/containerd/conf.d
47    # bb-tmp-file - Create temp file function. More information: http://www.bashbooster.net/#tmp
49    CERT_TMP_FILE="$( bb-tmp-file )"
50    echo -e "${CERT_CONTENT}" > "${CERT_TMP_FILE}"  
52    CONFIG_TMP_FILE="$( bb-tmp-file )"
53    echo -e "${CONFIG_CONTENT}" > "${CONFIG_TMP_FILE}"  
55    # bb-event           - Creating subscription for event function. More information: http://www.bashbooster.net/#event
56    ## ca-file-updated   - Event name
57    ## update-certs      - The function name that the event will call
59    bb-event-on "ca-file-updated" "update-certs"
61    update-certs() {          # Function with commands for adding a certificate to the store
62      update-ca-certificates  # Restarting the containerd service is not required as this is done automatically in the script 032_configure_containerd.sh
63    }
65    # bb-sync-file                                - File synchronization function. More information: http://www.bashbooster.net/#sync
66    ## "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt"    - Destination file
67    ##  ${CERT_TMP_FILE}                          - Source file
68    ##  ca-file-updated                           - Name of event that will be called if the file changes.
70    bb-sync-file \
71      "${CERTS_FOLDER}/${CERT_FILE_NAME}.crt" \
72      ${CERT_TMP_FILE} \
73      ca-file-updated   
74      
75    bb-sync-file \
76      "/etc/containerd/conf.d/${REGISTRY_URL}.toml" \
77      ${CONFIG_TMP_FILE}