Настроил. Добавил серию статей о K3S Cluster
@@ -1,13 +0,0 @@
|
||||
---
|
||||
title: "Hello World"
|
||||
date: 2026-02-13
|
||||
draft: false
|
||||
description: "Первый пост на новом сайте"
|
||||
tags: ["test"]
|
||||
---
|
||||
|
||||
## Привет!
|
||||
|
||||
Это первый пост на новом сайте **oakazanin.ru**.
|
||||
|
||||
Сайт работает на Hugo + Blowfish теме.
|
||||
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 663 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,374 @@
|
||||
---
|
||||
title: "K3s HA для homelab: архитектура без боли"
|
||||
date: 2025-10-14
|
||||
draft: false
|
||||
description: "Полноценный Kubernetes в бинарнике на 50MB вместо 1.5GB зависимостей. Разбираем архитектуру K3s HA кластера: почему именно 3 master ноды, зачем embedded etcd и сколько ресурсов закладывать."
|
||||
summary: "Kubernetes слишком тяжёлый, Docker Swarm мёртв, а хочется нормальный кластер для экспериментов. K3s решает эту проблему - полноценный Kubernetes в 50MB. Разберём архитектуру HA кластера без боли."
|
||||
tags: ["kubernetes", "k3s", "homelab", "proxmox", "architecture", "ha", "devops"]
|
||||
series: ["K3s HA кластер для homelab"]
|
||||
series_order: 1
|
||||
# seriesOpened: false
|
||||
# showTableOfContents: true
|
||||
showAuthor: true
|
||||
---
|
||||
|
||||
Kubernetes слишком тяжёлый, Docker Swarm мёртв, а хочется нормальный кластер для экспериментов. Знакомо? K3s решает эту проблему - полноценный Kubernetes в бинарнике на 50MB вместо 1.5GB зависимостей. Но без правильного планирования вы получите нестабильную конструкцию, которая падает в самый неподходящий момент.
|
||||
|
||||
В этой статье разберём архитектуру K3s HA кластера: почему именно 3 master ноды, зачем embedded etcd и сколько ресурсов закладывать. В конце - готовый план для установки.
|
||||
|
||||
**Результат:** понимание архитектуры + таблица ресурсов + сетевая схема. Всё, что нужно перед тем, как создавать VM.
|
||||
|
||||
---
|
||||
|
||||
## Для кого это
|
||||
|
||||
**Подходит:**
|
||||
- Знаком с базовыми концепциями Kubernetes (pod, service, deployment)
|
||||
- Есть Proxmox с 14+ vCPU и 56GB+ RAM
|
||||
- Хочешь понять *что* устанавливать, прежде чем устанавливать
|
||||
|
||||
**Не подходит:**
|
||||
- Нужна одна нода для экспериментов - достаточно docker-compose или K3s single-node
|
||||
- Ищешь managed Kubernetes для бизнеса - смотри в сторону Yandex Cloud или VK Cloud
|
||||
- Хочешь сразу команды без теории - переходи к статье 2
|
||||
|
||||
---
|
||||
|
||||
## K3s vs Kubernetes: в чём разница
|
||||
|
||||
**Kubernetes (K8s)** - оркестратор контейнеров, стандарт индустрии. Добро пожаловать в enterprise, где для запуска трёх контейнеров нужно поддерживать шесть виртуальных машин.
|
||||
|
||||
**K3s** - тот же Kubernetes, но кто-то в Rancher (теперь SUSE) задумался: "А что если выкинуть всё, что нужно только Сберу и Yandex Cloud?"
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
**Что выкинули:**
|
||||
|
||||
- Интеграции с облачными провайдерами (вы же не в VK Cloud)
|
||||
- Legacy API (вы же не мигрируете кластер 2016 года)
|
||||
- Встроенные драйверы хранилищ на все случаи жизни (вы же не используете 47 типов СХД)
|
||||
- Альфа/бета-функции (нестабильные эксперименты)
|
||||
|
||||
**Что осталось:** полноценный Kubernetes, сертифицированный CNCF (Cloud Native Computing Foundation - организация, которая решает, что считать "настоящим" Kubernetes). Все манифесты работают. Helm работает. kubectl работает. Ответы со StackOverflow работают.
|
||||
|
||||
### Сравнение в цифрах
|
||||
|
||||
| Характеристика | Kubernetes | K3s |
|
||||
|----------------|------------|-----|
|
||||
| Размер | ~1.5GB образы | 50MB бинарник |
|
||||
| RAM на control plane | ~2GB на ноду | ~500MB на ноду |
|
||||
| Установка | kubeadm, 10+ шагов | один curl-скрипт |
|
||||
| etcd | Отдельный кластер (3+ VM) | Встроенный |
|
||||
| CNI | Нужно устанавливать | Flannel из коробки |
|
||||
| Совместимость | 100% | 100% |
|
||||
|
||||
*"Но я потеряю гибкость!"* - скажете вы. Да, вы не сможете заменить сетевой плагин Flannel без пересборки. Это критично примерно для одного проекта из тысячи, и ваш homelab в их число не входит.
|
||||
|
||||
**Вердикт:** для homelab K3s - очевидный выбор. Теряем 5% гибкости, получаем 90% простоты.
|
||||
|
||||
---
|
||||
|
||||
## Что такое High Availability и зачем оно вам
|
||||
|
||||
**HA (High Availability)** - способность системы продолжать работу при отказе компонентов. Звучит как enterprise-термин для больших компаний? На практике это разница между "кластер упал в субботу, но я починил в понедельник" и "кластер сам пережил падение ноды, пока я спал".
|
||||
|
||||
### Без HA (single node)
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ K3s Master │ ← Единственная точка отказа
|
||||
│ + Worker │
|
||||
└─────────────────┘
|
||||
|
||||
Нода упала → кластер мёртв → ваши сервисы недоступны
|
||||
```
|
||||
|
||||
### С HA (3+ master nodes)
|
||||
|
||||
```
|
||||
┌──────────┐ ┌──────────┐ ┌──────────┐
|
||||
│ Master 1 │ │ Master 2 │ │ Master 3 │
|
||||
│ + etcd │ │ + etcd │ │ + etcd │
|
||||
└──────────┘ └──────────┘ └──────────┘
|
||||
↓ ↓ ↓
|
||||
┌──────────┐ ┌──────────┐
|
||||
│ Worker 1 │ │ Worker 2 │
|
||||
└──────────┘ └──────────┘
|
||||
|
||||
Одна master упала → кластер работает
|
||||
Один worker упал → поды переехали на другой
|
||||
```
|
||||
|
||||
### Сколько master нод нужно
|
||||
|
||||
Вот тут начинается интересное. Интуиция подсказывает: одна нода - плохо, две - уже лучше. Логично? Логично. И неправильно.
|
||||
|
||||
| Master нод | Выдержит отказов | Кворум | Вердикт |
|
||||
|------------|------------------|--------|---------|
|
||||
| 1 | 0 | 1/1 | Нет HA, но честно |
|
||||
| 2 | 0 | **Ловушка!** | ⛔ Хуже, чем 1 |
|
||||
| 3 | 1 | 2/3 | ✅ Минимум для HA |
|
||||
| 5 | 2 | 3/5 | Для критичных систем |
|
||||
|
||||
### Почему 2 master ноды хуже, чем 1
|
||||
|
||||
etcd (база данных кластера, где хранится вообще всё) работает по принципу голосования. Чтобы записать данные, нужно согласие большинства нод. Не "хотя бы одной" - именно большинства.
|
||||
|
||||
Считаем:
|
||||
|
||||
- **1 нода:** большинство = 1. Упала - кластер мёртв. Честная игра, вы знали на что шли.
|
||||
- **2 ноды:** большинство = 2. Упала одна - кворума нет, кластер мёртв. Сюрприз!
|
||||
- **3 ноды:** большинство = 2. Одна упала - две оставшиеся продолжают работать.
|
||||
|
||||
Это как договор, требующий подписи обоих директоров - заболел один, и компания парализована.
|
||||
|
||||
С двумя нодами вы не получили отказоустойчивость. Вы удвоили количество точек отказа и назвали это "высокой доступностью".
|
||||
|
||||

|
||||
|
||||
**Правило:** или 1 нода (и честное понимание рисков), или 3+ (и настоящий HA). Двойка - ловушка для тех, кто не дочитал документацию.
|
||||
|
||||
---
|
||||
|
||||
## Embedded etcd vs External etcd
|
||||
|
||||
**etcd** - распределённое key-value хранилище. Единственный источник истины для всего состояния Kubernetes: все объекты (поды, сервисы, секреты), конфигурации, сетевые политики. Без etcd кластер не работает. Точка.
|
||||
|
||||
Есть два варианта архитектуры:
|
||||
|
||||
### External etcd (классический Kubernetes)
|
||||
|
||||
```
|
||||
Control Plane (3 VM) etcd кластер (3 VM)
|
||||
┌────────────────┐ ┌──────────────┐
|
||||
│ API Server │ │ etcd-1 │
|
||||
│ Scheduler │ ──────────────>│ (только etcd)│
|
||||
│ Controller │ └──────────────┘
|
||||
└────────────────┘ ┌──────────────┐
|
||||
┌────────────────┐ │ etcd-2 │
|
||||
│ API Server │ ──────────────>│ (только etcd)│
|
||||
│ Scheduler │ └──────────────┘
|
||||
│ Controller │ ┌──────────────┐
|
||||
└────────────────┘ │ etcd-3 │
|
||||
┌────────────────┐ │ (только etcd)│
|
||||
│ API Server │ ──────────────>└──────────────┘
|
||||
│ Scheduler │
|
||||
│ Controller │
|
||||
└────────────────┘
|
||||
|
||||
Итого: 6 виртуальных машин
|
||||
```
|
||||
|
||||
### Embedded etcd (K3s)
|
||||
|
||||
```
|
||||
┌─────────────────────────┐
|
||||
│ K3s Master 1 │
|
||||
│ ┌───────────────────┐ │
|
||||
│ │ API + Scheduler │ │
|
||||
│ │ + Controller │ │
|
||||
│ └───────────────────┘ │
|
||||
│ ┌───────────────────┐ │
|
||||
│ │ etcd (встроенный) │◄─┼──┐
|
||||
│ └───────────────────┘ │ │
|
||||
└─────────────────────────┘ │ Raft protocol
|
||||
┌─────────────────────────┐ │ (синхронизация)
|
||||
│ K3s Master 2 │ │
|
||||
│ etcd ◄────────────────────┤
|
||||
└─────────────────────────┘ │
|
||||
┌─────────────────────────┐ │
|
||||
│ K3s Master 3 │ │
|
||||
│ etcd ◄────────────────────┘
|
||||
└─────────────────────────┘
|
||||
|
||||
Итого: 3 виртуальные машины
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Сравнение подходов
|
||||
|
||||
| Критерий | External etcd | Embedded etcd |
|
||||
|----------|---------------|---------------|
|
||||
| Количество VM | 6 (3 master + 3 etcd) | 3 (всё вместе) |
|
||||
| Сложность настройки | Высокая | Один флаг `--cluster-init` |
|
||||
| Сложность обновления | Отдельно etcd и K8s | Одна команда |
|
||||
| Производительность | Чуть лучше | Достаточно для homelab |
|
||||
| Масштаб | >500 нод | До 100-200 нод |
|
||||
|
||||
**Для homelab embedded etcd - очевидный выбор.** Теряем 5-10% производительности etcd, экономим 3 VM и часы настройки.
|
||||
|
||||
*"А если мне понадобится масштаб?"* - официально embedded etcd поддерживает до 100 нод и 5000 подов. Для homelab это как ограничение скорости 300 км/ч на велосипеде.
|
||||
|
||||
---
|
||||
|
||||
## Зачем отдельные worker ноды
|
||||
|
||||
**Worker ноды** - машины для запуска ваших приложений (подов). На них не запускаются компоненты control plane.
|
||||
|
||||
*"А можно запускать приложения прямо на master нодах?"*
|
||||
|
||||
Технически - да. K3s не ставит ограничений на master ноды (в отличие от обычного Kubernetes). Но это плохая идея:
|
||||
|
||||
- **Control plane должен быть стабильным.** Ваше приложение съело всю память → API server упал → кластер недоступен.
|
||||
- **etcd чувствителен к диску.** База данных на той же ноде создаёт I/O нагрузку → etcd тормозит → весь кластер тормозит.
|
||||
- **Изоляция отказов.** Проблема с приложением не должна убивать control plane.
|
||||
|
||||
**2 worker ноды - минимум для HA приложений:**
|
||||
- Можно запускать 2 реплики (на разных нодах)
|
||||
- При падении одного worker'а второй держит нагрузку
|
||||
- Легко добавить третью, четвёртую ноду потом
|
||||
|
||||
---
|
||||
|
||||
## Архитектура нашего кластера
|
||||
|
||||
Вот что мы будем строить:
|
||||
|
||||

|
||||
|
||||
**Ключевые моменты:**
|
||||
|
||||
1. **Все master ноды равны** - нет "главной", kubectl подключается к любой.
|
||||
2. **etcd синхронизируется через Raft** - алгоритм консенсуса, гарантирует согласованность данных.
|
||||
3. **Workers знают только про API** - они не подключаются к etcd напрямую.
|
||||
4. **Flannel создаёт overlay-сеть** - все поды получают IP из 10.42.0.0/16, видят друг друга.
|
||||
|
||||
---
|
||||
|
||||
## Планирование ресурсов
|
||||
|
||||
### Таблица VM
|
||||
|
||||
| Hostname | VM ID | IP | vCPU | RAM | Disk | Роль |
|
||||
|----------|-------|------------|------|-----|------|------|
|
||||
| k3s-master-1 | 201 | 192.168.11.201 | 2 | 8GB | 32GB | Control Plane + etcd |
|
||||
| k3s-master-2 | 202 | 192.168.11.202 | 2 | 8GB | 32GB | Control Plane + etcd |
|
||||
| k3s-master-3 | 203 | 192.168.11.203 | 2 | 8GB | 32GB | Control Plane + etcd |
|
||||
| k3s-worker-1 | 210 | 192.168.11.210 | 4 | 16GB | 50GB | Workloads |
|
||||
| k3s-worker-2 | 211 | 192.168.11.211 | 4 | 16GB | 50GB | Workloads |
|
||||
| **Итого** | - | - | **14** | **56GB** | **196GB** | - |
|
||||
|
||||
### Почему именно такие ресурсы
|
||||
|
||||
**Master ноды (2 vCPU / 8GB RAM / 32GB Disk):**
|
||||
|
||||
Реальное потребление в idle:
|
||||
- API server: ~200-300MB RAM
|
||||
- etcd: ~100-200MB RAM (растёт со временем)
|
||||
- Scheduler + Controller: ~150MB RAM
|
||||
- Системные поды: ~100-200MB RAM
|
||||
- **Итого:** ~600-900MB используется
|
||||
|
||||
*"Зачем тогда 8GB?"* - запас для burst-нагрузки. Когда вы деплоите 50 подов одновременно, API server временно съедает больше. etcd при большом кластере может вырасти до 1-2GB. Golang GC работает лучше с запасом памяти.
|
||||
|
||||
**Worker ноды (4 vCPU / 16GB RAM / 50GB Disk):**
|
||||
|
||||
Здесь будут ваши приложения. При 16GB можно запустить:
|
||||
- 5-10 средних приложений (256MB-2GB каждое)
|
||||
- Или 2-3 базы данных (PostgreSQL любит память)
|
||||
- Или комбинацию
|
||||
|
||||
50GB диска - под образы контейнеров (10-20GB), логи (5-10GB), временные данные.
|
||||
|
||||
### Можно ли меньше?
|
||||
|
||||
**Минимальная конфигурация (для экспериментов):**
|
||||
- Master: 1 vCPU / 4GB RAM / 20GB Disk
|
||||
- Worker: 2 vCPU / 8GB RAM / 30GB Disk
|
||||
- **Итого:** 9 vCPU / 36GB RAM
|
||||
|
||||
**Риски:**
|
||||
- Медленная работа API server
|
||||
- OOM killer при нагрузке
|
||||
- Нет запаса для burst
|
||||
|
||||
Для production-like homelab рекомендую таблицу выше. Комфортный запас стоит дешевле, чем отладка странных падений.
|
||||
|
||||
---
|
||||
|
||||
## Сетевая схема
|
||||
|
||||
### IP-адреса (адаптируй под свою сеть)
|
||||
|
||||
```
|
||||
192.168.11.0/24 - Локальная сеть
|
||||
192.168.11.1 - Gateway (роутер)
|
||||
192.168.11.201-203 - Master ноды
|
||||
192.168.11.210-211 - Worker ноды
|
||||
192.168.11.220-230 - Резерв для MetalLB (статья 2)
|
||||
```
|
||||
|
||||
### Kubernetes внутренние сети (создаются автоматически)
|
||||
|
||||
```
|
||||
10.42.0.0/16 - Pod network (Flannel VXLAN overlay)
|
||||
10.43.0.0/16 - Service network (ClusterIP)
|
||||
10.43.0.10 - CoreDNS
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Порты между нодами
|
||||
|
||||
| Порт | Протокол | Направление | Назначение |
|
||||
|------|----------|-------------|------------|
|
||||
| 6443 | TCP | Master ← Worker | Kubernetes API |
|
||||
| 2379-2380 | TCP | Master ↔ Master | etcd (client + peer) |
|
||||
| 10250 | TCP | Master ↔ All | Kubelet API |
|
||||
| 8472 | UDP | All ↔ All | Flannel VXLAN |
|
||||
|
||||
---
|
||||
|
||||
## Требования к железу и софту
|
||||
|
||||
### Железо (Proxmox хост)
|
||||
|
||||
**Минимум:**
|
||||
- CPU: 14 vCPU свободных
|
||||
- RAM: 56GB свободных
|
||||
- Disk: 200GB на SSD
|
||||
- Network: 1 Gbit
|
||||
|
||||
**Рекомендуется:**
|
||||
- CPU: 18+ vCPU (запас для приложений)
|
||||
- RAM: 64GB+ (базы данных прожорливые)
|
||||
- Disk: NVMe для etcd
|
||||
- Network: 2.5 Gbit (для NFS, если будете использовать)
|
||||
|
||||
### Софт
|
||||
|
||||
| Компонент | Версия |
|
||||
|-----------|--------|
|
||||
| Proxmox VE | 7.x или 8.x |
|
||||
| K3s | v1.31+ (stable) |
|
||||
| ОС на нодах | Debian 12 или Ubuntu 22.04+ |
|
||||
| Kernel | 5.15+ (для cgroup v2) |
|
||||
|
||||
## Итог
|
||||
|
||||
**Что мы спроектировали:**
|
||||
- 5 VM: 3 master + 2 worker
|
||||
- K3s с embedded etcd (HA без лишних VM)
|
||||
- Отказоустойчивость: выдерживает падение 1 master и любого worker
|
||||
- Ресурсы: 14 vCPU / 56GB RAM / 196GB Disk
|
||||
|
||||
**Что НЕ входит в эту серию** (отдельные статьи):
|
||||
- LoadBalancer (MetalLB)
|
||||
- Ingress (Traefik)
|
||||
- SSL (cert-manager)
|
||||
- Мониторинг (Prometheus/Grafana)
|
||||
|
||||
---
|
||||
|
||||
## Что дальше
|
||||
|
||||
**👉 "Подготовить инфраструктуру для K3s в Proxmox"**
|
||||
|
||||
Там мы:
|
||||
- Создадим template VM с Debian 12
|
||||
- Склонируем 5 VM с правильными ресурсами
|
||||
- Настроим статические IP
|
||||
- Подготовим ОС (swap, cgroup v2, firewall)
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 672 KiB |
@@ -0,0 +1,619 @@
|
||||
---
|
||||
title: "Подготовить инфраструктуру для K3s в Proxmox"
|
||||
date: 2025-10-21
|
||||
draft: true
|
||||
description: "Создаём 5 VM в Proxmox с Debian 12, настраиваем сеть, отключаем swap и готовим систему для K3s. Пошаговая инструкция без сюрпризов."
|
||||
summary: "Архитектура спланирована, ресурсы посчитаны - пора создавать виртуальные машины. Подготовим 5 VM в Proxmox и настроим ОС так, чтобы K3s установился без сюрпризов."
|
||||
tags: ["kubernetes", "k3s", "homelab", "proxmox", "infrastructure", "debian", "devops"]
|
||||
series: ["K3s HA кластер для homelab"]
|
||||
series_order: 2
|
||||
# seriesOpened: true
|
||||
showTableOfContents: true
|
||||
---
|
||||
|
||||
Архитектура спланирована, ресурсы посчитаны - пора создавать виртуальные машины. В этой статье подготовим 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
|
||||
```
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Шаг 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
|
||||
- Проверим работу кластера
|
||||
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 3.6 MiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 741 KiB |
@@ -0,0 +1,650 @@
|
||||
---
|
||||
title: "Установить K3s HA кластер"
|
||||
date: 2025-11-02
|
||||
draft: true
|
||||
description: "Один curl-скрипт на каждую ноду - и через 15 минут у вас работающий HA-кластер. Устанавливаем K3s на 3 master и 2 worker ноды, настраиваем kubectl."
|
||||
summary: "Инфраструктура готова: 5 VM работают, ОС настроена, порты открыты. Пора устанавливать K3s. Один curl-скрипт на каждую ноду - и через 15 минут у вас работающий HA-кластер."
|
||||
tags: ["kubernetes", "k3s", "homelab", "installation", "ha", "etcd", "devops"]
|
||||
series: ["K3s HA кластер для homelab"]
|
||||
series_order: 3
|
||||
# seriesOpened: true
|
||||
showTableOfContents: true
|
||||
---
|
||||
|
||||
Инфраструктура готова: 5 VM работают, ОС настроена, порты открыты. Пора устанавливать K3s. Один curl-скрипт на каждую ноду - и через 15 минут у вас работающий HA-кластер.
|
||||
|
||||
Звучит слишком просто? Потому что сложная часть уже позади - в предыдущих статьях. Теперь осталось не перепутать флаги и порядок установки.
|
||||
|
||||
**Результат:** 5 нод в статусе Ready, etcd кластер 3/3 healthy, kubectl работает с локальной машины.
|
||||
|
||||
---
|
||||
|
||||
## Для кого это
|
||||
|
||||
**Подходит:**
|
||||
- Прошёл статьи 1 и 2 (или имеешь готовые VM с настроенной ОС)
|
||||
- Все 5 нод доступны по SSH
|
||||
- Понимаешь разницу между master и worker
|
||||
|
||||
**Не подходит:**
|
||||
- VM ещё не созданы → статья 2
|
||||
- Не понимаешь зачем 3 master ноды → статья 1
|
||||
|
||||
---
|
||||
|
||||
## Что понадобится
|
||||
|
||||
| Компонент | Значение |
|
||||
|-----------|----------|
|
||||
| K3s версия | v1.31.4+k3s1 (или актуальная stable) |
|
||||
| Token | Сгенерируем на первом шаге |
|
||||
| SSH доступ | Ко всем 5 нодам |
|
||||
| Время | ~15-20 минут |
|
||||
|
||||
---
|
||||
|
||||
## Шаг 1: Сгенерировать token
|
||||
|
||||
Token - общий секрет для всех нод кластера. Без правильного token нода не присоединится.
|
||||
|
||||
**На локальной машине:**
|
||||
|
||||
```bash
|
||||
# Сгенерировать случайный token
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
**Пример вывода:**
|
||||
```
|
||||
K10f8c9a7b6e5d4c3b2a1f0e9d8c7b6a5e4d3c2b1a0f9e8d7c6b5a4==
|
||||
```
|
||||
|
||||
**Сохрани этот token** - он понадобится для каждой ноды. Положи в менеджер паролей или временный файл.
|
||||
|
||||
```bash
|
||||
# Для удобства - сохранить в переменную (на время сессии)
|
||||
export K3S_TOKEN="твой_сгенерированный_token"
|
||||
echo $K3S_TOKEN
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Шаг 2: Установить K3s на первую master ноду
|
||||
|
||||
Первая нода инициализирует etcd кластер. Она особенная - использует флаг `--cluster-init`.
|
||||
|
||||
**SSH на k3s-master-1:**
|
||||
|
||||
```bash
|
||||
ssh k3s@192.168.11.201
|
||||
```
|
||||
|
||||
**Установка:**
|
||||
|
||||
```bash
|
||||
# Задать переменные
|
||||
export K3S_TOKEN="твой_сгенерированный_token"
|
||||
export INSTALL_K3S_VERSION="v1.31.4+k3s1"
|
||||
|
||||
# Установить K3s
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--cluster-init \
|
||||
--tls-san=192.168.11.201 \
|
||||
--disable=traefik \
|
||||
--disable=servicelb \
|
||||
--write-kubeconfig-mode=644
|
||||
```
|
||||
|
||||
**Разбор флагов:**
|
||||
|
||||
| Флаг | Зачем |
|
||||
|------|-------|
|
||||
| `server` | Режим control plane (не agent) |
|
||||
| `--cluster-init` | **Ключевой!** Инициализирует etcd. Только на первой ноде |
|
||||
| `--tls-san=192.168.11.201` | Добавить IP в сертификат API server |
|
||||
| `--disable=traefik` | Отключить встроенный Traefik (установим свой через Helm) |
|
||||
| `--disable=servicelb` | Отключить встроенный LB (установим MetalLB) |
|
||||
| `--write-kubeconfig-mode=644` | Разрешить чтение kubeconfig без sudo |
|
||||
|
||||
**Установка займёт 1-2 минуты.** K3s скачает бинарник (~50MB) и запустит все компоненты.
|
||||
|
||||
### Проверка
|
||||
|
||||
```bash
|
||||
# 1. Статус сервиса
|
||||
sudo systemctl status k3s
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
● k3s.service - Lightweight Kubernetes
|
||||
Loaded: loaded
|
||||
Active: active (running) since ...
|
||||
```
|
||||
|
||||
```bash
|
||||
# 2. Статус ноды
|
||||
sudo k3s kubectl get nodes
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
k3s-master-1 Ready control-plane,etcd,master 45s v1.31.4+k3s1
|
||||
```
|
||||
|
||||
<!-- СКРИНШОТ: Терминал с выводом `sudo k3s kubectl get nodes` - одна нода в статусе Ready -->
|
||||
|
||||
### Checkpoint: Первая master работает
|
||||
|
||||
```bash
|
||||
# Быстрая проверка
|
||||
sudo systemctl is-active k3s && \
|
||||
sudo k3s kubectl get nodes | grep -q "Ready" && \
|
||||
echo "✓ Master-1 готов" || echo "✗ Проблема"
|
||||
```
|
||||
|
||||
**Если статус NotReady или сервис не запустился:**
|
||||
|
||||
```bash
|
||||
# Смотреть логи
|
||||
sudo journalctl -u k3s -f --no-pager | tail -50
|
||||
```
|
||||
|
||||
| Ошибка в логах | Причина | Решение |
|
||||
|----------------|---------|---------|
|
||||
| `cgroup v1 is not supported` | Нужен cgroup v2 | Вернись к статье 2, шаг 6.5 |
|
||||
| `port 6443 already in use` | Что-то занимает порт | `sudo ss -tlnp \| grep 6443` |
|
||||
| `etcd failed to start` | Мало места на диске | `df -h`, увеличь диск |
|
||||
|
||||
---
|
||||
|
||||
## Шаг 3: Добавить вторую master ноду
|
||||
|
||||
Теперь присоединяем вторую master. Она подключается к существующему кластеру - **без** `--cluster-init`.
|
||||
|
||||
**SSH на k3s-master-2:**
|
||||
|
||||
```bash
|
||||
ssh k3s@192.168.11.202
|
||||
```
|
||||
|
||||
**Установка:**
|
||||
|
||||
```bash
|
||||
export K3S_TOKEN="твой_сгенерированный_token"
|
||||
export INSTALL_K3S_VERSION="v1.31.4+k3s1"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--server=https://192.168.11.201:6443 \
|
||||
--tls-san=192.168.11.202 \
|
||||
--disable=traefik \
|
||||
--disable=servicelb \
|
||||
--write-kubeconfig-mode=644
|
||||
```
|
||||
|
||||
**Ключевое отличие:**
|
||||
- ❌ Нет `--cluster-init` - кластер уже инициализирован
|
||||
- ✅ Есть `--server=https://192.168.11.201:6443` - адрес существующего кластера
|
||||
|
||||
### Проверка
|
||||
|
||||
```bash
|
||||
# На master-2
|
||||
sudo k3s kubectl get nodes
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
k3s-master-1 Ready control-plane,etcd,master 3m v1.31.4+k3s1
|
||||
k3s-master-2 Ready control-plane,etcd,master 30s v1.31.4+k3s1
|
||||
```
|
||||
|
||||
Две ноды - но кворума ещё нет. etcd требует большинство, а 2 из 3 - это ещё не "большинство от трёх".
|
||||
|
||||
---
|
||||
|
||||
## Шаг 4: Добавить третью master ноду
|
||||
|
||||
**SSH на k3s-master-3:**
|
||||
|
||||
```bash
|
||||
ssh k3s@192.168.11.203
|
||||
```
|
||||
|
||||
**Установка (аналогично master-2):**
|
||||
|
||||
```bash
|
||||
export K3S_TOKEN="твой_сгенерированный_token"
|
||||
export INSTALL_K3S_VERSION="v1.31.4+k3s1"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - server \
|
||||
--server=https://192.168.11.201:6443 \
|
||||
--tls-san=192.168.11.203 \
|
||||
--disable=traefik \
|
||||
--disable=servicelb \
|
||||
--write-kubeconfig-mode=644
|
||||
```
|
||||
|
||||
### Checkpoint: Control Plane HA готов
|
||||
|
||||
**На любой master ноде:**
|
||||
|
||||
```bash
|
||||
# 1. Все 3 master ноды Ready
|
||||
sudo k3s kubectl get nodes
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
k3s-master-1 Ready control-plane,etcd,master 5m v1.31.4+k3s1
|
||||
k3s-master-2 Ready control-plane,etcd,master 3m v1.31.4+k3s1
|
||||
k3s-master-3 Ready control-plane,etcd,master 1m v1.31.4+k3s1
|
||||
```
|
||||
|
||||
```bash
|
||||
# 2. etcd кластер здоров
|
||||
sudo k3s kubectl exec -n kube-system \
|
||||
$(sudo k3s kubectl get pods -n kube-system -l component=etcd -o name | head -1) \
|
||||
-- etcdctl endpoint health --cluster
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
https://192.168.11.201:2379 is healthy: successfully committed proposal: took = 2.1ms
|
||||
https://192.168.11.202:2379 is healthy: successfully committed proposal: took = 1.8ms
|
||||
https://192.168.11.203:2379 is healthy: successfully committed proposal: took = 2.3ms
|
||||
```
|
||||
|
||||
<!-- СКРИНШОТ: Терминал с выводом etcdctl endpoint health - все 3 endpoint healthy -->
|
||||
|
||||
**Теперь у вас настоящий HA.** Можете остановить любую master ноду - кластер продолжит работать.
|
||||
|
||||
### Тест отказоустойчивости (опционально)
|
||||
|
||||
Хотите убедиться, что HA работает? Проверьте:
|
||||
|
||||
```bash
|
||||
# С локальной машины - остановить master-2
|
||||
ssh k3s@192.168.11.202 "sudo systemctl stop k3s"
|
||||
|
||||
# Подождать 30-40 секунд, затем на master-1:
|
||||
ssh k3s@192.168.11.201 "sudo k3s kubectl get nodes"
|
||||
# master-2 станет NotReady, но кластер работает
|
||||
|
||||
# Проверить etcd - 2/3 кворум есть
|
||||
ssh k3s@192.168.11.201 "sudo k3s kubectl exec -n kube-system \
|
||||
\$(sudo k3s kubectl get pods -n kube-system -l component=etcd -o name | head -1) \
|
||||
-- etcdctl endpoint health --cluster"
|
||||
# 2 из 3 healthy - кворум есть
|
||||
|
||||
# Вернуть master-2
|
||||
ssh k3s@192.168.11.202 "sudo systemctl start k3s"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Шаг 5: Добавить worker ноды
|
||||
|
||||
Worker ноды устанавливаются как **agent** - они не участвуют в etcd и не запускают control plane.
|
||||
|
||||
### 5.1. Установить K3s agent на worker-1
|
||||
|
||||
**SSH на k3s-worker-1:**
|
||||
|
||||
```bash
|
||||
ssh k3s@192.168.11.210
|
||||
```
|
||||
|
||||
**Установка:**
|
||||
|
||||
```bash
|
||||
export K3S_TOKEN="твой_сгенерированный_token"
|
||||
export INSTALL_K3S_VERSION="v1.31.4+k3s1"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - agent \
|
||||
--server=https://192.168.11.201:6443
|
||||
```
|
||||
|
||||
**Отличия от master:**
|
||||
- `agent` вместо `server` - режим worker
|
||||
- Нет флагов `--disable` и `--tls-san` - они не нужны для worker
|
||||
- Только `--server` - куда подключаться
|
||||
|
||||
### 5.2. Установить K3s agent на worker-2
|
||||
|
||||
**SSH на k3s-worker-2:**
|
||||
|
||||
```bash
|
||||
ssh k3s@192.168.11.211
|
||||
```
|
||||
|
||||
**Установка:**
|
||||
|
||||
```bash
|
||||
export K3S_TOKEN="твой_сгенерированный_token"
|
||||
export INSTALL_K3S_VERSION="v1.31.4+k3s1"
|
||||
|
||||
curl -sfL https://get.k3s.io | sh -s - agent \
|
||||
--server=https://192.168.11.201:6443
|
||||
```
|
||||
|
||||
### Checkpoint: Все ноды в кластере
|
||||
|
||||
**На любой master ноде:**
|
||||
|
||||
```bash
|
||||
sudo k3s kubectl get nodes -o wide
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
NAME STATUS ROLES AGE VERSION INTERNAL-IP
|
||||
k3s-master-1 Ready control-plane,etcd,master 10m v1.31.4+k3s1 192.168.11.201
|
||||
k3s-master-2 Ready control-plane,etcd,master 8m v1.31.4+k3s1 192.168.11.202
|
||||
k3s-master-3 Ready control-plane,etcd,master 6m v1.31.4+k3s1 192.168.11.203
|
||||
k3s-worker-1 Ready <none> 2m v1.31.4+k3s1 192.168.11.210
|
||||
k3s-worker-2 Ready <none> 1m v1.31.4+k3s1 192.168.11.211
|
||||
```
|
||||
|
||||
<!-- СКРИНШОТ: Терминал с выводом kubectl get nodes - все 5 нод Ready -->
|
||||
|
||||
**Обрати внимание:**
|
||||
- Master: роли `control-plane,etcd,master`
|
||||
- Worker: роли `<none>` - только выполнение workloads
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## Шаг 6: Настроить kubectl на локальной машине
|
||||
|
||||
Сейчас kubectl работает только на master нодах через `sudo k3s kubectl`. Настроим доступ с вашей рабочей машины.
|
||||
|
||||
### 6.1. Скопировать kubeconfig
|
||||
|
||||
**На локальной машине (не на ноде):**
|
||||
|
||||
```bash
|
||||
# 1. Создать директорию
|
||||
mkdir -p ~/.kube
|
||||
|
||||
# 2. Скопировать конфиг с master-1
|
||||
scp k3s@192.168.11.201:/etc/rancher/k3s/k3s.yaml ~/.kube/config
|
||||
|
||||
# 3. Заменить localhost на реальный IP
|
||||
sed -i 's/127.0.0.1/192.168.11.201/g' ~/.kube/config
|
||||
|
||||
# Для macOS:
|
||||
# sed -i '' 's/127.0.0.1/192.168.11.201/g' ~/.kube/config
|
||||
|
||||
# 4. Права доступа
|
||||
chmod 600 ~/.kube/config
|
||||
```
|
||||
|
||||
### 6.2. Установить kubectl (если нет)
|
||||
|
||||
**Linux:**
|
||||
|
||||
```bash
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
rm kubectl
|
||||
```
|
||||
|
||||
**macOS:**
|
||||
|
||||
```bash
|
||||
brew install kubectl
|
||||
```
|
||||
|
||||
### 6.3. Проверить подключение
|
||||
|
||||
```bash
|
||||
# Версия
|
||||
kubectl version
|
||||
|
||||
# Ноды
|
||||
kubectl get nodes
|
||||
|
||||
# Все поды
|
||||
kubectl get pods -A
|
||||
```
|
||||
|
||||
**Ожидаемый результат `kubectl get pods -A`:**
|
||||
```
|
||||
NAMESPACE NAME READY STATUS RESTARTS AGE
|
||||
kube-system coredns-xxx 1/1 Running 0 10m
|
||||
kube-system local-path-provisioner-xxx 1/1 Running 0 10m
|
||||
kube-system metrics-server-xxx 1/1 Running 0 10m
|
||||
```
|
||||
|
||||
<!-- СКРИНШОТ: Терминал локальной машины с выводом kubectl get nodes и kubectl get pods -A -->
|
||||
|
||||
**Если kubectl не подключается:**
|
||||
|
||||
| Симптом | Причина | Решение |
|
||||
|---------|---------|---------|
|
||||
| `connection refused` | k3s не запущен | `ssh k3s@192.168.11.201 "sudo systemctl status k3s"` |
|
||||
| `connection timeout` | Firewall блокирует | Проверь UFW на master: `sudo ufw status \| grep 6443` |
|
||||
| `certificate signed by unknown authority` | Неправильный kubeconfig | Скопируй заново с master ноды |
|
||||
|
||||
### 6.4. Настроить автодополнение (опционально)
|
||||
|
||||
```bash
|
||||
# Bash
|
||||
echo 'source <(kubectl completion bash)' >> ~/.bashrc
|
||||
echo 'alias k=kubectl' >> ~/.bashrc
|
||||
echo 'complete -o default -F __start_kubectl k' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
|
||||
# Zsh
|
||||
echo 'source <(kubectl completion zsh)' >> ~/.zshrc
|
||||
source ~/.zshrc
|
||||
```
|
||||
|
||||
Теперь работает `k get nodes` и Tab-автодополнение.
|
||||
|
||||
---
|
||||
|
||||
## Финальная проверка
|
||||
|
||||
Полный чеклист работоспособности кластера:
|
||||
|
||||
```bash
|
||||
echo "=== Проверка K3s HA кластера ==="
|
||||
|
||||
echo -n "1. Все ноды Ready: "
|
||||
[ $(kubectl get nodes --no-headers | grep -c "Ready") -eq 5 ] && echo "✓ (5/5)" || echo "✗"
|
||||
|
||||
echo -n "2. Master ноды: "
|
||||
kubectl get nodes --no-headers | grep -c "control-plane" | xargs -I {} echo "✓ ({}/3)"
|
||||
|
||||
echo -n "3. Worker ноды: "
|
||||
kubectl get nodes --no-headers | grep -c "<none>" | xargs -I {} echo "✓ ({}/2)"
|
||||
|
||||
echo -n "4. etcd healthy: "
|
||||
kubectl exec -n kube-system \
|
||||
$(kubectl get pods -n kube-system -l component=etcd -o name | head -1) \
|
||||
-- etcdctl endpoint health --cluster 2>/dev/null | grep -c "is healthy" | xargs -I {} echo "✓ ({}/3)"
|
||||
|
||||
echo -n "5. CoreDNS Running: "
|
||||
kubectl get pods -n kube-system -l k8s-app=kube-dns --no-headers | grep -q "Running" && echo "✓" || echo "✗"
|
||||
|
||||
echo -n "6. Metrics Server Running: "
|
||||
kubectl get pods -n kube-system -l k8s-app=metrics-server --no-headers | grep -q "Running" && echo "✓" || echo "✗"
|
||||
|
||||
echo ""
|
||||
echo "=== Информация о кластере ==="
|
||||
kubectl cluster-info
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
=== Проверка K3s HA кластера ===
|
||||
1. Все ноды Ready: ✓ (5/5)
|
||||
2. Master ноды: ✓ (3/3)
|
||||
3. Worker ноды: ✓ (2/2)
|
||||
4. etcd healthy: ✓ (3/3)
|
||||
5. CoreDNS Running: ✓
|
||||
6. Metrics Server Running: ✓
|
||||
|
||||
=== Информация о кластере ===
|
||||
Kubernetes control plane is running at https://192.168.11.201:6443
|
||||
CoreDNS is running at https://192.168.11.201:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
|
||||
Metrics-server is running at https://192.168.11.201:6443/api/v1/namespaces/kube-system/services/https:metrics-server:https/proxy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Тестовый деплой
|
||||
|
||||
Убедимся, что кластер может запускать приложения:
|
||||
|
||||
```bash
|
||||
# 1. Создать тестовый под
|
||||
kubectl run nginx-test --image=nginx:alpine --port=80
|
||||
|
||||
# 2. Подождать запуска
|
||||
kubectl wait --for=condition=Ready pod/nginx-test --timeout=60s
|
||||
|
||||
# 3. Проверить на какой ноде запустился
|
||||
kubectl get pod nginx-test -o wide
|
||||
```
|
||||
|
||||
**Ожидаемый результат:**
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE IP NODE
|
||||
nginx-test 1/1 Running 0 30s 10.42.1.5 k3s-worker-1
|
||||
```
|
||||
|
||||
Под запустился на worker ноде - как и должно быть.
|
||||
|
||||
```bash
|
||||
# 4. Проверить доступность изнутри кластера
|
||||
kubectl run -it --rm debug --image=busybox --restart=Never -- wget -qO- nginx-test
|
||||
```
|
||||
|
||||
**Ожидаемый результат:** HTML-страница nginx.
|
||||
|
||||
```bash
|
||||
# 5. Удалить тестовые ресурсы
|
||||
kubectl delete pod nginx-test
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Нода не присоединяется к кластеру
|
||||
|
||||
**Симптом:** После установки нода не появляется в `kubectl get nodes`.
|
||||
|
||||
| Причина | Диагностика | Решение |
|
||||
|---------|-------------|---------|
|
||||
| Неправильный token | Логи: `sudo journalctl -u k3s-agent -f` | Проверь token, переустанови |
|
||||
| Firewall блокирует | `curl -k https://192.168.11.201:6443` | Открой порт 6443 на masters |
|
||||
| DNS не резолвит | `ping k3s-master-1` | Проверь /etc/hosts или DNS |
|
||||
|
||||
### etcd не формирует кворум
|
||||
|
||||
**Симптом:** `etcdctl endpoint health` показывает unhealthy.
|
||||
|
||||
```bash
|
||||
# Проверить членов etcd
|
||||
sudo k3s kubectl exec -n kube-system \
|
||||
$(sudo k3s kubectl get pods -n kube-system -l component=etcd -o name | head -1) \
|
||||
-- etcdctl member list --write-out=table
|
||||
```
|
||||
|
||||
| Причина | Диагностика | Решение |
|
||||
|---------|-------------|---------|
|
||||
| Порты 2379-2380 закрыты | `sudo ufw status` | `sudo ufw allow 2379:2380/tcp` |
|
||||
| Нода недоступна по сети | `ping 192.168.11.20X` | Проверь сеть, UFW |
|
||||
| etcd ещё стартует | `uptime` на ноде | Подожди 2-3 минуты |
|
||||
|
||||
### Поды не запускаются на workers
|
||||
|
||||
**Симптом:** Все поды на master нодах, workers пустые.
|
||||
|
||||
```bash
|
||||
# Проверить taints
|
||||
kubectl describe node k3s-worker-1 | grep Taints
|
||||
```
|
||||
|
||||
Если есть taints - убрать:
|
||||
```bash
|
||||
kubectl taint nodes k3s-worker-1 node.kubernetes.io/not-ready:NoSchedule-
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Откат: удаление K3s
|
||||
|
||||
Если нужно начать заново:
|
||||
|
||||
**На master ноде:**
|
||||
```bash
|
||||
sudo /usr/local/bin/k3s-uninstall.sh
|
||||
```
|
||||
|
||||
**На worker ноде:**
|
||||
```bash
|
||||
sudo /usr/local/bin/k3s-agent-uninstall.sh
|
||||
```
|
||||
|
||||
**Что удаляется:**
|
||||
- Бинарники K3s
|
||||
- Systemd сервисы
|
||||
- Данные из `/var/lib/rancher/k3s/`
|
||||
- etcd данные (на masters)
|
||||
- Контейнеры и образы
|
||||
|
||||
**⚠️ Внимание:** etcd снапшоты тоже удаляются. Если нужен бэкап:
|
||||
```bash
|
||||
# Перед удалением - сохранить снапшоты
|
||||
sudo cp -r /var/lib/rancher/k3s/server/db/snapshots/ ~/k3s-backup/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Итог
|
||||
|
||||
**Что сделано:**
|
||||
- ✅ Сгенерирован token для кластера
|
||||
- ✅ Установлен K3s на 3 master ноды с embedded etcd
|
||||
- ✅ Добавлены 2 worker ноды
|
||||
- ✅ Настроен kubectl на локальной машине
|
||||
- ✅ Проверена работоспособность кластера
|
||||
|
||||
**Что имеем:**
|
||||
- HA Control Plane - выдерживает падение 1 master ноды
|
||||
- 2 worker ноды для приложений
|
||||
- kubectl доступ с локальной машины
|
||||
- Встроенные компоненты: CoreDNS, metrics-server, local-path storage
|
||||
|
||||
**Что ещё не настроено** (следующие статьи):
|
||||
- LoadBalancer (MetalLB) - для доступа к сервисам извне
|
||||
- Ingress Controller (Traefik) - для HTTP/HTTPS routing
|
||||
- SSL сертификаты (cert-manager) - для автоматического HTTPS
|
||||
- Мониторинг (Prometheus/Grafana) - для наблюдения за кластером
|
||||
|
||||
---
|
||||
|
||||
## Что дальше
|
||||
|
||||
Кластер готов, но пока он изолирован от внешнего мира. Чтобы запускать реальные приложения с доступом извне, нужны:
|
||||
|
||||
1. **MetalLB** - выдаёт IP-адреса для LoadBalancer сервисов
|
||||
2. **Traefik** - маршрутизирует HTTP/HTTPS трафик
|
||||
3. **cert-manager** - автоматически получает SSL сертификаты
|
||||
|
||||
Это темы для следующей серии статей.
|
||||
|
||||
**А пока можно:**
|
||||
- Поэкспериментировать с kubectl
|
||||
- Задеплоить тестовые приложения
|
||||
- Изучить как работает scheduling между нодами
|
||||
|
||||
|
After Width: | Height: | Size: 14 KiB |