10 KiB
Окружение курса: удалённый сервер вместо Windows + Docker Desktop
Курс 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-инфраструктура на сервере — что нельзя ломать» ниже |
| 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) — троттлинга нет |
Вердикт
Сервер уверенно тянет весь курс, модули 0–13, включая самый тяжёлый — модуль 11 (kube-prometheus-stack, обычно 2–3 ГБ 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):
# 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:
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:
# с самого сервера
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 → раздел 9 (это реальный кейс легенды, не учебный).
Перед каждой сессией K8s-курса и в конце неё — быстрая проверка, что CI-стек жив:
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.