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

10 KiB
Raw Blame History

Окружение курса: удалённый сервер вместо 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) — троттлинга нет

Вердикт

Сервер уверенно тянет весь курс, модули 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):

# 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.