История этой статьи берет свое начало в далеком 2023 году. Именно тогда я поднимал свой первый kubernetes кластер в домашних условиях на локальном сервере для своих потребностей, который жил до недавнего времени.
С чего все началось сейчас - это банальный апгрейд серверного железа (серверного это конечно слишком круто, обычный ПК чуть покруче чем рабочая станция да с RAID10). А раз так то, пора и софт обновить. На момент сборки сервера у меня стоял Debian (люблю я его), но так как все локально и для себя обновления я не ставил особо часто (не трогай если все работает). Жужжала железка в подсобке и кушать не просила.
Сразу скажу, что были мысли просто сделать upgrade Debian и все пакеты иже с ним, но посмотрев на мамонта, принял решение все сделать с нуля. Приступаем к делу, которое хоть и кажется большим но выполняется достаточно просто.
Конфигуарция NOD
MASTER NODE (1 шт)
- 2 CPU / vCPU
- 2 GB RAM
- 100 GB HDD
WORKER NOD (2 шт, может быть бесконечно с ресурсами по возможности)
- 8 CPU / vCPU
- 16 GB RAM
- 100 GB HDD
Подготовка операционной системы
Debian 12 для Kubernetes
Устанавливаем необходимые для работы пакеты и настройки Firewall на всех нодах:
apt install curl
apt install gpg
apt install procps после установки выполнить
export PATH=$PATH:/sbin:/usr/sbin
apt install ufw
добавим сразу в patch
export PATH=$PATH:/usr/sbin
ufw enable
Будет запрошено подтверждение на включение, где ответим да
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
CRITICAL: Поле добавляем правило с разрешением доступ по ssh
root@K8S-MASTER:/home/admin# ufw allow 22/tcp
Rules updated
Rules updated (v6)
Перезапускаем файрвол:
root@K8S-MASTER:/home/admin# ufw reload
Firewall reloaded
Все операции выше делаем на всех нодах и теперь можно работать спокойно. Порт SSH можно заменить на свой, но так как у меня система стоит в закрытом контуре (за NAT), то мне позволяет религия пользоваться такими настройками.
Настройки Firewall которые делаем на MASTER NOD
ufw allow 6443/tcp
ufw allow 2379/tcp
ufw allow 2380/tcp
ufw allow 10250/tcp
ufw allow 10251/tcp
ufw allow 10252/tcp
ufw allow 10255/tcp
ufw reload
Настройки Firewall которые делаем на WORKER NOD
ufw allow 22/tcp - ssh
ufw allow 10250/tcp
ufw allow 30000:32767/tcp
ufw reload
Добавим нужные нам репозитарии Kubernetes.
$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
Незабывем, после добавления сделать
apt update, и проверить, что у вас не выводит ошибок, что система не может достучаться до ресурсов.
Настройка имен серверов
$ sudo hostnamectl set-hostname "k8s-master.vmconnect.ru" // Run on master node
$ sudo hostnamectl set-hostname "k8s-worker1.vmconnect.ru" // Run on 1st worker node
$ sudo hostnamectl set-hostname "k8s-worker2.vmconnect.ru" // Run on 2nd worker node
Делаем доступ к серверам в рамках локали, для чего правим файл /etc/hosts, настройку делаем на всех нодах
Ваш IP k8s-master.vmconnect.ru k8s-master
Ваш IP k8s-worker1.vmconnect.ru k8s-worker1
Ваш IP k8s-worker2.vmconnect.ru k8s-worker2
Отключаем Swap на всех Nodes без исключения
$ swapoff -a
$ sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
Перезагружаем виртуалки (У меня каждая нода это отдельная виртуальная машина), проверяем еще раз доступность серверов командой ping по имени и IP, если все доступно приступаем к выполнению дальнейшей инструкции.
Настроим важные функции ядра и сети
$ cat <<EOF | tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
$ cat <<EOF | tee /etc/sysctl.d/99-kubernetes-k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
После ввода команды применяем настройки
$ sudo sysctl --system
Если система сообщила
root@K8S-WORKER2:/home/admin# sysctl --system
bash: sysctl: команда не найдена
Выполните ввод команды
apt install procps
export PATH=$PATH:/sbin:/usr/sbin
повторите применение sysctl --system
Приступаем в установке
Kubernetes и его компонентов
По шагам проходим по командам на каждой из нод (Master и оба Worker)
$ apt update
$ apt -y install containerd
Задаем default конфигурацию containerd
$ containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
Теперь самое главное в конфигурации сделать разрешение групп.
Открываем конфигурацию nano /etc/containerd/config.toml
Перезапускаем containerd
$ systemctl restart containerd
$ systemctl enable containerd
Следующим шагом нам нужно установить Tool
Проверьте еще раз, что у вас добавлены нужные репозитории (делали в начале статьи)
$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list
$ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
И стартуем к установке
$ apt update
$ apt install kubelet kubeadm kubectl -y
$ apt-mark hold kubelet kubeadm kubectl
На последнем этапе кода вводим apt-mark hold kubelet kubeadm kubectl, мы должны получить вот такое сообщение:
kubelet помечен как зафиксированный.
Если оно получено, вы спешно спраивлись с задаче. 90% работы сделано и мы можем продолжать дальше.
Все что мы делали выполняется на Master & Worker нодах. Это базовый набор компонентов и настроек для работы кластера Kubernetes.
Для завершения работ, нам необходимо поднять MSTER так, чтоб он мог управлять WIRKER.
Установка Kubernetes Cluster with Kubeadm
Для начала работ и упрощения их в целом создадим конфигурационный файл с именем kubelet.yaml - именно он позволит нам в будущем управлять нашим кластером
$ nano kubelet.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
kubernetesVersion: "1.28.0" # Указываем какую версию kubernetes мы ставим
controlPlaneEndpoint: "k8s-master1"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
Запускаем инициализацию:
$ sudo kubeadm init --config kubelet.yaml
Итогом и успешной инициализацией кластера будет сообщение
(Сохраните целиком это сообщение оно вам очень сильно будет нужно)
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 control-plane nodes by copying certificate authorities and service account keys on each node and then running the following as root:
kubeadm join k8s-master1:6443 --token evl0sp.vavsbdwo3tcel88r6m \--discovery-token-ca-cert-hash sha256:66c3a9f4d3684f4f1fde36a339370ca608082b2d223963330521b80084a0d370413 \
--control-plane
Для подключения новых nodes ввести:
kubeadm join k8s-master1:6443 --token evl0sp.vavsbdo3tcel88r6m \--discovery-token-ca-cert-hash sha256:66c3a9f4d3684f4f1f6a33937cd320ca608082b2d223963330521b80084a0d370413
Проверить что у нас получилось и как работает наш кластер, сохраним все что нужно для конфигурирования:
$ mkdir -p $HOME/.kube
$ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ chown $(id -u):$(id -g) $HOME/.kube/config
В консоли, мастер ноды проверяем
kubectl get nodes
Так как у меня уже добавлены веркеры я вижу все что у меня в кластере, у вас будет для начала только мастер.
kubectl cluster-info
И теперь надо в кластер добавить ноды, для этого когда на местере мы делали инициализацию в самом конце вы получите вот такое сообщение
Для подключения новых nodes ввести:
kubeadm join k8s-master1:6443 --token evl0sp.vavsbdo3tcel88r6m \--discovery-token-ca-cert-hash sha256:66c3a9f4d3684f4f1f6a33937cd320ca608082b2d223963330521b80084a0d370413
Именно его мы будем использовать всегда, чтоб добавлять ноды.
Установка Pod Network Using Calico
Calico — это популярная сетевая плагин (CNI, Container Network Interface) для Kubernetes, который обеспечивает сетевое взаимодействие между подами, а также политики безопасности (Network Policies)
Поэтому, давайте развернем один из последних компонентов для Kubernetes.
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml
Разрешим нужные нам порты
$ ufw allow 179/tcp
$ ufw allow 4789/udp
$ ufw allow 51820/udp
$ ufw allow 51821/udp
$ ufw reload
Проверяем работу
kubectl get pods -n kube-system
Результат видим на скрине ниже, все получилось.
Для управления кластерами Kubernetes как и всегда применяем консоль, но есть и dashboard, причем их достаточно много и можно выбрать по вкусу.
Установка классического
kubernetes-dashboard
Приступаем к работам на Master ноде.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.1/aio/deploy/recommended.yaml
kubectl get all -n kubernetes-dashboard
Как попасти в dashboard
Сервис kubernetes-dashboard для доступа к dashboard имеет по умолчанию тип ClusterIP, чтобы можно было получить доступ, нужно изменить тип на NodePort, что мы сейчас и сделаем.
kubectl edit service/kubernetes-dashboard -n kubernetes-dashboard
Результатом мы более чем довольны и нас интересует строка обведенная красным прямоугольником, а именно порт TCP\IP, идем в браузер и вбиваем в строку
https:// IP вашей мастер ноды :30919/#/workloads?namespace=_all
и получаем приветствие:
Вход с помощью токена - мне больше всех нравится
Токены доступа существует в секретном хранилище созданного пользователя. Он автоматически генерируется при создании пользователя, и нужно получить его для входа в dashboard.
Так как у нас пользователя нет, давайте его быстро сделаем
Создание пользователя
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: superadmin-user namespace: kubernetes-dashboard
EOF
Определение роли нового пользователя
cat <<EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: superadmin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: superadmin-user namespace: kubernetes-dashboard
EOF
Получаем токен
kubectl -n kubernetes-dashboard create token superadmin-user
Копируем токен и авторизуемся.
Вот и получили наш dashboard
Давайте подведем итоги, что у нас получилось и порадуемся какие мы молодцы.
- Мы собрали классический кластер kubernetes состоящий из 2-х рабочих нод WORKER и одной MASTER ноды. Это рабочая лошадка, будет жить и не приносить сложностей пока не умрет дисковая подсистема.
- Мы установили dashboard который позволит смотреть и принимать решение, что делать. Dashboard со своей ролью будет справляться, если вдумчиво действовать в его рамках и не путать возможности консоли с конфигами и визуальные кнопочки. Я поставил его себе чисто поиграться не более того, все люблю делать в консоли.
- Мы подготовили площадку для будущего деплоя, о чем расскажу в следующих выпусках.
Как всегда, подписывайтесь на канал, никакого пока платного контента. Если нужна консультация, смело пишите комментарии.