Как развернуть отказоустойчивый Control Plane для Kubernetes-кластера?

«Как развернуть отказоустойчивый Control Plane для Kubernetes-кластера?» — вопрос из категории Kubernetes, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Развертывание высокодоступного (HA) Control Plane — критическая задача для продакшн-кластеров. Я предпочитаю использовать kubeadm для инициализации и внешний балансировщик нагрузки.

Архитектура HA Control Plane (3 ноды):

                       +----------------+
                       |  Load Balancer |
                       |  (haproxy/ELB) |
                       +-------+--------+
                               |
        +----------------------+----------------------+
        |                      |                      |
+-------+--------+    +--------+-------+    +--------+-------+
| Control Plane 1|    | Control Plane 2|    | Control Plane 3|
| (cp-01)        |    | (cp-02)        |    | (cp-03)        |
+----------------+    +----------------+    +----------------+

Пошаговый процесс:

  1. Подготовка нод и балансировщика:

    • На трех серверах с Ubuntu 22.04 устанавливаю Docker, kubeadm, kubelet, kubectl.
    • Разворачиваю HAProxy на отдельной ноде или использую облачный Load Balancer (AWS NLB, GCP Load Balancer). Конфиг HAProxy для балансировки kube-apiserver (порт 6443):
    frontend kubernetes-apiserver
        bind *:6443
        mode tcp
        option tcplog
        default_backend kube-apiservers
    
    backend kube-apiservers
        mode tcp
        option tcp-check
        balance roundrobin
        server cp-01 10.0.1.10:6443 check
        server cp-02 10.0.1.11:6443 check
        server cp-03 10.0.1.12:6443 check
  2. Инициализация первого Control Plane нода:

    sudo kubeadm init 
      --control-plane-endpoint "LOAD_BALANCER_DNS:6443" 
      --upload-certs 
      --pod-network-cidr=10.244.0.0/16

    Команда выдает kubeadm join токен с сертификатами для присоединения остальных нод Control Plane.

  3. Присоединение второй и третьей ноды Control Plane:

    # На cp-02 и cp-03 выполняю команду, выданную kubeadm init
    sudo kubeadm join LOAD_BALANCER_DNS:6443 
      --token <token> 
      --discovery-token-ca-cert-hash sha256:<hash> 
      --control-plane 
      --certificate-key <certificate-key>
  4. Развертывание сетевого плагина (CNI):

    # Устанавливаю Calico для сетевой политики и overlay-сети
    kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
  5. Проверка отказоустойчивости:

    • Проверяю статус нод: kubectl get nodes -o wide.
    • Проверяю компоненты Control Plane на каждой ноде: kubectl get pods -n kube-system -o wide | grep -E "apiserver|scheduler|controller".
    • Имитирую отказ одной ноды (например, systemctl stop kubelet на cp-02) и убеждаюсь, что kubectl команды продолжают работать через балансировщик.

Ключевые моменты для продакшена:

  • etcd-кластер: Kubeadm автоматически настраивает etcd как статический Pod на каждой Control Plane ноде, формируя отказоустойчивый кластер.
  • External etcd: Для очень крупных кластеров (>5 Control Plane нод) разворачивал etcd на выделенных нодах.
  • Резервное копирование etcd: Настраивал cron-задачу для регулярного снапшота etcd с помощью etcdctl snapshot save и хранения в S3.
  • Управление через IaC: Весь процесс описывал в Terraform-модулях для автоматического развертывания кластера в облаке.