Skip to content

Latest commit

 

History

History

kubeadm

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

Настройка kubernetes кластера после чистой установки при помощи kubeadm

Создание ВМ

Наш кластер работает на 6 виртуальных машинах (3 control-plane и 3 node) и разворачивается с помощью OpenTofu.

Подготовка ВМ

Тестирование проводилось на Ubuntu 24.04

Подготавливаем ВМ при помощи плейбука

Плейбук настроит все что нужно для работы Kubernetes. Добавит необходимые модули ядра, установит kubelet, kubeadm, kubectl, cri-o... и перезапустит машинки если это необходимо. Также произойдет инициализация кластера в HA режиме без kube-proxy.

Запускаем плейбук

ansible-playbook kubeadm.yml

Результат работы плейбука

PLAY RECAP *******************************************************************************************************
kubeadm-cp-01              : ok=28   changed=23   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
kubeadm-cp-02              : ok=22   changed=17   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
kubeadm-cp-03              : ok=22   changed=17   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
kubeadm-node-01            : ok=13   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
kubeadm-node-02            : ok=13   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
kubeadm-node-03            : ok=13   changed=11   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

четверг 02 мая 2024  19:33:56 +0500 (0:00:02.841)       0:04:44.638 ***********
===============================================================================
Добавляю control-plane узлы в кластер ------------------------------------------------ 67.74s
Инициализирую высокодоступный кластер ------------------------------------------------ 50.23s
Устанавливаю пакеты kubelet, kubeadm, kubectl и cri-o -------------------------------- 44.44s
Добавляю репозитории Kubernetes и cri-o ---------------------------------------------- 14.60s
Устанавливаю нужные пакеты ----------------------------------------------------------- 13.38s
Добавляю node узлы в кластер --------------------------------------------------------- 11.06s
Устанавливаю пакеты ------------------------------------------------------------------- 7.83s
Предотвращаю обновление kubelet, kubeadm и kubectl ------------------------------------ 4.89s
Добавляю gpg ключ для репозиториев Kubernetes и cri-o --------------------------------- 4.74s
haproxy_static_pods : Наливаю конфигурацию keepalived --------------------------------- 4.62s
haproxy_static_pods : Создать директории /etc/kubernetes/manifests и /etc/keepalived -- 4.48s
Gathering Facts ----------------------------------------------------------------------- 4.44s
Включаю и запускаю службы kubelet и cri-o --------------------------------------------- 4.30s
upgrade_packages : Обновляю все пакеты до актуальных версий --------------------------- 4.20s
Gathering Facts ----------------------------------------------------------------------- 3.70s
haproxy_static_pods : Наливаю check_apiserver.sh -------------------------------------- 3.52s
haproxy_static_pods : Наливаю haproxy.cfg --------------------------------------------- 3.31s
haproxy_static_pods : Наливаю haproxy static pods manifest ---------------------------- 3.31s
haproxy_static_pods : Наливаю keepalived static pods manifest ------------------------- 3.23s
Добавляю модули br_netfilter и overlay ------------------------------------------------ 3.21s

Если все прошло успешно, то можно перейти к настройке CNI.

Инициализация кластера

Первый вариант подходит для тестирования, или создания не отказоустоичивого кластера, Второй вариант создаст отказоустойчивый кластер готовый для прода. Ansible Playbook создает второй вариант.

Дальше описаны варианты для понимания работы.

Non HA (Подходит для тестирования, не рекомендуется для прода)

Для инициализации кластера запускаем на control-plane машинке команду

sudo kubeadm init --pod-network-cidr=10.244.0.0/16

Команда инициализирует кластер Kubernetes с указанием диапазона подсети для сети плагина CNI (Container Network Interface). В результате выполнения вы увидите лог выполнения и получите краткую инструкцию по дальнейшей работе.

В результате мы должны получить что-то подобное

kubectl get nodes -o wide
NAME              STATUS   ROLES           AGE    VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION       CONTAINER-RUNTIME
kubeadm-cp-01     Ready    control-plane   2m9s   v1.30.0   10.0.70.70    <none>        Ubuntu 22.04.4 LTS   5.15.0-105-generic   cri-o://1.30.0
kubeadm-node-01   Ready    <none>          27s    v1.30.0   10.0.70.71    <none>        Ubuntu 22.04.4 LTS   5.15.0-105-generic   cri-o://1.30.0
kubeadm-node-02   Ready    <none>          13s    v1.30.0   10.0.70.77    <none>        Ubuntu 22.04.4 LTS   5.15.0-105-generic   cri-o://1.30.0

HA (Production Ready решение, рекомендуется)

Мы разместим haproxy и keepalived на control-plane узлах. Конфигурации налиты при помощи Ansible на этапе подготовки. Наш виртуальный IP: 10.0.70.85:8888 для взаимодействия с Kube Api Server

Обратите внимание, что мы не устанавливаем kube-proxy, для этого мы указали ключ --skip-phases=addon/kube-proxy, этот вариант подходит при использовании Kubernetes без kube-proxy и позволяет использовать Cilium для его полной замены.

Если вы планируете использовать Flannel, нужно оставить kube-proxy.

sudo kubeadm init \
    --pod-network-cidr=10.244.0.0/16 \
    --control-plane-endpoint=10.0.70.85:8888 \
    --upload-certs \
    --skip-phases=addon/kube-proxy

При успешном выполнении мы увидим примерно следующее

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of the control-plane node running the following command on each as root:

  kubeadm join 10.0.70.85:8888 --token r120zn.za3vq0au6kzgoepu \
        --discovery-token-ca-cert-hash sha256:cacb3c674f63d7f261c4fed403f59ce6e7d4c869c3748e301c98b2b9f17f7786 \
        --control-plane --certificate-key 31ba08487b6899c2ebe43dd3857e168840a98d1077a7998c79f6f4838b4c08f7

Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 10.0.70.85:8888 --token r120zn.za3vq0au6kzgoepu \
        --discovery-token-ca-cert-hash sha256:cacb3c674f63d7f261c4fed403f59ce6e7d4c869c3748e301c98b2b9f17f7786

Добавляем узлы и проверяем.

В результате мы должны получить что-то подобное

kubectl get nodes -o wide
NAME              STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE           KERNEL-VERSION     CONTAINER-RUNTIME
kubeadm-cp-01     Ready    control-plane   46m   v1.30.0   10.0.70.70    <none>        Ubuntu 24.04 LTS   6.8.0-31-generic   cri-o://1.31.0
kubeadm-cp-02     Ready    control-plane   45m   v1.30.0   10.0.70.78    <none>        Ubuntu 24.04 LTS   6.8.0-31-generic   cri-o://1.31.0
kubeadm-cp-03     Ready    control-plane   45m   v1.30.0   10.0.70.79    <none>        Ubuntu 24.04 LTS   6.8.0-31-generic   cri-o://1.31.0
kubeadm-node-01   Ready    <none>          45m   v1.30.0   10.0.70.71    <none>        Ubuntu 24.04 LTS   6.8.0-31-generic   cri-o://1.31.0
kubeadm-node-02   Ready    <none>          45m   v1.30.0   10.0.70.77    <none>        Ubuntu 24.04 LTS   6.8.0-31-generic   cri-o://1.31.0
kubeadm-node-03   Ready    <none>          45m   v1.30.0   10.0.70.74    <none>        Ubuntu 24.04 LTS   6.8.0-31-generic   cri-o://1.31.0

Настройка CNI

CNI (Container Network Interface) - это спецификация, которая определяет, как контейнеры в сети взаимодействуют друг с другом и с внешним миром. Она позволяет плагинам сети в Kubernetes управлять сетевыми настройками контейнеров.

Cilium

Cilium - это проект с открытым исходным кодом для обеспечения сетевого взаимодействия, безопасности и наблюдаемости для облачных сред, таких как кластеры Kubernetes и другие платформы для оркестровки контейнеров.

В основе Cilium лежит новая технология ядра Linux под названием eBPF, которая позволяет динамически вставлять в ядро Linux мощную логику управления безопасностью, видимостью и сетями. eBPF используется для обеспечения высокопроизводительных сетей, мультикластерных и мультиоблачных возможностей, расширенной балансировки нагрузки, прозрачного шифрования, широких возможностей сетевой безопасности, прозрачной наблюдаемости и многого другого.

Есть несколько вариантов установки Cilium

Cilium CLI

Установите последнюю версию Cilium CLI. Cilium CLI можно использовать для установки Cilium, проверки состояния установки Cilium, а также для включения/выключения различных функций (например, кластерной сетки, Hubble).

brew install cilium-cli

Установите Cilium в кластер Kubernetes, на который указывает ваш текущий контекст kubectl:

cilium install --version 1.16.0

Helm Chart

Установка Cilium на кластер без kube-proxy

helm upgrade cilium cilium/cilium --version 1.16.0 \
    --namespace kube-system \
    --install \
    --values cilium/values.yaml

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

kubectl -n kube-system exec ds/cilium -- cilium-dbg status | grep KubeProxyReplacement

Для получения подробной информации используйте --verbose:

kubectl -n kube-system exec ds/cilium -- cilium-dbg status --verbose
KubeProxyReplacement Details:
  Status:                 True
  Socket LB:              Enabled
  Socket LB Tracing:      Enabled
  Socket LB Coverage:     Full
  Devices:                eth0   10.0.75.83 fe80::be24:11ff:fee9:819e (Direct Routing)
  Mode:                   SNAT
  Backend Selection:      Random
  Session Affinity:       Enabled
  Graceful Termination:   Enabled
  NAT46/64 Support:       Disabled
  XDP Acceleration:       Disabled
  Services:
  - ClusterIP:      Enabled
  - NodePort:       Enabled (Range: 30000-32767)
  - LoadBalancer:   Enabled
  - externalIPs:    Enabled
  - HostPort:       Enabled

Больше информации о работе без kube-proxy в официальной документации.

Проверяем статус установки

cilium status --wait

Мы должны увидеть что-то подобное

    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK
 /¯¯\__/¯¯\    Envoy DaemonSet:    disabled (using embedded mode)
 \__/¯¯\__/    Hubble Relay:       disabled
    \__/       ClusterMesh:        disabled

DaemonSet              cilium             Desired: 6, Ready: 6/6, Available: 6/6
Deployment             cilium-operator    Desired: 2, Ready: 2/2, Available: 2/2
Containers:            cilium             Running: 6
                       cilium-operator    Running: 2
Cluster Pods:          2/2 managed by Cilium
Helm chart version:
Image versions         cilium             quay.io/cilium/cilium:v1.15.6@sha256:6aa840986a3a9722cd967ef63248d675a87add7e1704740902d5d3162f0c0def: 6
                       cilium-operator    quay.io/cilium/operator-generic:v1.15.6@sha256:5789f0935eef96ad571e4f5565a8800d3a8fbb05265cf6909300cd82fd513c3d: 2

Выполните следующую команду, чтобы убедиться, что ваш кластер имеет правильное сетевое подключение (опционально):

cilium connectivity test

Пример вывода

✅ [cilium-test] All 52 tests (600 actions) successful, 28 tests skipped, 0 scenarios skipped.

Можно удалить неймспейс cilium-test

kubectl delete namespaces cilium-test

Установка тестового приложения

Для проверки работоспособности кластера установим kube-prometheus-stack при помощи helm

helm upgrade \
  --install \
  --namespace monitoring \
  --create-namespace \
  kube-prometheus-stack \
  prometheus-community/kube-prometheus-stack \
  --values ./kube-prometheus-stack/values.yaml  \
  --version 61.3.2

Проверяем, что все запустилось

kubectl get pods -o wide -n monitoring

Должны увидеть

NAME                                                        READY   STATUS    RESTARTS   AGE   IP           NODE              NOMINATED NODE   READINESS GATES
alertmanager-kube-prometheus-stack-alertmanager-0           2/2     Running   0          34s   10.244.2.5   kubeadm-node-02   <none>           <none>
kube-prometheus-stack-grafana-67997d8bd4-7s2fq              3/3     Running   0          50s   10.244.1.2   kubeadm-node-01   <none>           <none>
kube-prometheus-stack-kube-state-metrics-6fb5dddbdb-48l45   1/1     Running   0          50s   10.244.2.3   kubeadm-node-02   <none>           <none>
kube-prometheus-stack-operator-775b5fb784-gpn94             1/1     Running   0          50s   10.244.1.3   kubeadm-node-01   <none>           <none>
kube-prometheus-stack-prometheus-node-exporter-9d6ks        1/1     Running   0          50s   10.0.70.71   kubeadm-node-01   <none>           <none>
kube-prometheus-stack-prometheus-node-exporter-d74z8        1/1     Running   0          50s   10.0.70.77   kubeadm-node-02   <none>           <none>
kube-prometheus-stack-prometheus-node-exporter-fzgq2        1/1     Running   0          50s   10.0.70.70   kubeadm-cp-01     <none>           <none>
prometheus-kube-prometheus-stack-prometheus-0               2/2     Running   0          34s   10.244.2.6   kubeadm-node-02   <none>           <none>

Зайдем на веб интерфейс графаны

kubectl port-forward -n monitoring svc/kube-prometheus-stack-grafana 8000:80

Заходим на localhost:8000 и вводим

Логин: admin
Пароль: prom-operator

Настройка CSI

CSI (Container Storage Interface) - это спецификация, которая позволяет контейнерам в Kubernetes взаимодействовать с различными хранилищами данных, такими как блочные и файловые системы, через стандартизированный интерфейс. Это позволяет управлять хранилищем данных более гибко и эффективно в среде контейнеров.

Longhorn

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

Longhorn - это легкая, надежная и мощная система хранения распределенных блоков для Kubernetes.

Longhorn реализует распределенное блочное хранилище с помощью контейнеров и микросервисов. Longhorn создает выделенный контроллер хранения для каждого тома блочного устройства и синхронно реплицирует том на несколько реплик, хранящихся на нескольких узлах. Контроллер хранилища и реплики сами оркеструются с помощью Kubernetes.

Характеристики

  • Распределенное блочное хранилище корпоративного класса без единой точки отказа
  • Инкрементный снимок блочного хранилища
  • Резервное копирование на вторичное хранилище (NFS или S3-совместимое объектное хранилище), основанное на эффективном обнаружении блоков изменений
  • Повторяющиеся снимки и резервное копирование
  • Автоматизированное обновление без сбоев. Вы можете обновить весь стек программного обеспечения Longhorn, не нарушая работу томов хранения.
  • Интуитивно понятная приборная панель с графическим интерфейсом

Пререквизиты

  • Кластер Kubernetes: Убедитесь, что каждый узел соответствует требованиям к установке.
  • Ваша рабочая станция: Установите Helm версии 3.0 или более поздней.

Установка Longhorn

Примечание:

  • Начальные настройки для Longhorn можно найти в пользовательских опциях Helm или отредактировав файл конфигурации развертывания.
  • Для Kubernetes < v1.25, если в вашем кластере все еще используется контроллер допуска Pod Security Policy, установите значение helm enablePSP в true, чтобы установить ресурс longhorn-psp PodSecurityPolicy, который позволит запускать привилегированные поды Longhorn.

Требования к установке

Каждый узел в кластере Kubernetes, на котором установлен Longhorn, должен отвечать следующим требованиям:

  • Контейнерная среда выполнения, совместимая с Kubernetes (Docker v1.13+, containerd v1.3.7+ и т. д.)
  • Kubernetes >= v1.21
  • Установлен open-iscsi, и на всех узлах запущен демон iscsid. Это необходимо, поскольку Longhorn полагается на iscsiadm на узле для предоставления постоянных томов Kubernetes. Помощь в установке open-iscsi см. в этом разделе.
  • Поддержка RWX требует, чтобы на каждом узле был установлен клиент NFSv4. Об установке клиента NFSv4 читайте в этом разделе.
  • Файловая система узла поддерживает функцию расширения файлов для хранения данных. В настоящее время мы поддерживаем: ext4 XFS
  • Должны быть установлены bash, curl, findmnt, grep, awk, blkid, lsblk.
  • Распространение монтирования должно быть включено.

Рабочие нагрузки Longhorn должны иметь возможность запускаться от имени root, чтобы Longhorn был развернут и работал должным образом.

Этот сценарий можно использовать для проверки среды Longhorn на наличие потенциальных проблем.

Минимальное рекомендуемое аппаратное обеспечение см. в руководстве по передовому опыту.

  1. Добавьте репозиторий Longhorn Helm:

    helm repo add longhorn https://charts.longhorn.io
  2. Получите список последних чартов из репозитория:

    helm repo update
  3. Установите Longhorn в пространстве имен longhorn-system.

    helm upgrade \
      --install \
      longhorn longhorn/longhorn \
      --namespace longhorn-system \
      --create-namespace \
      --version 1.6.2
  4. Чтобы убедиться, что развертывание прошло успешно, выполните команду:

    kubectl -n longhorn-system get pod

    Результат должен выглядеть следующим образом:

    NAME                                                READY   STATUS    RESTARTS   AGE
    csi-attacher-799967d9c-nx4f9                        1/1     Running   0          3m10s
    csi-attacher-799967d9c-vsz7g                        1/1     Running   0          3m10s
    csi-attacher-799967d9c-zh6vq                        1/1     Running   0          3m10s
    csi-provisioner-58f97759c-676jf                     1/1     Running   0          3m10s
    csi-provisioner-58f97759c-fxsb5                     1/1     Running   0          3m10s
    csi-provisioner-58f97759c-krfs2                     1/1     Running   0          3m10s
    csi-resizer-6c9b8598f4-dzxwp                        1/1     Running   0          3m10s
    csi-resizer-6c9b8598f4-kkfn4                        1/1     Running   0          3m10s
    csi-resizer-6c9b8598f4-wq47f                        1/1     Running   0          3m10s
    csi-snapshotter-5c5f9b754d-4pdbg                    1/1     Running   0          3m10s
    csi-snapshotter-5c5f9b754d-7n7wf                    1/1     Running   0          3m10s
    csi-snapshotter-5c5f9b754d-q4rzx                    1/1     Running   0          3m10s
    engine-image-ei-5cefaf2b-8j4j9                      1/1     Running   0          3m14s
    engine-image-ei-5cefaf2b-94g2f                      1/1     Running   0          3m14s
    engine-image-ei-5cefaf2b-g5bg5                      1/1     Running   0          3m14s
    instance-manager-3af1ba7167264c2020df4d36d77d3905   1/1     Running   0          3m14s
    instance-manager-8452580cb8e2bc9ad134bb6a1c2806cc   1/1     Running   0          3m12s
    instance-manager-a006e8fdef719ff0b5aee753abbe1dd8   1/1     Running   0          3m14s
    longhorn-csi-plugin-bswvc                           3/3     Running   0          3m10s
    longhorn-csi-plugin-fmlrd                           3/3     Running   0          3m10s
    longhorn-csi-plugin-tpnqm                           3/3     Running   0          3m10s
    longhorn-driver-deployer-68b5879955-7tkrs           1/1     Running   0          3m31s
    longhorn-manager-5psrc                              1/1     Running   0          3m31s
    longhorn-manager-5qjbd                              1/1     Running   0          3m31s
    longhorn-manager-rwzbb                              1/1     Running   0          3m31s
    longhorn-ui-9ccf5c989-bxdv2                         1/1     Running   0          3m31s
    longhorn-ui-9ccf5c989-dsvz6                         1/1     Running   0          3m31s
    
  5. Чтобы включить доступ к пользовательскому интерфейсу Longhorn, необходимо настроить контроллер Ingress.

    По умолчанию аутентификация в пользовательском интерфейсе Longhorn не включена. Информацию о создании контроллера NGINX Ingress с базовой аутентификацией см. в этом разделе.

  6. Войдите в пользовательский интерфейс Longhorn, выполнив следующие действия.

Посмотреть на веб интерфейс можно так:

kubectl port-forward -n longhorn-system svc/longhorn-frontend 8000:80

Ingress Controller

Ingress Controller - это компонент в Kubernetes, который управляет входящими HTTP и HTTPS запросами в кластер. Он обеспечивает балансировку нагрузки, маршрутизацию трафика и обеспечивает доступ к службам внутри кластера извне.

Ingress Controller работает на уровне приложения и использует информацию из объекта Ingress, который определяет правила маршрутизации для входящего трафика. Это позволяет настраивать маршрутизацию трафика без изменения конфигурации службы или приложения.

Установка при помощи helm

Добавьте репозиторий Traefik Labs в Helm:

helm repo add traefik https://traefik.github.io/charts

Вы можете обновить хранилище, выполнив команду:

helm repo update

И установите его с помощью командной строки Helm:

helm upgrade \
  --install \
  --namespace traefik \
  --create-namespace \
  traefik traefik/traefik \
  --values traefik/values.yaml
helm upgrade \
  --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx \
  --create-namespace \
  --set controller.kind=DaemonSet \
  --set controller.hostNetwork=false \
  --set controller.hostPort.enabled=false \
  --set controller.service.loadBalancerIP=10.0.70.199

Проброс дашборда Traefik

kubectl port-forward -n traefik $(kubectl get pods -n traefik --selector "app.kubernetes.io/name=traefik" --output=name) 9000:9000

Его ним можно увидеть по адресу: 127.0.0.1:9000/dashboard/

Удаляем узел из кластера

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

kubectl get nodes -o wide

Эти команды выполняют следующие действия:

  • kubectl drain - этот шаг убеждается, что все поды, которые могут быть перезапущены в другом месте, были перезапущены. Он также удаляет все пустые директории, которые были созданы подами на узле, и удаляет все поды, которые не могут быть перезапущены в другом месте (например, поды, которые имеют локальные данные).
kubectl drain kubeadm-node-01 --delete-local-data --force --ignore-daemonsets
  • kubectl delete node - этот шаг удаляет узел из кластера. Обратите внимание, что эти команды могут привести к потере данных, поэтому убедитесь, что вы понимаете, что делаете, и что у вас есть резервное копирование данных, если это необходимо.
kubectl delete node kubeadm-node-01

Просмотр списка join ссылок в Kubernetes

Для просмотра списка join ссылок в Kubernetes, вы можете использовать команду kubeadm token list. Эта команда отобразит список всех активных join токенов, которые могут быть использованы для присоединения новых узлов к кластеру.

Вот пример использования:

kubeadm token list

Для получения join ссылки в Kubernetes, вы можете использовать команду kubeadm token create --print-join-command. Эта команда создаст новый join токен и напечатает команду, которую вы можете использовать для присоединения новых узлов к кластеру.

Вот пример использования:

kubeadm token create --print-join-command