feat: крупное обновление стека — пути, bootstrap, etcd, cert-manager, custom errors, ноды
## Переименование путей (rancher → kubernetes)
- Все пути /var/lib/rancher/k3s → /var/lib/kubernetes/k3s
- Все пути /etc/rancher/k3s → /etc/kubernetes/k3s
- Добавлены переменные k3s_config_dir, k3s_data_dir, k3s_kubeconfig_path
- K3S install получил --data-dir и K3S_CONFIG_FILE флаги
- k3s-server-config.yaml.j2: добавлены write-kubeconfig и data-dir ключи
- Все роли (csi-nfs, ingress-nginx, cert-manager, prometheus, istio, cni)
переведены на {{ k3s_kubeconfig_path }} вместо хардкода
## Bootstrap (новое)
- bootstrap.yml — playbook для первоначальной настройки нод
- roles/bootstrap/ — создаёт пользователя ansible, настраивает sudoers,
деплоит SSH публичный ключ по паролю из vault
- host_vars/*/vault.yml.example — шаблоны с bootstrap_user/bootstrap_password
- make bootstrap, make vault-bootstrap-create NODE=..., make vault-bootstrap-edit NODE=...
## Добавление/удаление нод (новое)
- add-node.yml — добавляет мастер или воркер в существующий кластер через VIP
- remove-node.yml — cordon → drain → delete → uninstall → cleanup
- inventory/hosts.ini: добавлена группа [k3s_workers], обновлён [k3s_cluster:children]
- roles/k3s/tasks/main.yml: install_agent.yml для воркеров
## etcd backup/restore (новое)
- etcd-backup.yml / etcd-restore.yml — top-level playbooks
- roles/etcd/tasks/backup.yml — k3s etcd-snapshot save + retention cleanup
- roles/etcd/tasks/restore.yml — cluster-reset + перезапуск всех нод
- make etcd-backup, make etcd-restore SNAPSHOT=..., make etcd-list-snapshots
## cert-manager addon (новое)
- roles/cert-manager/ — установка через Helm + опциональный ClusterIssuer
- Поддержка: none | selfsigned | letsencrypt
- Шаблоны ClusterIssuer для selfsigned CA и ACME HTTP-01
- Управляется флагом cert_manager_enabled: false
## Custom error backend для ingress-nginx (новое)
- custom-error-page.html.j2 — тёмная Kubernetes-styled страница ошибок
- custom-error-backend.yaml.j2 — ConfigMap + Deployment (nginx) + Service
- nginx использует sub_filter для динамической подстановки X-Code/X-Message
- ingress-nginx Helm values: custom-http-errors, default-backend-service
- Управляется флагом ingress_nginx_custom_errors_enabled: true
## Hostname и пакеты (новое)
- prereqs.yml: установка hostname из inventory_hostname (пропускается в Molecule)
- prereqs.yml: установка k3s_common_packages (nfs-common, mc, htop, vim, wget, и др.)
- molecule_test: true в converge.yml исключает hostname из тестов
## Molecule improvements
- 3 платформы: master01 (Ubuntu 22.04) + worker01 (Ubuntu 22.04) + rpi01 (Debian 12)
- Molecule запускается из Docker контейнера через /var/run/docker.sock (DinD)
- Все пути в converge.yml и verify.yml обновлены под /etc/kubernetes/k3s
## Флаги включения компонентов
- kube_vip_enabled, nfs_server_enabled, csi_nfs_enabled, ingress_nginx_enabled
- cert_manager_enabled, istio_enabled, kiali_enabled, prometheus_stack_enabled
- Каждая роль пропускает установку через meta: end_play при disabled
## Документация
- README полностью переработан: все новые возможности с примерами
- Новые разделы: Управление нодами, etcd backup/restore, cert-manager, bootstrap
- Обновлены Makefile, docker/entrypoint.sh под все новые команды
This commit is contained in:
240
README.md
240
README.md
@@ -12,6 +12,8 @@
|
||||
- [Рабочий процесс](#рабочий-процесс)
|
||||
- [Настройка кластера](#настройка-кластера)
|
||||
- [Опциональные компоненты](#опциональные-компоненты)
|
||||
- [Управление нодами](#управление-нодами)
|
||||
- [Резервное копирование etcd](#резервное-копирование-etcd)
|
||||
- [Все команды Make](#все-команды-make)
|
||||
- [Тестирование через Molecule](#тестирование-через-molecule)
|
||||
- [Компоненты стека](#компоненты-стека)
|
||||
@@ -71,6 +73,7 @@
|
||||
| NFS Server | — | Персистентное хранилище на master01 |
|
||||
| CSI NFS Driver | v4.8.0 | Динамические PVC через NFS |
|
||||
| ingress-nginx | chart 4.10.1 | HTTP/S Ingress controller |
|
||||
| cert-manager | v1.15.3 | TLS сертификаты (опционально) |
|
||||
| Istio | 1.22.2 | Service mesh (опционально) |
|
||||
| Kiali | 1.86.0 | UI для Istio, вход по токену (опционально) |
|
||||
| kube-prometheus-stack | 60.3.0 | Prometheus + Grafana + Alertmanager (опционально) |
|
||||
@@ -147,6 +150,10 @@ k3s-ansible/
|
||||
├── upgrade.yml
|
||||
├── uninstall.yml
|
||||
├── healthcheck.yml
|
||||
├── add-node.yml ← Добавить ноду в кластер
|
||||
├── remove-node.yml ← Удалить ноду из кластера
|
||||
├── etcd-backup.yml ← Создать снимок etcd
|
||||
├── etcd-restore.yml ← Восстановить etcd из снимка
|
||||
│
|
||||
├── inventory/
|
||||
│ └── hosts.ini ← IP и параметры серверов
|
||||
@@ -180,6 +187,17 @@ k3s-ansible/
|
||||
├── nfs-server/ ← NFS сервер
|
||||
├── csi-nfs/ ← CSI Driver + StorageClass
|
||||
├── ingress-nginx/ ← Ingress controller
|
||||
├── cert-manager/ ← TLS сертификаты (опционально)
|
||||
│ ├── tasks/main.yml
|
||||
│ ├── defaults/main.yml
|
||||
│ └── templates/
|
||||
│ ├── clusterissuer-selfsigned.yaml.j2
|
||||
│ └── clusterissuer-letsencrypt.yaml.j2
|
||||
├── etcd/ ← Backup/restore задачи etcd
|
||||
│ ├── tasks/
|
||||
│ │ ├── backup.yml
|
||||
│ │ └── restore.yml
|
||||
│ └── defaults/main.yml
|
||||
│
|
||||
├── istio/ ← Service mesh + Kiali (опционально)
|
||||
│ ├── tasks/main.yml
|
||||
@@ -346,7 +364,8 @@ make install
|
||||
6. NFS server на master01
|
||||
7. CSI NFS Driver на всех нодах → StorageClass `nfs-master01`
|
||||
8. ingress-nginx через Helm
|
||||
9. Финальная проверка: nodes / pods / svc / storageclass
|
||||
9. cert-manager (только если `cert_manager_enabled: true`)
|
||||
10. Финальная проверка: nodes / pods / svc / storageclass
|
||||
|
||||
Ожидаемое время: **15-25 минут** в зависимости от скорости интернета.
|
||||
|
||||
@@ -440,6 +459,11 @@ k3s_disable_traefik: true # ОБЯЗАТЕЛЬНО true при ingress-ngi
|
||||
|
||||
# CNI выбирается здесь:
|
||||
k3s_cni: "flannel" # flannel | calico | cilium
|
||||
|
||||
# Пути K3S (изменены с /var/lib/rancher на /var/lib/kubernetes)
|
||||
k3s_config_dir: /etc/kubernetes/k3s # конфиги и kubeconfig
|
||||
k3s_data_dir: /var/lib/kubernetes/k3s # данные etcd, токены, манифесты
|
||||
k3s_kubeconfig_path: "{{ k3s_config_dir }}/k3s.yaml"
|
||||
```
|
||||
|
||||
### CNI
|
||||
@@ -557,6 +581,77 @@ vault_kiali_token: ""
|
||||
|
||||
---
|
||||
|
||||
### cert-manager (TLS сертификаты)
|
||||
|
||||
Автоматически выдаёт и обновляет TLS сертификаты в кластере. Поддерживает самоподписанные сертификаты (для внутреннего использования) и Let's Encrypt (для публичных доменов).
|
||||
|
||||
**Включить:**
|
||||
```yaml
|
||||
# group_vars/all/main.yml
|
||||
cert_manager_enabled: true
|
||||
```
|
||||
|
||||
Или разово:
|
||||
```bash
|
||||
make install-cert-manager
|
||||
```
|
||||
|
||||
**Типы ClusterIssuer:**
|
||||
|
||||
| `cert_manager_issuer` | Описание |
|
||||
|---|---|
|
||||
| `none` | Только установка cert-manager, без ClusterIssuer |
|
||||
| `selfsigned` | Самоподписанный CA (умолч.) — для внутреннего использования |
|
||||
| `letsencrypt` | Let's Encrypt ACME — требует публичный домен и ingress-nginx |
|
||||
|
||||
**Параметры:**
|
||||
|
||||
| Переменная | Умолч. | Описание |
|
||||
|---|---|---|
|
||||
| `cert_manager_enabled` | `false` | Включить установку |
|
||||
| `cert_manager_version` | `v1.15.3` | Версия Helm chart |
|
||||
| `cert_manager_namespace` | `cert-manager` | Namespace |
|
||||
| `cert_manager_issuer` | `selfsigned` | Тип ClusterIssuer |
|
||||
| `cert_manager_acme_email` | `admin@example.com` | Email для Let's Encrypt |
|
||||
| `cert_manager_acme_server` | `prod` | `prod` или `staging` |
|
||||
|
||||
**Использование selfsigned (внутренний CA):**
|
||||
|
||||
После установки будут созданы:
|
||||
- `selfsigned-issuer` — базовый самоподписанный issuer
|
||||
- `cluster-ca` — Certificate (CA сертификат)
|
||||
- `cluster-ca-issuer` — ClusterIssuer для выдачи сертификатов приложениям
|
||||
|
||||
Пример использования в манифестах:
|
||||
```yaml
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: my-app-tls
|
||||
spec:
|
||||
secretName: my-app-tls-secret
|
||||
issuerRef:
|
||||
name: cluster-ca-issuer
|
||||
kind: ClusterIssuer
|
||||
dnsNames:
|
||||
- myapp.local
|
||||
```
|
||||
|
||||
**Использование Let's Encrypt:**
|
||||
```yaml
|
||||
cert_manager_issuer: "letsencrypt"
|
||||
cert_manager_acme_email: "admin@example.com"
|
||||
cert_manager_acme_server: "prod" # или staging для тестирования
|
||||
```
|
||||
|
||||
Добавить аннотацию на Ingress:
|
||||
```yaml
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Istio (Service Mesh)
|
||||
|
||||
Устанавливает `istio/base` (CRDs) → `istiod` (control plane) → `istio/gateway` (LoadBalancer) → глобальную политику mTLS.
|
||||
@@ -716,6 +811,119 @@ prometheus_grafana_ingress_host: "grafana.example.com"
|
||||
|
||||
---
|
||||
|
||||
## Управление нодами
|
||||
|
||||
### Добавить ноду
|
||||
|
||||
Перед добавлением:
|
||||
1. Добавь ноду в `inventory/hosts.ini` в нужную группу (`k3s_master` или `k3s_workers`)
|
||||
2. Убедись что SSH доступ работает: `make ping`
|
||||
|
||||
```bash
|
||||
# Добавить мастер-ноду (станет etcd участником)
|
||||
make add-node NODE=master04
|
||||
|
||||
# Добавить рабочую ноду (только agent, без etcd)
|
||||
make add-node NODE=worker04
|
||||
```
|
||||
|
||||
Новые ноды подключаются через **VIP** (`kube_vip_address`) — kube-vip должен быть запущен. После добавления нода автоматически появляется в кластере.
|
||||
|
||||
Пример `inventory/hosts.ini` с рабочими нодами:
|
||||
```ini
|
||||
[k3s_master]
|
||||
master01 ansible_host=192.168.1.10 ansible_user=ubuntu
|
||||
worker01 ansible_host=192.168.1.11 ansible_user=ubuntu
|
||||
rpi01 ansible_host=192.168.1.12 ansible_user=pi
|
||||
|
||||
[k3s_workers]
|
||||
worker04 ansible_host=192.168.1.14 ansible_user=ubuntu
|
||||
worker05 ansible_host=192.168.1.15 ansible_user=ubuntu
|
||||
|
||||
[k3s_cluster:children]
|
||||
k3s_master
|
||||
k3s_workers
|
||||
```
|
||||
|
||||
### Удалить ноду
|
||||
|
||||
```bash
|
||||
make remove-node NODE=worker04
|
||||
```
|
||||
|
||||
Порядок удаления:
|
||||
1. `cordon` — запретить планирование новых подов
|
||||
2. `drain` — вытеснить все поды на другие ноды (таймаут 180 сек)
|
||||
3. `delete` — удалить ноду из Kubernetes API
|
||||
4. Запустить uninstall-скрипт K3S на удалённой ноде
|
||||
5. Очистить директории K3S
|
||||
|
||||
После удаления убери ноду из `inventory/hosts.ini`.
|
||||
|
||||
**Ограничения:**
|
||||
- Нельзя удалить первый мастер (`groups['k3s_master'][0]`) — он является точкой инициализации кластера
|
||||
- При удалении мастера etcd-кворум уменьшается: 3 → 2 нод. Рекомендуется добавить новый мастер после удаления
|
||||
|
||||
---
|
||||
|
||||
## Резервное копирование etcd
|
||||
|
||||
etcd хранит **всё состояние кластера** — поды, сервисы, конфигмапы, секреты, PVC. Регулярные снимки позволяют восстановить кластер после сбоя.
|
||||
|
||||
Снимки хранятся на сервере по пути `{{ k3s_data_dir }}/server/db/snapshots` (по умолчанию `/var/lib/kubernetes/k3s/server/db/snapshots`).
|
||||
|
||||
### Создать снимок
|
||||
|
||||
```bash
|
||||
make etcd-backup
|
||||
```
|
||||
|
||||
Создаёт снимок с автоматическим именем `k3s-etcd-<timestamp>.db`, удаляет старые снимки сверх `etcd_backup_retention` (по умолчанию 5).
|
||||
|
||||
Опционально — скопировать снимок на локальную машину:
|
||||
```yaml
|
||||
# group_vars/all/main.yml
|
||||
etcd_backup_copy_to_local: true
|
||||
etcd_backup_local_dir: "./etcd-backups"
|
||||
```
|
||||
|
||||
### Список снимков
|
||||
|
||||
```bash
|
||||
make etcd-list-snapshots
|
||||
```
|
||||
|
||||
### Восстановить из снимка
|
||||
|
||||
```bash
|
||||
# Посмотреть доступные снимки
|
||||
make etcd-list-snapshots
|
||||
|
||||
# Восстановить (с подтверждением — введи 'yes')
|
||||
make etcd-restore SNAPSHOT=k3s-etcd-20250101T120000.db
|
||||
|
||||
# Без интерактивного подтверждения
|
||||
FORCE=true make etcd-restore SNAPSHOT=k3s-etcd-20250101T120000.db
|
||||
```
|
||||
|
||||
**Что происходит при восстановлении:**
|
||||
1. K3S останавливается на **всех** мастерах и воркерах
|
||||
2. Запускается `k3s server --cluster-reset --cluster-reset-restore-path=<snapshot>` на первом мастере (процесс завершается после сброса)
|
||||
3. K3S запускается на первом мастере → ждёт готовности API
|
||||
4. K3S запускается на остальных мастерах
|
||||
5. K3S-agent запускается на воркерах
|
||||
|
||||
**Параметры резервного копирования:**
|
||||
|
||||
| Переменная | Умолч. | Описание |
|
||||
|---|---|---|
|
||||
| `etcd_backup_dir` | `{{ k3s_data_dir }}/server/db/snapshots` | Директория снимков на сервере |
|
||||
| `etcd_backup_retention` | `5` | Количество хранимых снимков |
|
||||
| `etcd_backup_copy_to_local` | `false` | Копировать снимок на Ansible-хост |
|
||||
| `etcd_backup_local_dir` | `./etcd-backups` | Локальная директория для снимков |
|
||||
|
||||
---
|
||||
|
||||
## Все команды Make
|
||||
|
||||
### Настройка и сборка
|
||||
@@ -743,10 +951,26 @@ make install-cni # CNI плагин (make install-cni K3S_CNI=calico|ci
|
||||
make install-kubevip # Только kube-vip
|
||||
make install-nfs # NFS + CSI
|
||||
make install-ingress # ingress-nginx
|
||||
make install-cert-manager # cert-manager + ClusterIssuer
|
||||
make install-istio # Istio + Kiali (нужен istio_enabled: true в vars)
|
||||
make install-monitoring # Prometheus + Grafana (нужен prometheus_stack_enabled: true)
|
||||
```
|
||||
|
||||
### Управление нодами
|
||||
|
||||
```bash
|
||||
make add-node NODE=worker04 # Добавить ноду в кластер
|
||||
make remove-node NODE=worker04 # Безопасно удалить ноду
|
||||
```
|
||||
|
||||
### etcd — резервное копирование
|
||||
|
||||
```bash
|
||||
make etcd-backup # Создать снимок etcd
|
||||
make etcd-list-snapshots # Список доступных снимков
|
||||
make etcd-restore SNAPSHOT=k3s-etcd-XXX.db # Восстановить из снимка
|
||||
```
|
||||
|
||||
### Тестирование (Molecule — всё в Docker, pip не нужен)
|
||||
|
||||
```bash
|
||||
@@ -848,13 +1072,13 @@ destroy → удалить Docker-контейнер
|
||||
|
||||
**Тестируемые задачи:**
|
||||
- `prereqs.yml` — пакеты, swap, модули ядра, sysctl
|
||||
- Рендеринг `k3s-server-config.yaml.j2` → `/etc/rancher/k3s/config.yaml`
|
||||
- Рендеринг `k3s-server-config.yaml.j2` → `/etc/kubernetes/k3s/config.yaml`
|
||||
|
||||
**Что проверяет `verify.yml`:**
|
||||
|
||||
| Проверка | Нода | Что именно |
|
||||
|---|---|---|
|
||||
| Директория `/etc/rancher/k3s` | все | Создана роль prereqs |
|
||||
| Директория `/etc/kubernetes/k3s` | все | Создана роль prereqs |
|
||||
| Файл `config.yaml` | все | Существует, права `0600` |
|
||||
| `cluster-init: true` | master01 | Первый мастер инициализирует кластер |
|
||||
| `server: https://...:6443` | worker01, rpi01 | Присоединяются к master01 |
|
||||
@@ -1308,9 +1532,9 @@ kubectl get events -A --sort-by='.lastTimestamp' | tail -20
|
||||
kubectl -n kube-system exec -it \
|
||||
$(kubectl -n kube-system get pods -l component=etcd -o name | head -1) \
|
||||
-- etcdctl --endpoints=https://127.0.0.1:2379 \
|
||||
--cacert=/var/lib/rancher/k3s/server/tls/etcd/server-ca.crt \
|
||||
--cert=/var/lib/rancher/k3s/server/tls/etcd/server-client.crt \
|
||||
--key=/var/lib/rancher/k3s/server/tls/etcd/server-client.key \
|
||||
--cacert=/var/lib/kubernetes/k3s/server/tls/etcd/server-ca.crt \
|
||||
--cert=/var/lib/kubernetes/k3s/server/tls/etcd/server-client.crt \
|
||||
--key=/var/lib/kubernetes/k3s/server/tls/etcd/server-client.key \
|
||||
member list
|
||||
```
|
||||
|
||||
@@ -1456,6 +1680,10 @@ spec:
|
||||
| Molecule: image pull failed | `docker pull geerlingguy/docker-ubuntu2204-ansible:latest` вручную |
|
||||
| Molecule: idempotency failed | Таск выдаёт `changed` при повторном запуске — добавь `changed_when: false` |
|
||||
| `ansible-lint` ошибки | Запусти `make molecule-lint` и исправь указанные файлы |
|
||||
| etcd restore: снимок не найден | Запусти `make etcd-list-snapshots` — снимок должен быть на первом мастере |
|
||||
| add-node: нода не присоединяется | Убедись что kube-vip работает: `kubectl -n kube-system get pods \| grep kube-vip` |
|
||||
| remove-node: drain завис | Поды с PodDisruptionBudget могут блокировать drain. Проверь PDB: `kubectl get pdb -A` |
|
||||
| cert-manager: сертификат в Pending | `kubectl describe certificate <name>` — проверь условия. При letsencrypt нужен публичный домен и ingress |
|
||||
|
||||
### Отладка с подробным выводом
|
||||
|
||||
|
||||
Reference in New Issue
Block a user