oakazanin/content/posts/k3s-part2-infrastructure/index.md

21 KiB
Raw Blame History

title date draft description tags categories series series_order
K3s HA для homelab: Готовим инфраструктуру в Proxmox 2025-10-21 false Готовим инфраструктуру для K3s в Proxmox: 5 VM с Debian 12, настройка сети, отключение swap. Пошаговая инструкция без сюрпризов.
kubernetes
k3s
homelab
proxmox
infrastructure
debian
devops
Kubernetes
Homelab
K3s HA кластер для homelab
2

Архитектура спланирована, ресурсы посчитаны - пора создавать виртуальные машины. В этой статье подготовим 5 VM в Proxmox и настроим ОС так, чтобы K3s установился без сюрпризов.

Звучит просто? В теории - да. На практике: забытый swap, cgroup v1 вместо v2, закрытые порты firewall - и вы тратите час на отладку того, что должно было работать "из коробки".

Результат: 5 VM (3 master + 2 worker) с Debian 12, настроенной сетью, отключённым swap и правильными параметрами ядра. SSH доступ работает, ноды видят друг друга.


Для кого это

Подходит:

  • Прочитал первую статью (или понимаешь архитектуру K3s HA)
  • Есть Proxmox с 14+ vCPU и 56GB+ RAM свободных
  • Умеешь работать в терминале Proxmox (или готов учиться)

Не подходит:

  • Proxmox ещё не установлен - сначала разберись с ним
  • Хочешь использовать LXC вместо VM - K3s в контейнерах работает, но с нюансами (не покрываем)

Что понадобится

Компонент Значение
Proxmox VE 7.x или 8.x
Storage pool local-lvm или другой (минимум 200GB свободно)
Сетевой bridge vmbr0 (или ваш)
SSH-ключ Публичный ключ для доступа к VM
ОС для VM Debian 12 cloud image

Шаг 1: Скачать cloud image Debian 12

Cloud image - готовый образ с поддержкой cloud-init. Не нужно проходить установщик вручную: задаёшь параметры (IP, пользователь, SSH-ключ) - VM стартует уже настроенной.

На Proxmox хосте (SSH или Shell в Web UI):

# Перейти в директорию для образов
cd /var/lib/vz/template/iso

# Скачать Debian 12 cloud image
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2

# Проверить
ls -lh debian-12-generic-amd64.qcow2

Ожидаемый результат:

-rw-r--r-- 1 root root 521M ... debian-12-generic-amd64.qcow2

Если скачивание медленное: образ ~500MB, на слабом канале может занять время. Альтернатива - скачать на локальную машину и загрузить через Proxmox Web UI (Datacenter → Storage → Upload).


Шаг 2: Создать template VM

Template - шаблон VM, из которого будем клонировать все 5 нод. Настраиваем один раз, клонируем пять.

2.1. Задать переменные

# Настрой под свою конфигурацию
TEMPLATE_ID=9000           # ID для template (любой свободный)
STORAGE=local-lvm          # Твой storage pool
BRIDGE=vmbr0               # Сетевой bridge
SSH_KEY_PATH=~/.ssh/id_rsa.pub  # Путь к публичному SSH-ключу

Как узнать имя storage:

pvesm status

Ожидаемый результат

Name             Type     Status           Total            Used       Available        %
local            dir      active       229199360         9095552       220103808    3.97%
local-lvm        pool     active       220103964              96       220103868    0.00%

2.2. Создать VM и импортировать диск

# 1. Создать пустую VM
qm create $TEMPLATE_ID \
  --name debian-12-template \
  --memory 2048 \
  --cores 2 \
  --net0 virtio,bridge=$BRIDGE

# 2. Импортировать скачанный образ как диск
qm importdisk $TEMPLATE_ID \
  /var/lib/vz/template/iso/debian-12-generic-amd64.qcow2 \
  $STORAGE

Ожидаемый результат:

importing disk '/var/lib/vz/template/iso/debian-12-generic-amd64.qcow2' to VM 9000 ...
Successfully imported disk as 'unused0:local-lvm:vm-9000-disk-0'

2.3. Настроить диск и загрузку

# 3. Подключить диск к VM
qm set $TEMPLATE_ID \
  --scsihw virtio-scsi-pci \
  --scsi0 $STORAGE:vm-$TEMPLATE_ID-disk-0

# 4. Настроить загрузку и cloud-init
qm set $TEMPLATE_ID \
  --boot c \
  --bootdisk scsi0 \
  --ide2 $STORAGE:cloudinit \
  --serial0 socket \
  --vga serial0

2.4. Настроить cloud-init

# 5. Пользователь, пароль, SSH-ключ
qm set $TEMPLATE_ID \
  --ciuser k3s \
  --cipassword "ВашНадёжныйПароль" \
  --sshkeys $SSH_KEY_PATH \
  --ipconfig0 ip=dhcp

# 6. Увеличить диск до 32GB (базовый размер для master)
qm resize $TEMPLATE_ID scsi0 32G

Замени:

  • ВашНадёжныйПароль - пароль для пользователя k3s (резервный доступ, если SSH не работает)
  • $SSH_KEY_PATH - путь к твоему публичному ключу

2.5. Превратить в template

# 7. Конвертировать VM в template
qm template $TEMPLATE_ID

После этого VM 9000 станет шаблоном - её нельзя запустить, только клонировать.

Checkpoint: Template создан

# Проверить что template существует
qm list | grep template

Ожидаемый результат:

9000 debian-12-template     stopped    2048       32.00          0

Если ошибка "disk import failed":

  • Проверь свободное место: pvesm status
  • Проверь путь к образу: ls -l /var/lib/vz/template/iso/

Шаг 3: Клонировать master ноды

Теперь создаём 3 master ноды из template. Каждая получит свой IP, имя и ресурсы.

TEMPLATE_ID=9000

# ─────────────────────────────────────────────
# Master 1
# ─────────────────────────────────────────────
qm clone $TEMPLATE_ID 201 --name k3s-master-1 --full
qm set 201 --cores 2 --memory 8192
qm set 201 --ipconfig0 ip=192.168.11.201/24,gw=192.168.11.1
qm set 201 --nameserver 8.8.8.8
qm resize 201 scsi0 32G

# ─────────────────────────────────────────────
# Master 2
# ─────────────────────────────────────────────
qm clone $TEMPLATE_ID 202 --name k3s-master-2 --full
qm set 202 --cores 2 --memory 8192
qm set 202 --ipconfig0 ip=192.168.11.202/24,gw=192.168.11.1
qm set 202 --nameserver 8.8.8.8
qm resize 202 scsi0 32G

# ─────────────────────────────────────────────
# Master 3
# ─────────────────────────────────────────────
qm clone $TEMPLATE_ID 203 --name k3s-master-3 --full
qm set 203 --cores 2 --memory 8192
qm set 203 --ipconfig0 ip=192.168.11.203/24,gw=192.168.11.1
qm set 203 --nameserver 8.8.8.8
qm resize 203 scsi0 32G

Параметры:

  • --full - полное клонирование (не linked clone), VM независима от template
  • --cores 2 --memory 8192 - 2 vCPU, 8GB RAM (как планировали)
  • --ipconfig0 - статический IP через cloud-init
  • --nameserver - DNS сервер (можешь указать свой)

Адаптируй под свою сеть:

  • 192.168.11.0/24 → твоя подсеть
  • 192.168.11.1 → твой gateway

Шаг 4: Клонировать worker ноды

Workers получают больше ресурсов - здесь будут работать приложения.

# ─────────────────────────────────────────────
# Worker 1
# ─────────────────────────────────────────────
qm clone $TEMPLATE_ID 210 --name k3s-worker-1 --full
qm set 210 --cores 4 --memory 16384
qm set 210 --ipconfig0 ip=192.168.11.210/24,gw=192.168.11.1
qm set 210 --nameserver 8.8.8.8
qm resize 210 scsi0 50G

# ─────────────────────────────────────────────
# Worker 2
# ─────────────────────────────────────────────
qm clone $TEMPLATE_ID 211 --name k3s-worker-2 --full
qm set 211 --cores 4 --memory 16384
qm set 211 --ipconfig0 ip=192.168.11.211/24,gw=192.168.11.1
qm set 211 --nameserver 8.8.8.8
qm resize 211 scsi0 50G

Отличия от master:

  • 4 vCPU вместо 2
  • 16GB RAM вместо 8GB
  • 50GB диск вместо 32GB

Шаг 5: Запустить все VM

# Запустить все 5 VM
for vmid in 201 202 203 210 211; do
  qm start $vmid
  echo "Запущена VM $vmid"
  sleep 3
done

# Проверить статус
qm list | grep k3s

Ожидаемый результат:

 201 k3s-master-1    running    8192      32.00     12345
 202 k3s-master-2    running    8192      32.00     12346
 203 k3s-master-3    running    8192      32.00     12347
 210 k3s-worker-1    running    16384     50.00     12348
 211 k3s-worker-2    running    16384     50.00     12349

Checkpoint: VM работают

Подожди 1-2 минуты (cloud-init применяет настройки при первом запуске), затем проверь SSH:

# Проверить доступность всех нод
for ip in 192.168.11.201 192.168.11.202 192.168.11.203 192.168.11.210 192.168.11.211; do
  echo -n "Проверяю $ip... "
  ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no k3s@$ip "hostname" 2>/dev/null && echo "OK" || echo "FAIL"
done

Ожидаемый результат:

Проверяю 192.168.11.201... k3s-master-1
OK
Проверяю 192.168.11.202... k3s-master-2
OK
...

Если SSH не работает:

Симптом Причина Решение
Connection refused VM не загрузилась или SSH не запущен Открой консоль в Proxmox, проверь загрузку
Connection timeout Неправильный IP или firewall Проверь IP в консоли: ip addr
Permission denied Неправильный SSH-ключ Проверь ~/.ssh/authorized_keys на VM
Host key verification failed Первое подключение Добавь -o StrictHostKeyChecking=no

Шаг 6: Подготовить ОС на всех нодах

Теперь нужно настроить каждую ноду: обновить пакеты, отключить swap, настроить ядро. Команды одинаковые для всех 5 нод.

6.1. Обновить систему

На каждой ноде (или через цикл):

# Вариант 1: по одной
ssh k3s@192.168.11.201

sudo apt update
sudo apt upgrade -y
sudo apt install -y curl wget vim htop iptables

# Вариант 2: массово (с локальной машины)
for ip in 192.168.11.{201..203} 192.168.11.{210..211}; do
  echo "=== Обновляю $ip ==="
  ssh k3s@$ip "sudo apt update && sudo apt upgrade -y && sudo apt install -y curl wget vim htop iptables"
done

6.2. Отключить swap

Kubernetes не любит swap. При включённом swap поды ведут себя непредсказуемо - OOMKiller срабатывает не тогда, когда ожидаешь.

На всех нодах:

# Отключить swap сейчас
sudo swapoff -a

# Отключить навсегда (закомментировать в fstab)
sudo sed -i '/swap/s/^/#/' /etc/fstab

# Проверить
free -h | grep Swap

Ожидаемый результат:

Swap:            0B          0B          0B

6.3. Загрузить kernel-модули

K3s использует overlay filesystem и bridge netfilter. Без этих модулей - ошибки при старте.

На всех нодах:

# Загрузить модули
sudo modprobe overlay
sudo modprobe br_netfilter

# Настроить автозагрузку
cat <<EOF | sudo tee /etc/modules-load.d/k3s.conf
overlay
br_netfilter
EOF

# Проверить
lsmod | grep -E 'overlay|br_netfilter'

Ожидаемый результат:

overlay               151552  0
br_netfilter           32768  0

6.4. Настроить sysctl

Параметры для сетевого взаимодействия между подами.

На всех нодах:

# Создать конфиг
cat <<EOF | sudo tee /etc/sysctl.d/k3s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# Применить
sudo sysctl --system

# Проверить
sysctl net.ipv4.ip_forward net.bridge.bridge-nf-call-iptables

Ожидаемый результат:

net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1

6.5. Проверить cgroup v2

Debian 12 по умолчанию использует cgroup v2 - просто проверим.

mount | grep cgroup

Ожидаемый результат (cgroup v2):

cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)

Если видишь tmpfs on /sys/fs/cgroup type tmpfs - это cgroup v1. Нужно включить v2:

# Добавить параметр ядра
sudo sed -i 's|^GRUB_CMDLINE_LINUX_DEFAULT="\(.*\)"|GRUB_CMDLINE_LINUX_DEFAULT="\1 systemd.unified_cgroup_hierarchy=1"|' /etc/default/grub

# Обновить GRUB
sudo update-grub

# Перезагрузить
sudo reboot

# После reboot проверить
mount | grep cgroup2

Шаг 7: Настроить firewall

UFW - простой интерфейс к iptables. Откроем только нужные порты.

7.1. На master нодах (201, 202, 203)

# Установить UFW
sudo apt install -y ufw

# Базовые правила
sudo ufw default deny incoming
sudo ufw default allow outgoing

# SSH (чтобы не потерять доступ)
sudo ufw allow 22/tcp

# Kubernetes API
sudo ufw allow 6443/tcp

# etcd (между masters)
sudo ufw allow 2379:2380/tcp

# Kubelet
sudo ufw allow 10250/tcp

# Flannel VXLAN
sudo ufw allow 8472/udp

# Включить
sudo ufw --force enable

# Проверить
sudo ufw status

7.2. На worker нодах (210, 211)

sudo apt install -y ufw

sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp      # SSH
sudo ufw allow 10250/tcp   # Kubelet
sudo ufw allow 8472/udp    # Flannel VXLAN

sudo ufw --force enable
sudo ufw status


Шаг 8: Настроить /etc/hosts

Не обязательно, но удобно - ноды смогут обращаться друг к другу по имени.

На всех нодах:

cat <<EOF | sudo tee -a /etc/hosts

# K3s Cluster
192.168.11.201 k3s-master-1
192.168.11.202 k3s-master-2
192.168.11.203 k3s-master-3
192.168.11.210 k3s-worker-1
192.168.11.211 k3s-worker-2
EOF

Проверить:

ping -c 1 k3s-master-2

Финальная проверка

Перед переходом к установке K3s убедись, что всё готово. Запусти на любой ноде:

echo "=== Проверка готовности ноды ==="

echo -n "1. Swap отключён: "
[ $(free | grep Swap | awk '{print $2}') -eq 0 ] && echo "✓" || echo "✗ ОШИБКА"

echo -n "2. Модуль overlay: "
lsmod | grep -q overlay && echo "✓" || echo "✗ ОШИБКА"

echo -n "3. Модуль br_netfilter: "
lsmod | grep -q br_netfilter && echo "✓" || echo "✗ ОШИБКА"

echo -n "4. IP forwarding: "
[ $(sysctl -n net.ipv4.ip_forward) -eq 1 ] && echo "✓" || echo "✗ ОШИБКА"

echo -n "5. bridge-nf-call-iptables: "
[ $(sysctl -n net.bridge.bridge-nf-call-iptables) -eq 1 ] && echo "✓" || echo "✗ ОШИБКА"

echo -n "6. cgroup v2: "
mount | grep -q "cgroup2" && echo "✓" || echo "✗ ОШИБКА"

echo -n "7. UFW активен: "
sudo ufw status | grep -q "Status: active" && echo "✓" || echo "✗ ОШИБКА"

echo -n "8. Пинг k3s-master-1: "
ping -c 1 -W 1 k3s-master-1 >/dev/null 2>&1 && echo "✓" || echo "✗ ОШИБКА"

Ожидаемый результат:

=== Проверка готовности ноды ===
1. Swap отключён: ✓
2. Модуль overlay: ✓
3. Модуль br_netfilter: ✓
4. IP forwarding: ✓
5. bridge-nf-call-iptables: ✓
6. cgroup v2: ✓
7. UFW активен: ✓
8. Пинг k3s-master-1: ✓

Если где-то ✗ - вернись к соответствующему шагу.


Troubleshooting

Симптом Причина Решение
VM не получает IP cloud-init не отработал Проверь консоль, жди 2-3 минуты, перезагрузи VM
SSH connection refused sshd не запущен Открой консоль, проверь systemctl status ssh
Swap не отключается Строка не закомментирована в fstab cat /etc/fstab, проверь swap строку, reboot
cgroup v1 после reboot GRUB не обновился Проверь /proc/cmdline, повтори update-grub
UFW блокирует всё Забыл разрешить SSH до включения Через консоль Proxmox: ufw allow 22/tcp
Ноды не пингуются UFW или неправильный IP Проверь ip addr, проверь правила UFW

Итог

Что сделано:

  • Скачан Debian 12 cloud image
  • Создан template VM с cloud-init
  • Склонированы 5 VM (3 master + 2 worker)
  • Настроены статические IP
  • Подготовлена ОС (swap, modules, sysctl, cgroup v2)
  • Настроен firewall с нужными портами
  • SSH работает на все ноды

Что дальше:

👉 Следующая статья: "Установить K3s HA кластер"

Там мы:

  • Сгенерируем token для кластера
  • Установим K3s на первую master ноду
  • Добавим ещё 2 master ноды (HA)
  • Подключим worker ноды
  • Настроим kubectl
  • Проверим работу кластера