Настройка отдельного диска под образы контейнеров

Вы можете выделить отдельный диск под хранение образов контейнеров на каждом worker-узле. Это обезопасит следующие ресурсы системы:

  • Неиспользуемые образы от удаления сборщиком мусора (garbage collector), если в файловой системе worker-узла останется меньше 15% свободного места.

  • Запущенные поды от вытеснения, если в файловой системе worker-узла останется меньше 1% свободного места.

Представленные пороги системы Kubernetes являются значениями по умолчанию.

Настройка отдельного диска для образов контейнеров состоит из следующих этапов:

Редактирование конфигураций контроллеров DaemonSet делается один раз в самом начале. Настройку отдельного диска для образов необходимо провести для каждого worker-узла.

Редактирование конфигураций контроллеров DaemonSet

Редактирование конфигураций контроллеров DaemonSet производится один раз в самом начале.

Чтобы изменить контроллеры DaemonSet:

  1. Подключитесь к кластеру.

  2. Измените контроллеры DaemonSet, выполнив команды:

    cat << EOF > daemonset-affinity-patch.yml
    spec:
      template:
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: marked-for-drain
                    operator: NotIn
                    values:
                    - "true"
    EOF
    kubectl patch daemonsets.apps -n <namespace> vector-daemon --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n ingress-nginx ingress-nginx-controller --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n metallb-system metallb-speaker --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n kube-prometheus-stack promtail --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n kube-prometheus-stack loki-canary --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n kube-prometheus-stack kube-prometheus-stack-prometheus-node-exporter --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n kube-system calico-node --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n kube-system kube-proxy --type=merge -p "$(cat daemonset-affinity-patch.yml)"
    kubectl patch daemonsets.apps -n kube-system nodelocaldns --type=merge -p "$(cat daemonset-affinity-patch.yml)"

    Здесь:

    • <namespace> — название пространства имен, в котором установлена система.

    Изменение контроллеров DaemonSet позволяет приостановить создание и распределение подов этих контроллеров на worker-узле с меткой marked-for-drain.

Настройка отдельного диска на worker-узлах

Настройка отдельного диска на worker-узлах состоит из следующих этапов:

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

Подготовка worker-узла к настройке отдельного диска

На данном этапе происходит отключение необходимых служб и вытеснение подов на выбранном worker-узле. Для этого:

  1. Подключитесь к кластеру.

  2. Проверьте все поды выбранного worker-узла, выполнив команду:

    kubectl get pods --field-selector spec.nodeName=<node_name> -A -o wide

    Здесь:

    • <node_name> — название выбранного worker-узла.

    Проверка подов необходима, чтобы обозначить, какие из них будут недоступны при их перераспределении на другие worker-узлы. Из-за этого часть функционала системы может быть недоступна на время переноса образов контейнеров на отдельный диск.
  3. Переведите выбранный worker-узел в drain-режим, выполнив команду:

    kubectl drain <node_name> --delete-emptydir-data

    Здесь:

    • <node_name> — название выбранного worker-узла.

    Операция drain позволяет перераспределить все поды с выбранного worker-узла.

    В процессе выполнения операции worker-узел помечается как Unschedulable (непланируемый) — это предотвращает появление на worker-узле новых подов. Затем начинается процесс вытеснения (evict) подов с worker-узла. Во время этого процесса система завершает работу запущенных контейнеров.

  4. Установите метку marked-for-drain для выбранного worker-узла, выполнив команду:

    kubectl label nodes <node_name> marked-for-drain=true

    Здесь:

    • <node_name> — название выбранного worker-узла.

  5. Подключитесь к выбранному worker-узлу.

  6. После того как Kubernetes вытеснил все поды с worker-узла, удалите под nginx-proxy, так как он используется для взаимодействия с kube-apiserver. Для этого:

    1. Перенесите манифест пода в домашнюю директорию на выбранном worker-узле, выполнив команду:

      sudo mv /etc/kubernetes/manifests/nginx-proxy.yml /root/
      Перенос файла манифеста необходим, чтобы закрыть kubelet доступ к файлу. Kubelet отслеживает статус пода nginx-proxy. Если удалить под nginx-proxy, то kubelet заново запустит его из файла манифеста.
    2. Удалите под nginx-proxy, выполнив команду:

      kubectl delete pod -n kube-system nginx-proxy-<node_name> --force

      Здесь:

      • <node_name> — название выбранного worker-узла.

  7. Остановите kubelet на worker-узле, выполнив команду:

    sudo systemctl stop kubelet
  8. Остановите containerd на worker-узле, выполнив команду:

    sudo systemctl stop containerd

Настройка отдельного диска и перенос образов контейнеров

В данном разделе приведены шаги по переносу содержимого containerd на отдельный том на примере виртуального диска, эмулирующего физическое устройство.

Чтобы настроить отдельный диск с образами контейнеров:

  1. Подключитесь к кластеру.

  2. Проверьте размер текущего диска, выполнив команду:

    sudo fdisk -l /dev/sda

    Если измененный размер не отображается, запустите принудительное сканирование этого диска, выполнив команду:

    sudo sh -c "echo 1 > /sys/block/sda/device/rescan"

    После сканирования снова проверьте размер текущего диска, выполнив команду:

    sudo fdisk -l /dev/sda
  3. Инициируйте создание нового раздела для образов контейнеров, выполнив команду:

    sudo fdisk /dev/sda

    После выполнения команды откроется утилита fdisk для управления разделами диска. В утилите создайте новый диск для образов контейнера. Для этого:

    1. Создайте новый раздел диска, введя значение n и нажав клавишу ENTER. Отобразятся поля для первичной настройки и создания раздела:

      1. Введите порядковый номер (partition number) нового раздела диска и нажмите клавишу ENTER.

      2. Введите первый сектор (first sector) доступного пространства раздела и нажмите клавишу ENTER.

      3. Введите последний сектор (last sector) доступного пространства раздела и нажмите клавишу ENTER.

    2. Проверьте наличие нового раздела, введя значение p и нажав клавишу ENTER. Отобразится список доступных разделов диска.

    3. Измените тип нового раздела на LVM, введя значение t и нажав клавишу ENTER. Отобразятся поля для смены типа раздела:

      1. Введите порядковый номер (partition number) созданного раздела и нажмите клавишу ENTER.

      2. Введите значение 30 и нажмите клавишу ENTER. Тип созданного раздела изменится на LVM.

    4. Проверьте, что тип корректно изменился, введя значение p и нажав клавишу ENTER. Отобразится список разделов. В столбце TYPE должно отображаться соответствующее значение.

    5. Сохраните изменения и закройте утилиту fdisk, введя значение w и нажав клавишу ENTER.

      Чтобы вывести список доступных команд утилиты fdisk, введите значение m в командную строку и нажмите клавишу ENTER.
  4. Создайте новую группу томов, выполнив команду:

    sudo vgcreate vg_containerd /dev/<disk_name>

    Здесь:

    • <disk_name> — название раздела, созданного на предыдущем шаге.

    Чтобы отобразить все созданные физические тома LVM, выполните команду:

    sudo pvdisplay

    Чтобы отобразить все группы томов, выполните команду:

    sudo vgdisplay
  5. Создайте логический том, выполнив команду:

    sudo lvcreate -l 100%FREE -n lv_containerd vg_containerd

    Чтобы отобразить все логические тома, выполните команду:

    sudo lvdisplay
  6. Отформатируйте LVM-раздел в необходимую файловую систему:

    sudo mkfs.<fs_tag> /dev/vg_containerd/lv_containerd

    Здесь:

    • <fs_tag> — тег файловой системы.

  7. Создайте временную директорию для образов контейнеров, выполнив команду:

    sudo mkdir -p /mnt/containerd
  8. Смонтируйте логический том lv_containerd во временную директорию, выполнив команду:

    sudo mount /dev/vg_containerd/lv_containerd /mnt/containerd
  9. Проверьте размер директории с образами контейнеров, выполнив команду:

    du -sh /var/lib/containerd
  10. Перенесите во временную директорию содержимое директории /var/lib/containerd, выполнив команду:

    sudo rsync -a /var/lib/containerd/ /mnt/containerd/
    Процесс переноса может занять определенное время в зависимости от размера каталога и производительности диска.
  11. Размонтируйте временный том /mnt/containerd и смонтируйте его в /var/lib/containerd, выполнив команду:

    sudo umount /mnt/containerd
    echo "/dev/mapper/vg_containerd-lv_containerd /var/lib/containerd    <fs-tag>     nodev,defaults        0       0" >> /etc/fstab
    mount -a

    Здесь:

    • <fs_tag> — тег файловой системы.

Запуск служб и возвращение worker-узла в рабочее состояние

Чтобы вернуть worker-узел в рабочее состояние:

  1. Подключитесь к кластеру.

  2. Подключитесь к выбранному worker-узлу.

  3. Запустите службу containerd, выполнив команду:

    sudo systemctl start containerd
  4. Запустите службу kubelet, выполнив команду:

    sudo systemctl start kubelet
  5. Верните манифест nginx-proxy в изначальную директорию, выполнив команду:

    sudo mv /root/nginx-proxy.yml /etc/kubernetes/manifests/

    Kubelet автоматически создаст под nginx-proxy из файла манифеста. Дождитесь успешного запуска пода nginx-proxy.

  6. Снимите метку marked-for-drain с выбранного worker-узла, выполнив команду:

    kubectl label nodes <node_name> marked-for-drain-

    Здесь:

    • <node_name> — название выбранного worker-узла.

  7. Сделайте worker-узел доступным для назначения подов, выполнив команду:

    kubectl uncordon <node_name>

    Здесь:

    • <node_name> — название выбранного worker-узла.

  8. Проверьте, что все поды worker-узла корректно запустились, выполнив команду:

    kubectl get pods --field-selector spec.nodeName=<node_name> -A -o wide

    Здесь:

    • <node_name> — название выбранного worker-узла.

    Отобразится список всех подов worker-узла. Убедитесь, что поды контроллеров DaemonSet корректно запустились после снятия метки marked-for-drain с worker-узла.

    После возвращения worker-узла в рабочее состояние под ingress-nginx-controller может не запуститься. Подробности по решению данной проблемы приведены в разделе Ошибки при запуске пода ingress-nginx-controller.

Была ли полезна эта страница?

Обратная связь