Содержание
Уcтанавливаем Kubernetes - kubeadm.
Долго, нудно. Но позволяет понять весь процесс…
Подготовка
Дано:
Есть как минимум 5 физических или виртуальных машин с установленной OS Debian.
Требуется:
Развернуть кластер минимально работоспособный кластер Kubernetes в составе:
- 3-х серверов control-plane
- 2-х (и более) серверов workers
Данную инструкцию писал для себя. Если Вы будете ее использовать - используйте на свой страх и риск. И не забывайте менять ip адреса и параметры в настройках.
Предварительная подготовка control-plane серверов
Установим на все три сервера, которые планируем использовать для control-plane OS Debian 12 в минимальной конфигурации, без графического интерфейса.
Сервера должны удовлетворять минимальным требованиям:
- 2 GB или больше RAM на машину.
- 2 CPUs или больше.
- Машины должны видеть друг друга по сети.
- Уникальные hostname, MAC и product_uuid для каждой ноды.1
- Открыты необходимые порты на нодах.2
- Поправить /etc/hosts или dns что бы машины видели друг друга по именам.
- Выключена подкачка - swap.
- Обязательно синхронизировано время на всех нодах.
1
Product_uuid можно поглядеть #cat /sys/class/dmi/id/product_uuid
2
Control-plane node(s):
Protocol | Direction | Port Range | Purpose | Used By |
---|---|---|---|---|
TCP | Inbound | 6443 | Kubernetes API server | All |
TCP | Inbound | 2379-2380 | etcd server client API | kube-apiserver, etcd |
TCP | Inbound | 10250 | kubelet API | Self, Control plane |
TCP | Inbound | 10259 | kube-scheduler | Self |
TCP | Inbound | 10257 | kube-controller-manager | Self |
Worker node(s):
Protocol | Direction | Port Range | Purpose | Used By |
---|---|---|---|---|
TCP | Inbound | 10250 | kubelet API | Self, Control plane |
TCP | Inbound | 30000-32767 | NodePort Services* | All |
Любые номера портов, отмеченные знаком *, могут быть в переопределены в Вами в дальнейшем.
Вообще, по моему мнению, выставлять кластер во внешние сети - это простой и быстрый способ создать себе проблемы. Между внешними сетями (например internet) и кластером обязательно должен быть межсетевой экран.
Замечаение про Swap:
По умолчанию, поддержка swap в kubernetes отключена. Можно включить поддержку swap в настройках, но так как это просто пример развертывания kubernetes кластера - просто отключим swap на всех серверах.
Планируем
Спланируем, как будут называться наши ноды в кластере, и какие у них будут IP:
Имя ноды | IP |
---|---|
k8s-master-71 | 192.168.254.71 |
k8s-master-72 | 192.168.254.72 |
k8s-master-73 | 192.168.254.73 |
k8s-worker-74 | 192.168.254.74 |
k8s-worker-75 | 192.168.254.75 |
Так же, зарезервируем на будущее ip - 192.168.254.70. Это у нас будет ip адрес для доступа к кластеру, не привязанный к конкретной ноде (для высокой доступности кластера).
Настраиваем ноды
Для примера, приведу настройку одной ноды. То же самое нужно сделать на всех нодах, изменив их имена и адреса соответственно.
Ставим sudo, всегда работать от имени root-а - это нехорошо и небезопасно.
apt install sudo usermod -aG sudo <username>
Отключаем Swap:
swapoff -a
и комментируем строчку в файле /etc/fastb которая отвечает за загрузку swap
При необходимости немного настроим сеть:
Правим /etc/network/interfaces
в нем конфигурируем сетевой интерфейс:
# The primary network interface allow-hotplug <interface_name> iface <interface_name> inet static address 192.168.254.71/24 gateway 192.168.254.1
Правим /etc/resolv.conf
в нем прописываем dns сервер:
nameserver 8.8.4.4
Правим /etc/hosts в нем прописываем все наши ноды - их адреса и имена:
192.168.254.70 k8s-master 192.168.254.71 k8s-master-71 192.168.254.72 k8s-master-72 192.168.254.73 k8s-master-73 192.168.254.74 k8s-worker-74 192.168.254.75 k8s-worker-75
Ставим дополнительные необходимые пакеты
sudo apt update sudo apt upgrade -y sudo apt install curl apt-transport-https ca-certificates gnupg2 wget socat chrony -y
Загружаем модули и меняем sysctl
sudo modprobe overlay sudo modprobe br_netfilter
Правим(создаем) файл: sudo nano /etc/sysctl.d/kubernetes.conf
и в него добавляем:
net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1
Правим(создаем) файл: sudo nano /etc/modules-load.d/containerd.conf и в него добавляем:
overlay br_netfilter
Применяем изменения:
sudo sysctl --system
Устанавливаем containerd
Получаем ключик:
sudo mkdir -m 0755 -p /etc/apt/keyrings sudo wget https://download.docker.com/linux/debian/gpg -O /etc/apt/keyrings/docker.asc sudo chmod 644 /etc/apt/keyrings/docker.asc
Получаем репы:
sudo echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Устанавливаем последнею версию containerd
sudo apt-get install containerd.io
Немного ее настраиваем:
sudo mkdir -p /etc/containerd sudo containerd config default >/etc/containerd/config.toml sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
Запускаем:
sudo systemctl restart containerd sudo systemctl enable containerd
Устанавливаем kubeadm, kubelet и kubectl
Для начала - надо знать какую версию мы будем устанавливать.
Посмотреть какие версии есть - можно например тут.
В моем случае - актуальная версия: v1.31
Получаем ключики:
sudo wget https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key -O /etc/apt/keyrings/kubernetes-apt-keyring.asc sudo chmod 644 /etc/apt/keyrings/kubernetes-apt-keyring.asc
Получаем репы:
sudo echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.asc] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
Ставим kubeadm, kubelet и kubectl и замораживаем.
sudo apt-get update sudo apt-get install -y kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
Запускаем kubelet:
sudo systemctl enable --now kubelet
Еще немного настраиваем containerd:
SAND=`kubeadm config images list | grep pause | cut -d: -f 2` && sed -i "s/:.*/\:${SAND}\"/" /etc/containerd/config.toml systemctl restart containerd
Отказоустойчивый control-plane
Нам надо control-plane которая устойчива к сбоям и отказам. Например, к выходу из строя одной control-plane ноды.
Поэтому, на всех control-plane (и только control-plane) нодах устанавливаем keepalived.
sudo apt install keepalived -y
Приводим файл конфига keepalived (/etc/keepalived/keepalived.conf) к следующему виду:
global_defs { router_id MyKube_123 <= Это надо поменять enable_script_security } vrrp_script apiserver { script "/usr/bin/curl -s -k https://localhost:6443/healthz -o /dev/null" interval 20 timeout 5 rise 1 fall 1 user root } vrrp_instance Kube_71 { state MASTER interface ens192 <= Это надо поменять virtual_router_id 51 <= Это надо поменять priority 100 advert_int 1 authentication { auth_type PASS auth_pass skdjfgkwjrhflehkurf <= Это надо поменять } virtual_ipaddress { 192.168.254.70 label ens192:keep <= Это надо поменять } track_script { apiserver } }
Запускаем keepalived на всех control-plane нодах.
systemctl restart keepalived systemctl enable keepalived
Устанавливать дополнительно, как указано в других местах haproxy - нет смысла. При поднятие адреса keepalived на этом же адресе поднимается порты доступа к kubeAPI.
Инициализируем кластер
Создадим файл конфигурации для kubeadm - /etc/kubernetes/kubeadm-config.yaml
В него добавим следующею конфигурацию:
--- apiVersion: kubeadm.k8s.io/v1beta4 kind: ClusterConfiguration controlPlaneEndpoint: "192.168.254.70:6443" clusterName: "cluster.local" etcd: local: extraArgs: - name: listen-metrics-urls value: http://0.0.0.0:2381 networking: podSubnet: "10.244.0.0/16" scheduler: extraArgs: - name: bind-address value: "0.0.0.0" controllerManager: extraArgs: - name: bind-address value: "0.0.0.0" --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration metricsBindAddress: 0.0.0.0 mode: ipvs ipvs: strictARP: True
Актуальную версию kubeadm.k8s.io/v1beta4 можно поглядеть так:
kubeadm config print init-defaults | grep apiVersion
Подробности про параметры конфига можно прочитать тут: https://kubernetes.io/docs/reference/config-api/. Обращаем внимание на версии!
Соб-но подготовка закончена. Приступим к сбору кластера в одно целое.
На одной из нод, которая у нас будет исполнять роль control-plane запускаем:
sudo kubeadm init --config /etc/kubernetes/kubeadm-config.yaml --upload-certs
Нода задумается и если все хорошо, выведет инструкцию по дальнейшему добавлению остальных нод в кластер.
Для добавления других control-plane нод:
kubeadm join 192.168.254.70:6443 –token egcvbl.g97lu30g8lejfiz3 \
–discovery-token-ca-cert-hash sha256:0af49752295e168f14debc45484d4fb0a2479e492b026d07916b75beb513b086 \
–control-plane –certificate-key 7070f2f345910332376947bdaf46cdcf991c208a00c8601bf6e99fa930fe3efa
И для добавления к кластер workers нод:
kubeadm join 192.168.254.70:6443 –token egcvbl.g97lu30g8lejfiz3 \
–discovery-token-ca-cert-hash sha256:0af49752295e168f14debc45484d4fb0a2479e492b026d07916b75beb513b086
На соответствующих нодах выполняем соотвествующие команды для добавления этих нод в кластер.
Примечание:
Выданные кластером токены на присоединение будут действительны:
- 2 часа для присоединения control-plane нод
- 24 часа для присоединения worker нод
по соображениям безопасности.
Однако, в любой момент можно создать новый токен для присоединения worker ноды:
sudo kubeadm token create --print-join-command
и certificate-key для присоединения control-plane нод:
kubeadm init phase upload-certs --upload-certs
Теперь проверим, все ли собралось.
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config kubectl get ComponentStatus kubectl get nodes
Мы должны увидеть состояние кластера. Он собрался, компоненты кластера работают, но ноды пока все еще не готовы так как нет сетевого плагина:
NAME | STATUS | MESSAGE | ERROR |
---|---|---|---|
scheduler | Healthy | ok | |
controller-manager | Healthy | ok | |
etcd-0 | Healthy | ok |
NAME | STATUS | ROLES | AGE | VERSION |
---|---|---|---|---|
k8s-master-71 | NotReady | control-plane | 2m34s | v1.31.1 |
k8s-master-72 | NotReady | control-plane | 2m15s | v1.31.1 |
k8s-master-73 | NotReady | control-plane | 2m10s | v1.31.1 |
k8s-worker-74 | NotReady | <none> | 1m20s | v1.31.1 |
k8s-worker-75 | NotReady | <none> | 37s | v1.31.1 |
Теперь самое время установить сетевой плагин flannel + MetalLB или сетевой плагин Calico CNI+PureLB.