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

618 lines
21 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "K3s HA для homelab: Готовим инфраструктуру в Proxmox"
date: 2025-10-21
draft: false
description: "Готовим инфраструктуру для K3s в Proxmox: 5 VM с Debian 12, настройка сети, отключение swap. Пошаговая инструкция без сюрпризов."
tags: ["kubernetes", "k3s", "homelab", "proxmox", "infrastructure", "debian", "devops"]
categories: ["Kubernetes", "Homelab"]
series: ["K3s HA кластер для homelab"]
series_order: 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):**
```bash
# Перейти в директорию для образов
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
```
<!-- СКРИНШОТ: Терминал Proxmox с выводом wget и ls -lh, показывающим скачанный образ ~500MB -->
**Если скачивание медленное:** образ ~500MB, на слабом канале может занять время. Альтернатива - скачать на локальную машину и загрузить через Proxmox Web UI (Datacenter → Storage → Upload).
---
## Шаг 2: Создать template VM
Template - шаблон VM, из которого будем клонировать все 5 нод. Настраиваем один раз, клонируем пять.
### 2.1. Задать переменные
```bash
# Настрой под свою конфигурацию
TEMPLATE_ID=9000 # ID для template (любой свободный)
STORAGE=local-lvm # Твой storage pool
BRIDGE=vmbr0 # Сетевой bridge
SSH_KEY_PATH=~/.ssh/id_rsa.pub # Путь к публичному SSH-ключу
```
**Как узнать имя storage:**
```bash
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%
```
<!-- СКРИНШОТ: Вывод pvesm status с выделенным именем storage pool (например, local-lvm) -->
### 2.2. Создать VM и импортировать диск
```bash
# 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. Настроить диск и загрузку
```bash
# 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
```bash
# 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
```bash
# 7. Конвертировать VM в template
qm template $TEMPLATE_ID
```
После этого VM 9000 станет шаблоном - её нельзя запустить, только клонировать.
<!-- СКРИНШОТ: Proxmox Web UI - список VM, где debian-12-template отображается с иконкой template (отличается от обычных VM) -->
### Checkpoint: Template создан
```bash
# Проверить что 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, имя и ресурсы.
```bash
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 получают больше ресурсов - здесь будут работать приложения.
```bash
# ─────────────────────────────────────────────
# 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
```bash
# Запустить все 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
```
<!-- СКРИНШОТ: Proxmox Web UI - Summary или список VM, все 5 нод в статусе "running" с правильными ресурсами -->
### Checkpoint: VM работают
Подожди 1-2 минуты (cloud-init применяет настройки при первом запуске), затем проверь SSH:
```bash
# Проверить доступность всех нод
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` |
<!-- СКРИНШОТ: Proxmox Console для одной из VM - экран входа или вывод `ip addr show` с правильным IP -->
---
## Шаг 6: Подготовить ОС на всех нодах
Теперь нужно настроить каждую ноду: обновить пакеты, отключить swap, настроить ядро. Команды одинаковые для всех 5 нод.
### 6.1. Обновить систему
**На каждой ноде (или через цикл):**
```bash
# Вариант 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 срабатывает не тогда, когда ожидаешь.
**На всех нодах:**
```bash
# Отключить 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. Без этих модулей - ошибки при старте.
**На всех нодах:**
```bash
# Загрузить модули
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
Параметры для сетевого взаимодействия между подами.
**На всех нодах:**
```bash
# Создать конфиг
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 - просто проверим.
```bash
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:
```bash
# Добавить параметр ядра
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)
```bash
# Установить 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)
```bash
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
```
![](mermaid-diagram.svg)
---
## Шаг 8: Настроить /etc/hosts
Не обязательно, но удобно - ноды смогут обращаться друг к другу по имени.
**На всех нодах:**
```bash
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
```
Проверить:
```bash
ping -c 1 k3s-master-2
```
---
## Финальная проверка
Перед переходом к установке K3s убедись, что всё готово. Запусти на любой ноде:
```bash
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
- Проверим работу кластера