Files
resume/stack/kubernetes/SERVER.md
2026-07-18 23:44:30 +03:00

124 lines
10 KiB
Markdown
Raw 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.

# Окружение курса: удалённый сервер вместо Windows + Docker Desktop
Курс [LEARNING.md](LEARNING.md) написан под Windows + Docker Desktop + Git Bash. Этот документ — альтернативное окружение: тот же курс, тот же kind, но на удалённом Ubuntu-сервере по SSH. Здесь — характеристики железа, результаты бенчмарков и точечные адаптации команд там, где они отличаются от курса. Сам курс не переписан — по нему проходишь как есть, отличия смотришь здесь по мере необходимости.
## Сервер
| | |
|---|---|
| Хост | `totserver@192.168.31.163`, Ubuntu 24.04.3 LTS, kernel 6.8.0-124-generic |
| CPU | Intel N100, 4 ядра / 4 потока, до 3.4 ГГц, пассивное охлаждение |
| RAM | 16 ГБ DDR4-2667 (1 планка, второй слот пустой — апгрейд до 32 ГБ возможен) |
| Диск | Kingston NVMe 1 ТБ, ~852 ГБ свободно |
| Сеть | 1 Гбит/с (enp2s0) |
| Уже занято | Gitea + Postgres + два CI-раннера + file-server (docker) + Grafana + nginx (systemd), ~1.3 ГБ RAM в простое. Порты 80, 443, **3000 (Grafana)**, **3030 (Gitea)**, 222 (Gitea SSH), 4400 (file-server), 9090 (Prometheus) на хосте заняты этим стеком — **не трогать**. Подробный чек-лист — [«CI-инфраструктура на сервере — что нельзя ломать»](#ci-инфраструктура-на-сервере--что-нельзя-ломать) ниже |
| sudo | Требует пароль — все команды курса на этом сервере выполняются без sudo (kind/helm стоят в `~/.local/bin`) |
## Результаты бенчмарков (18-07-2026)
| Тест | Результат |
|---|---|
| CPU, sysbench, 4 потока, 15с | 11 283 events/sec |
| CPU, sysbench, 1 поток, 10с | 3 301 events/sec |
| RAM, sysbench memory, 4 потока | 9 900 МиБ/с |
| Диск, fio seq write 1M blocks | ~1024 МиБ/с (1.07 ГБ/с) |
| Диск, fio random 4k, mix 70/30, 4 jobs, iodepth=16 | read 12.6k IOPS / write 5.4k IOPS, avg latency ~0.2 мс |
| `kind create cluster` (1 нода, с нуля) | 52.8 с (в основном — скачивание образа ноды `kindest/node`) |
| Нода Ready + все поды kube-system Ready | ещё +6.5 с сверху |
| Idle-потребление 1-нодового kind-кластера | ~516 МБ RAM, ~20% CPU одного ядра |
| Температура CPU под нагрузкой | 60°C (crit 89.8°C у NVMe, 105°C у CPU) — троттлинга нет |
## Вердикт
Сервер уверенно тянет весь курс, модули 013, включая самый тяжёлый — модуль 11 (`kube-prometheus-stack`, обычно 23 ГБ RAM под Prometheus+Grafana+Alertmanager) — с большим запасом в 16 ГБ. Диск с латентностью ~0.2 мс на случайных 4k операциях с запасом покрывает требования etcd к fsync. Ограничение курса «Docker Desktop не меньше 8 ГБ RAM» здесь неактуально — нативный Docker на Linux видит всю память хоста, никакого выделенного лимита нет.
Единственное реальное ограничение — 4 ядра CPU: под тяжёлой нагрузкой (например, одновременно 3-нодовый kind-кластер + Helm-чарт с Prometheus) возможны просадки по отзывчивости, но не критично для pet-лабы.
## Точечные адаптации курса по модулям
### Модуль 0 — установка инструментов
Вместо `choco install kind kubernetes-cli kubernetes-helm` (Windows):
```bash
# kubectl уже стоит через snap (kubectl 1.35.6) — можно оставить, ставить заново не нужно
snap list kubectl
# kind — бинарь в ~/.local/bin (без sudo)
mkdir -p ~/.local/bin
KIND_VER=$(curl -s https://api.github.com/repos/kubernetes-sigs/kind/releases/latest | grep -oP '"tag_name": "\K[^"]+')
curl -Lo ~/.local/bin/kind "https://kind.sigs.k8s.io/dl/${KIND_VER}/kind-linux-amd64"
chmod +x ~/.local/bin/kind
# helm — официальный установочный скрипт, без sudo
curl -fsSL -o /tmp/get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod +x /tmp/get_helm.sh
HELM_INSTALL_DIR=$HOME/.local/bin USE_SUDO=false /tmp/get_helm.sh
rm -f /tmp/get_helm.sh
# проверка (в интерактивной SSH-сессии ~/.local/bin уже в PATH через ~/.profile)
docker --version; kind --version; kubectl version --client; helm version
```
Bash-синтаксис курса (heredoc, `base64 -d`, `curl`) работает нативно в SSH-сессии — отдельный Git Bash не нужен, это уже полноценный Linux.
### Модуль 2 — топология кластера
Порты 80/443 хоста заняты Gitea, поэтому в `kind-config.yaml` из модуля 2 сразу добавляй `extraPortMappings`, чтобы не пересоздавать кластер повторно в модуле 6:
```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 8080
- containerPort: 443
hostPort: 8443
- role: worker
- role: worker
```
### Модуль 6 — Ingress
Порты 80/443 заняты — доступ к `demo.local` идёт через 8080:
```bash
# с самого сервера
curl -H "Host: demo.local" http://localhost:8080
# с Windows-машины: добавить в C:\Windows\System32\drivers\etc\hosts
# 192.168.31.163 demo.local
# и открывать http://demo.local:8080 в браузере
```
### Модуль 7 — Secret/base64
`base64 -d` и heredoc работают нативно, отдельного Git Bash не требуется (актуально только для Windows-окружения курса).
### Модуль 11 — Helm, kube-prometheus-stack
Оговорку курса про «Docker Desktop не меньше 8 ГБ RAM» — игнорировать, неприменимо. Ресурсов в `my-values.yaml` из модуля 11 достаточно оставить как есть или ослабить (сервер потянет и дефолтные значения чарта).
## CI-инфраструктура на сервере — что нельзя ломать
Вне периметра K8s-курса, но на этом же сервере: Gitea + два CI-раннера Gitea Actions обслуживают реальный проект (`maxim/Pluto-SDR`, кросс-сборка C-кода под ARM). 18-07-2026 раннер `gitea_runner` был починен из restart-loop (устаревшая регистрация act_runner — вылечено чистой перерегистрацией), и поднят второй раннер `gitea_runner_armhf` — кастомный образ cross-builder'а (Debian + `arm-linux-gnueabihf-gcc` + статические armhf-либы в `/root/xarm`, собираются в образе через `build_deps.sh`). Подробный разбор этой настройки — в [../docker/CASE.md](../docker/CASE.md) → раздел 9 (это реальный кейс легенды, не учебный).
**Перед каждой сессией K8s-курса и в конце неё — быстрая проверка, что CI-стек жив:**
```bash
docker ps --filter name=gitea --format '{{.Names}}\t{{.Status}}'
# ожидаем Up у всех четырёх: gitea, gitea_db, gitea_runner, gitea_runner_armhf
```
Чек-лист, что можно ломать курсом, а что нет:
- **Не выполнять** `docker system prune -a` / `docker image prune -a`, пока запущен курс или контейнеры Gitea остановлены: образ `gitea-runner-armhf:latest` собран локально и нигде больше не существует (пересборка — кросс-компиляция 5 ARM-библиотек, ~20 мин и нужен интернет). `kind delete cluster` — безопасен, kind-образы отдельные.
- **Не удалять** файлы регистрации раннеров: `/opt/gitea/runner/.runner` и `/opt/gitea/runner-armhf/data/.runner` (личность раннера на сервере) — их удаление форсирует restart-loop, аналогичный уже починенному. `.env`-файлы в тех же каталогах — тоже не трогать.
- **Не запускать** `docker-compose ... --remove-orphans` внутри `/opt/gitea` — несколько compose-файлов делят один каталог/проект, `--remove-orphans` может снести соседний стек.
- **Порты в `kind-config.yaml`** (`extraPortMappings` из модуля 2) — использовать только 8080/8443. Не занимать 3000 (Grafana), 3030 (Gitea), 222 (Gitea SSH), 4400 (file-server), 9090 (Prometheus).
- **Конфиг Gitea**: `REQUIRE_SIGNIN_VIEW = false` в `app.ini` обязателен для CI-клонов (бэкап рядом: `app.ini.bak-2026-07-18`) — не возвращать в `true`. Воркфлоу Pluto-SDR клонируют `localhost:3000` через socat-проброс **внутри** `gitea_runner_armhf` на порт Gitea (:3030) — хостовый порт 3000 (Grafana) тут ни при чём, трогать его конфигурацию не требуется.
- **После ребута сервера** всё поднимается само (`restart: unless-stopped` у обоих раннеров + `gitea.service` для Gitea/Postgres) — вмешательство не требуется.
- **Признак, что CI жив**: в админке https://totmaxim.ru/-/admin/actions/runners оба раннера (`my-runner`, `my-runner-ci`) online.