k8s - хорошая шутка, но технологию очень сильно привязывают к облакам, например AWS и т.д. Но что делать, если у тебя есть свои мощности, и хочется поработать с k8s на своих машинах, или же просто поднять кластер на виртуалках, чтобы поучиться им пользоваться.
Я задумался, о том, что хочу поднять свой кластер, чтобы просто поучиться работать с “кубером”, на своей работе мы его не используем (да такие организации есть), но потрогать технологию хочется, особенно когда о ней много пишут, говорят, показывают)
Для начала нам нужно поднять 2 или 3 виртуальные машины. Я решил выбрать именно три. Устанавливаем на них Ubuntu 22.04 LTS
Назову я их так
k8s-master-01 IP: 192.168.88.54
k8s-node-01 IP: 192.168.88.55
k8s-node-02 IP: 192.168.99.56
Теперь начнем предварительную настройку
Настройка всех машин
Настройка системы
Сейчас я буду описывать команды, которые необходимо выполнить на все виртуалках, неважно какая у них будет роль, то есть мы настраиваем и мастер и ноды
Настоим файл hosts, чтобы было проще ориентироваться и приведем файл к подобному виду
/etc/hosts
127.0.0.1 localhost
127.0.1.1 k8s-master-01
192.168.88.54 k8s-master-01
192.168.88.55 k8s-node-01
192.168.88.56 k8s-node-02
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
В файл были добавлены эти строки
192.168.88.54 k8s-master-01
192.168.88.55 k8s-node-01
192.168.88.56 k8s-node-02
Обновим пакеты системы
apt update && apt upgrade -y && apt dist-upgrade -y
Установим необходимые пакеты
apt install curl apt-transport-https git -y
Отключаем файл подкачки
swapoff -a
И отключим монтирование этого файла при загрузке системы
В файле /etc/fstab
находим строку, начинающуюся с /swap.img
и комментируем ее
...
#/swap.img none swap sw 0 0
Загружаем дополнительные модули ядра
Создадим файл /etc/modules-load.d/k8s.conf
и запишем в него
br_netfilter
overlay
br_netfilter расширяет возможности netfilter, overlay необходим для Docker
Сразу же загрузим эти модули, чтоб не перезагружать систему
modprobe br_netfilter && modprobe overlay
И проверяем, загружены ли они
lsmod | egrep "br_netfilter|overlay"
Вывод будет примерно вот таким
overlay 151552 16
br_netfilter 32768 0
bridge 307200 1 br_netfilter
Создадим еще один файл /etc/sysctl.d/k8s.conf
с содержимым
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
Данная настройка контролирует возможность обработки трафика через bridge в netfilter. В нашем примере мы разрешаем данную обработку для IPv4 и IPv6
Применяем параметры командой sysctl --system
Установка Docker
На всех узлах кластера установим Docker
apt install docker docker.io -y
Разрешаем автозапуск докера
systemctl enable docker
Создадим файл /etc/docker/daemon.json
, если он уже есть, то приводим его к подобному виду
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
Важным параметром является настройка native.cgroupdriver, значение должно быть именно systemd
. Если этого не сделать, при создании кластера k8s выдаст множество предупреждений, что по началу может сбивать с толку, но не повлияет на работоспособность кластера
И перезапускаем Docker
service docker restart
Установка Kubernetes
Установка выполняется из сторонних репозиториев, по этому для начала добавим публичный ключ проверки подписи пакетов
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
Добавим сам репозиторий создав файл /etc/apt/sources.list.d/kubernetes.list
с содержимым
deb https://apt.kubernetes.io/ kubernetes-xenial main
И выполним установку
apt update && apt install kubelet kubeadm kubectl -y
Для полноценной работы кластера данные пакеты необходимо установить на всех узлах
Полноценная работа кластера сильно зависит от версий установленных пакетов, чтобы случайно не обновить пакет, требуется запретить его обновление
apt-mark hold kubelet kubeadm kubectl
Настройка Master Node k8s
Настройка системы
Теперь мы работаем только на мастер ноде. Нужно заранее решить одну проблему, которой я столкнулся на Ubuntu 22.04 LTS. Когда вы будете инициализировать мастер, он может падать.
Решение я нашел вот тут: https://github.com/kubernetes/kubernetes/issues/106464
apparently, the new Linux system which by default use cgroup v2 such as Arch linux, bullseye, ubuntu 21 , etc causing problems when deploying Kubernetes cluster using kubeadm init
по-видимому, новая система Linux, которая по умолчанию использует cgroup v2, такую как Arch linux, bullseye, ubuntu 21 и т. д., вызывает проблемы при развертывании кластера Kubernetes с использованием kubeadm init.
Решением было включить cgroup v1 при старте системы. Для этого нам нужно отредактировать файл /etc/default/grub
Находим строку GRUB_CMDLINE_LINUX_DEFAULT=""
и добавим значение systemd.unified_cgroup_hierarchy=0
Пример готового файла /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="systemd.unified_cgroup_hierarchy=0"
GRUB_CMDLINE_LINUX=""
Затем обновляем настройки grub2 update-grub
и перезагружаем master node
Инициализация master node
Установим дополнительные пакеты для master node
apt update && apt install kubeadm kubectl -y
kubelet мы уже устанавливали и отключили автообновление, по этому его уже не трогаем
Так же отключим автообновление
apt-mark hold kubeadm kubectl
Установка завершена, проверяем версию k8s
kubectl version --client --output=yaml
clientVersion:
buildDate: "2022-07-13T14:30:46Z"
compiler: gc
gitCommit: aef86a93758dc3cb2c658dd9657ab4ad4afc21cb
gitTreeState: clean
gitVersion: v1.24.3
goVersion: go1.18.3
major: "1"
minor: "24"
platform: linux/amd64
kustomizeVersion: v4.5.4
Создание кластера
Инициализация мастер ноды
kubeadm init --pod-network-cidr=10.244.0.0/16
–pod-network-cidr - задает внутреннюю подсеть для нашего кластера
Данный процесс не быстрый и занимает несколько минут, после выполнения мы увидим подобный вывод
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/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.88.54:6443 --token 9x5u03.gvpohd0ihswqf38x \
--discovery-token-ca-cert-hash sha256:bb7a86234c57d4a77fab5accbe159385f25e7091b5569abcd155ff4b7d41b0da
Разберем, что нам вывели
Выполняем данные команды, чтоб конфиг k8s лежал у пользователя в домашней папке
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Так же рекомендуется в окружение пользователя добавить переменную KUBECONFIG, можно просто выполнить эту команду
export KUBECONFIG=/etc/kubernetes/admin.conf
или лучше вот так
export KUBECONFIG=$HOME/.kube/config
Чтобы каждый раз команду не вводить, добавим ее в ENV. В файле /etc/environment
добавим строку
export KUBECONFIG=$HOME/.kube/config
Можно так же в домашней папке пользователя добавить в файл ~/.bashrc
, в самый низ строку export KUBECONFIG=$HOME/.kube/config
Посмотреть список узлов кластера можно данной командой
kubectl get nodes
На данном этапе мы должны увидеть только мастер ноду:
NAME STATUS ROLES AGE VERSION
k8s-master-01 NotReady control-plane 5m v1.27.2
Как можно увидеть, статус мастера не готов, и он так и будет висеть, пока не завершим настройку. Для этого нужно добавить CNI (Container Networking Interface) - это файл описывающий принцип работы сетевой инфраструктуры контейнеров. Их есть несколько вариантов, но пока возьмем тот, что я первый нашел в сети
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yaml
Через несколько минут мастер нода будет в статусе готовности и можно добавлять ноды в кластер
Инициализация ноды
Если так случилось, что вы потеряли команду на присоединение ноды к кластеру, то просто выполнить на мастере
kubeadm token create --print-join-command
На выводе, вы получаете команду, для присоединения ноды к кластеру
kubeadm join 192.168.99.54:6443 --token 2lobny.ji1kxd65rhr5ypl3 \
--discovery-token-ca-cert-hash \
sha256:bb7a86234c57d4a77fab5accbe159385f25e7091b5569abcd155ff4b7d41b0da
Выполняем данную команду на сервере k8s-node-01 (192.168.88.55) и на втором k8s-node-02 (192.168.88.56), ждем завершения процесса
После завершения работы команды, мы должны увидеть подобное
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
На мастер ноде вводим поиск новых нод
kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-01 Ready control-plane 18m v1.27.2
k8s-node-01 Ready <none> 80s v1.27.2
k8s-node-02 NotReady <none> 90s v1.27.2
Обратите внимание, что нода k8s-node-02 имеет статус NotReady. Это значит, что настройка еще выполняется и необходимо подождать. Как правило, в течение 2 минут статус меняется на Ready
Фаервол
Разрешим через UFW порты на мастер ноде
ufw allow 6443/tcp
ufw allow 6000:6007/tcp
ufw allow 10250:10252/tcp
6443 - подключение для управления (Kubernetes API)
2379:2380 - порты для взаимодействия мастера с воркерами (etcd server client API)
10250:10252 - работа с kubelet (соответственно API, scheduler, controller-manager)
На рабочей ноде
ufw allow 10250/tcp
ufw allow 30000:32767/tcp
10250 - подключение к kubelet API
30000:32767 - рабочие порты по умолчанию для подключения к подам (NodePort Services)
И наш кластер готов. В следующий раз опишу, как можно работать с данным кластером и как пользоваться k8s
Анонсы и еще больше информации в Telegram-канале