Установка kubernetes с тремя мастерами и "плавающим" IP-мастера
1) Предварительное условие
Перед установкой кластера kubernetes необходимо иметь:
- как минимум три сервера, на которых установлен Ubuntu Server 22.04
- свободный в сети IP-адрес (нужно чтобы его ни кто в сети больше не занял - он будет использоваться для плавающего IP-адреса)
- все мастера ДОЛЖНЫ лежать в одной подсети, иначе плавающий IP-адрес реализовать логически невозможно
- доступ ко всем этим серверам по ssh-протоколу
- (необязательно) настроен вход на эти сервера по ключу (это нужно чтобы не вводить постоянно пароли при входе на сервера)
- доступ к пользователю root на всех этих серверах. Мы будем пользоваться командой sudo
- каждый сервер должен иметь доступ в интернет напрямую (доступ через прокси не подойдёт)
2) Предварительное описание
Кластер будет устанавливаться с плавающим IP-адресом - это значит, что к одному мастеру из трёх будет прикреплён плавающий IP-адрес, и он будет доступен по этому адресу. И если это мастер упадёт, то IP-адрес автоматически подключиться к другому работающему мастеру. Это позволит системам управления кластером kubernetes не менять конфигурации доступа при падении активного мастера, делая систему более устойчивой.
В данном руководстве будут использоваться следующие сервера:
IP-сервера | Назначение | Название хоста в ssh |
---|---|---|
192.168.17.137 | плавающий IP-адрес | |
192.168.17.131 | первый мастер | master1 |
192.168.17.132 | второй мастер | master2 |
192.168.17.133 | третий мастер | master3 |
192.168.17.134 | первый рабочий | worker4 |
192.168.17.135 | второй рабочий | worker5 |
192.168.17.136 | третий рабочий | worker6 |
Рабочих серверов может быть больше, тогда вы должны повторять все операции на них как на этих рабочих серверах.
Если в руководстве будет команда:
ssh master2
То это обозначает, что нужно присоединиться к соответствующему серверу. Если у вас он назван иначе, то не забудьте в команде поправить имя сервера на такое, какое используется у вас. Гораздо лучше будет, если вы имена серверов сделаете точно такими же как и в этом руководстве. Тогда вы будете просто копировать команды из этого руководства в консоль и запускать их без каки-либо изменений. Для этого в ssh используется конфигурационный файл. Он находится по пути:
~/.ssh/config
Вот как настроен файл примера данного руководства:
Host master1
Hostname 192.168.17.131
Port 22
User greetgo
IdentitiesOnly=yes
Host master2
Hostname 192.168.17.132
Port 22
User greetgo
IdentitiesOnly=yes
Host master3
Hostname 192.168.17.133
Port 22
User greetgo
IdentitiesOnly=yes
Host worker4
Hostname 192.168.17.134
Port 22
User greetgo
IdentitiesOnly=yes
Host worker5
Hostname 192.168.17.135
Port 22
User greetgo
IdentitiesOnly=yes
Host worker6
Hostname 192.168.17.136
Port 22
User greetgo
IdentitiesOnly=yes
Вам тут нужно поменять IP-адреса на свои.
Так же желательно сделать доступ к серверам по ключу. Для этого необходимо сгенерировать ключ с помощью команды:
ssh-keygen -t ed25519
Эта команда сгенерирует два файла:
~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub
Файл: id_ed25519 - приватный ключ, а файл: id_ed25519.pub - публичный ключ.
ВНИМАНИЕ!!!: НИКОГДА приватный ключ (~/.ssh/id_ed25519) НИ КОМУ не давайте и не показывайте. Показывать можно ТОЛЬКО публичный ключ.
А потом выполнить команды:
ssh-copy-id master1
ssh-copy-id master2
ssh-copy-id master3
ssh-copy-id worker4
ssh-copy-id worker5
ssh-copy-id worker6
Команды потребуют ввести пароль доступа к соответствующему серверу.
Если администратор не предоставил вам пароль доступа, попросите его прописать содержимое следующего файла с вашего компьютера:
~/.ssh/id_ed25519.pub
В конец файла:
~/.ssh/authorized_keys
На всех серверах masterN и workerN
Проверить выполнение можно командой:
ssh master1 ls
Если всё нормально, то она покажет содержимое удалённой домашней папки. Тоже должно быть и для остальных серверов.
3) Проверка серверов на соответствие условий использования kubernetes
3.1) Проверьте уникальности MAC-адреса
Узнать MAC-адрес сервера, можно командой
ip link
Например, команда выведет
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default
qlen 1000
link/ether 08:00:27:48:0e:3d brd ff:ff:ff:ff:ff:ff
Значит MAC-адрес данного сервера - 08:00:27:48:0e:3d
Убедитесь, чтобы на всех серверах это значение было уникальным.
3.1) Проверьте уникальности product_uuid
Узнать product_uuid сервера, можно командой
sudo cat /sys/class/dmi/id/product_uuid
Убедитесь, чтобы на всех серверах это значение было уникальным.
4) Настройка серверов
В этом параграфе будут описаны действия для одного сервера. Вам нужно будет повторить их для всех серверов.
Зайдите на один сервер, например:
ssh master1
Далее будут команды для данного сервера. Не забудьте менять IP-адреса там, где они будут встречаться на соответствующе. Хорошей практикой будет скопировать данное руководство себе на диск и заменить в нём IP-адреса на ваши и далее напрямую копировать команды без какой-либо корректировки.
4.1) Называем сервер
Заходим на сервер:
ssh master1
Устанавливаем имя хоста:
sudo hostnamectl set-hostname master1
Выходим из сервера
exit
И заходим заново - в приглашении должно появиться имя хоста, примерно так:
greetgo@master1:~$
Далее в пунктах 4.xx все команды будут внутри этого хоста
4.2) Устанавливаем необходимый набор инструментов
sudo apt install -y mc less htop iputils-ping netcat lsof telnet
4.3) Отключаем файл подкачки (swap)
Запускаем команду
sudo swapoff -a
Далее открываем файл на редактирование
sudo mcedit /etc/fstab
В нём комментируем строку активации файла подкачки
#/swap.img none swap sw 0 0
Ставим # впереди этой строки. Сохраняем и выходим.
4.4) Устанавливаем containerd
4.4.1) Активируем модули ядра overlay и br_netfilter
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
Проверяем, что эти модули активировались.
lsmod | grep br_netfilter
lsmod | grep overlay
Желательно эту проверку сделать после перезагрузки, чтобы убедиться, что модули активируются на старте операционной системы.
4.4.2) Активируем проталкивание пакетов между интерфейсами (forwarding)
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
Проверить удачность этой активации можно командой:
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
Должно вылететь такое:
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
Единичка обозначает что данная опция активирована в системе. Желательно эту проверку сделать после перезагрузки операционной системы, чтобы убедиться, что опции активируются на старте.
4.4.3) Создаём директорию dist в домашней папке и переходим в неё
mkdir ~/dist
cd ~/dist
4.4.3) На странице:
https://github.com/containerd/containerd/releases
Находим Latest версию пакета.
ВНИМАНИЕ! Pre-Release НЕ подойдёт.
Копируем ссылку на нужный файл в буфер обмена, и скачиваем его командой:
wget https://github.com/containerd/containerd/releases/download/v1.6.19/containerd-1.6.19-linux-amd64.tar.gz
В вашем случае версия пакета может быть другой. Также правильно выберите платформу - в примере это - AMD64.
Также нужно скачать контрольную сумму пакета, командой:
wget https://github.com/containerd/containerd/releases/download/v1.6.19/containerd-1.6.19-linux-amd64.
tar.gz.sha256sum
Сравниваем контрольные суммы:
user@master0:~/dist$ cat containerd-1.6.19-linux-amd64.tar.gz.sha256sum
3262454d9b3581f4d4da0948f77dde1be51cfc42347a1548bc9ab6870b055815 containerd-1.6.19-linux-amd64.tar.gz
user@master0:~/dist$ sha256sum containerd-1.6.19-linux-amd64.tar.gz
3262454d9b3581f4d4da0948f77dde1be51cfc42347a1548bc9ab6870b055815 containerd-1.6.19-linux-amd64.tar.gz
Они должны быть идентичны. Если так, то переходим дальше.
4.4.4) Распаковываем архив с программой, командой:
tar xvf containerd-1.6.19-linux-amd64.tar.gz
И устанавливаем распакованные файлы командой:
sudo cp bin/* /usr/local/bin/
Убеждаемся, что в директории /usr/local/bin/ есть нужные файлы:
user@master0:~/dist$ ls -lhF /usr/local/bin/
total 123M
-rwxr-xr-x 1 root root 50M Mar 10 02:09 containerd*
-rwxr-xr-x 1 root root 7.1M Mar 10 02:09 containerd-shim*
-rwxr-xr-x 1 root root 9.1M Mar 10 02:09 containerd-shim-runc-v1*
-rwxr-xr-x 1 root root 9.1M Mar 10 02:09 containerd-shim-runc-v2*
-rwxr-xr-x 1 root root 22M Mar 10 02:09 containerd-stress*
-rwxr-xr-x 1 root root 26M Mar 10 02:09 ctr*
4.4.5) Настраиваем сервис на systemd, для этого скачиваем файл:
wget https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
И копируем его в нужное место:
sudo mkdir -p /usr/local/lib/systemd/system/
sudo cp containerd.service /usr/local/lib/systemd/system/containerd.service
И теперь регистрируем его в подсистеме-systemd:
sudo systemctl daemon-reload
sudo systemctl enable --now containerd
Проверить работу сервиса можно командой:
sudo systemctl status containerd
Вылететь должно что-то типа такого:
● containerd.service - containerd container runtime
Loaded: loaded (/usr/local/lib/systemd/system/containerd.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2023-03-10 02:16:37 UTC; 34s ago
Docs: https://containerd.io
Process: 1747 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 1748 (containerd)
Tasks: 10
Memory: 13.3M
CPU: 84ms
CGroup: /system.slice/containerd.service
└─1748 /usr/local/bin/containerd
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.662835442Z" level=info msg="Start
subscribing containerd event"
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.662939745Z" level=info msg="Start
recovering state"
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.662979488Z" level=info msg=serving...
address=/run/containerd/containerd.sock.ttrpc
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.663051181Z" level=info msg="Start
event monitor"
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.663052062Z" level=info msg=serving...
address=/run/containerd/containerd.sock
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.663081096Z" level=info msg="Start
snapshots syncer"
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.663121801Z" level=info msg="Start cni
network conf syncer for default"
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.663157858Z" level=info msg="containerd
successfully booted in 0.052843s"
Mar 10 02:16:37 master0 systemd[1]: Started containerd container runtime.
Mar 10 02:16:37 master0 containerd[1748]: time="2023-03-10T02:16:37.663132982Z" level=info msg="Start
streaming server"
Тут во третей строчке видно, что сервис активирован и работает.
4.5) Устанавливаем runc
Заходим на страницу
https://github.com/opencontainers/runc/releases
Копируем ссылку на исполняемый файл runc.
wget https://github.com/opencontainers/runc/releases/download/v1.1.4/runc.amd64
Далее устанавливаем команду runc в систему с помощью команды:
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
Убеждаемся, что команда установлена:
runc --version
Должно вылететь что-то типа:
runc version 1.1.4
commit: v1.1.4-0-g5fd4c4d1
spec: 1.0.2-dev
go: go1.17.10
libseccomp: 2.5.4
4.6) Устанавливаем плагины CNI
Заходим на страницу
https://github.com/containernetworking/plugins/releases
Копируем ссылку на архив с плагинами, и на сервере скачиваем архив командой:
wget https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins-linux-amd64-v1.2.0.tgz
Незабываем проверять контрольную сумму:
wget https://github.com/containernetworking/plugins/releases/download/v1.2.0/cni-plugins-linux-amd64-v1.2.0.
tgz.sha1
И далее:
user@master1:~/dist$ cat cni-plugins-linux-amd64-v1.2.0.tgz.sha1
eafd7e12dfa9457e40c36100f32336bcc293b21f cni-plugins-linux-amd64-v1.2.0.tgz
user@master1:~/dist$ sha1sum cni-plugins-linux-amd64-v1.2.0.tgz
eafd7e12dfa9457e40c36100f32336bcc293b21f cni-plugins-linux-amd64-v1.2.0.tgz
Плагины нужно поместить в директорию /opt/cni/bin командами
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.2.0.tgz
4.7) Генерируем и настраиваем конфигурацию для containerd
Запускаем команду для настройки сервиса:
sudo systemctl edit containerd
В открывшемся редакторе добавляем строки
[Service]
LimitMEMLOCK=infinity
Примечание: строку "[Service]" можно раскомментировать и ниже неё добавить "LimitMEMLOCK=infinity"
Сгенерируем конфигурационный файл по-умолчанию, выполнив команду:
sudo mkdir -p /etc/containerd/
containerd config default | sudo tee /etc/containerd/config.toml
Откроем полученный файл на редактирование
sudo mcedit -b /etc/containerd/config.toml
И активируем в нём SystemD для CGroups установив true в соответствующее место:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
Нужно перезапустить containerd чтобы новая конфигурация вступила в силу:
sudo systemctl daemon-reload && sudo systemctl restart containerd
4.8) Устанавливаем kubeadm, kubectl и kubelet
Устанавливаем необходимые пакеты:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
Скачиваем Google Cloud public signing key:
sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc
/apt-key.gpg
Добавляем репозиторий для Kubernetes в подсистему пакетов apt:
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/
kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
Обновляем подсистему пакетов, чтобы активировать только что добавленный репозиторий:
sudo apt-get update
И теперь устанавливаем целевые программы из только что добавленного репозитория:
sudo apt-get install -y kubelet kubeadm kubectl
Теперь нужно зафиксировать текущие версии пакетов, чтобы в дальнейшем они не обновлялись, при обновлении операционной системы - это может привести к блокированию доступа к кластеру kubernetes, для этого выполним команду:
sudo apt-mark hold kubelet kubeadm kubectl
Теперь проверим, всё ли установилось:
kubeadm version
Вылетит что то типа такого:
kubeadm version: &version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.2",
GitCommit:"fc04e732bb3e7198d2fa44efa5457c7c6f8c0f5b", GitTreeState:"clean", BuildDate:"2023-02-22T13:37:39Z",
GoVersion:"go1.19.6", Compiler:"gc", Platform:"linux/amd64"}
Запомним версию kubernetes - v1.26.2 - далее она будет использоваться. У вас она может быть более новой - в дальнейшем вам необходимо будет ставить свою версию везде, где используется эта.
Проверим другие команды:
kubectl version -o yaml
Вылетит что-то типа такого:
clientVersion:
buildDate: "2023-02-22T13:39:03Z"
compiler: gc
gitCommit: fc04e732bb3e7198d2fa44efa5457c7c6f8c0f5b
gitTreeState: clean
gitVersion: v1.26.2
goVersion: go1.19.6
major: "1"
minor: "26"
platform: linux/amd64
kustomizeVersion: v4.5.7
The connection to the server localhost:8080 was refused - did you specify the right host or port?
То, что он не смог соединиться к localhost:8080 - это нормально, так как кластера ещё нет.
Примечание
Проделываем инструкции из пункта 4 на всех серверах будущего кластера.
В продолжении будет описан процесс непосредственной установки кластера Kubernetes: продолжение