Kubernetes в полном сборе славится аппетитом к железу и словарю терминов: отдельно контрольная плоскость, отдельно хранилище состояния, отдельно сеть, вход, сертификаты и дюжина контроллеров вокруг. Для pet-проекта или песочницы для обучения этот парад избыточен. K3s упаковывает тот же Kubernetes в один бинарник: контрольная плоскость и воркер в одном процессе, встроенные сеть и вход, сертификационная подсистема ставится одной командой. Название честно намекает: половина от k8s, округлённая вверх. Ниже полный цикл на одной VPS: установка, первое приложение, ingress на встроенном Traefik и автоматические сертификаты для домена.
Один бинарник вместо тяжёлой платформы и что уже внутри
K3s это полноценный Kubernetes, собранный так, чтобы жить на одном сервере без свиты. Проект родился в стане Rancher, теперь части SUSE, с прицелом на оборудование, где обычному кластеру тесно: одноплатные машины, модемы, периферия, серверы с гигабайтом памяти и процессорами ARM. Внутри одного процесса сидят серверная часть и воркер, а вместо распределённого хранилища etcd используется локальная база SQLite через прослойку kine: для одиночного узла этого достаточно, состояние кластера лежит в файлах под /var/lib/rancher/k3s/server/db, и резервная копия этих файлов спасает весь кластер целиком. Бинарник размером в несколько десятков мегабайт тащит в себе целый дистрибутив платформы, и это же свойство делает обновление тривиальным: повторный запуск скрипта установки накатывает свежую версию поверх старой, сохранив состояние.
Из коробки приезжает всё, без чего обычный Kubernetes требует отдельных манифестов. Состав встроенных компонентов выглядит так:
- Контейнерный рантайм containerd для исполнения подов;
- Сеть узла на flannel и раздача имён через CoreDNS;
- Входная точка Traefik актуальной третьей ветки;
- Томы через local-path provisioner и встроенная эмуляция LoadBalancer;
- metrics-server, благодаря которому kubectl top работает сразу. На осень 2026 актуальный релиз K3s повторяет Kubernetes 1.37, и это не урезанная пародия, а сертифицированная сборка: манифесты и привычки с большого кластера переезжают без перевода. Для закрытых сетей существует и автономная установка из архива образов, без обращения к внешним реестрам. Когда одиночный узел вырастает в план на высокую доступность, тот же установщик умеет поднять режим с встроенным etcd и несколькими серверами, так что путь наверх не требует переезда на другой дистрибутив.
Аппетит к железу скромный: серверу с парой ядер и гигабайтом-двумя памяти хватает на всю связку плюс пару приложений. Полноценный кластер требует кратного размера, и в этом разница между обучением за копейки и бюджетом на мини ферму.
Установка скриптом одной командой и первый запуск с kubectl
Установка укладывается в строку, знакомую любому, кто ставил K3s хоть раз:
curl -sfL https://get.k3s.io | sh -
sudo k3s kubectl get nodes
NAME STATUS ROLES AGE VERSION
srv1 Ready control-plane,master 60s v1.37.1+k3s1
Скрипт скачивает бинарник, регистрирует службу systemd и через минуту кластер уже принимает команды. Желающие на стабильность вместо экспериментального канала задают переменную окружения с каналом stable, а диагностика встроенной утилитой k3s check-config показывает готовность ядра к контейнерным делам. Снаружи сервер слушает 6443 для API и 10250 для служебного канала, и оба порта разумно держать закрытыми от мира: администратор ходит по ssh, приложения попадают внутрь через 80 и 443. Конфигурация доступа живёт в /etc/rancher/k3s/k3s.yaml, и чтобы работать привычным kubectl, файл копируют в стандартное место:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER ~/.kube/config
kubectl get pods -A
Список подов системных пространств имён показывает весь вшитый комплект: traefik, coredns, metrics-server, local-path-provisioner. Журнал службы читается привычным journalctl -u k3s, а файл юнита лежит в /etc/systemd/system/k3s.service и правится для нестандартных флагов запуска. Для удаления кластера служит скрипт k3s-uninstall.sh из каталога установки: эксперименты на учебном сервере заканчиваются чисто, без осколков в системе.
Приложение в кластере через deployment и service
Классический путь приложения в Kubernetes начинается с деплоймента и сервиса. Императивные команды подходят для пробы:
kubectl create deployment web --image=nginx:stable
kubectl expose deployment web --port=80
kubectl get pods -o wide
kubectl scale deployment web --replicas=2
Деплоймент держит нужное число копий пода, сервис даёт им общее имя и адрес внутри кластера. Колонка NODE в выводе не даст соврать: обе копии живут на одном сервере, ведь кластер из одного узла. Приказы выполняются честно: упавший под пересоздаётся, а scale меняет число копий мгновенно. Для жизни приложение описывают манифестом:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:stable
readinessProbe:
httpGet:
path: /
port: 80
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
Проба готовности в описании говорит платформе, когда под действительно готов принимать трафик, и ingress не отправит запрос в контейнер, который ещё поднимается. Применяется манифест командой kubectl apply -f app.yaml, изменения в файле применяются повторно тем же путём, а kubectl describe pod и kubectl logs отвечают на вопросы, если что-то пошло не по плану. Заглянуть в приложение с локальной машины помогает kubectl port-forward svc/web 8080:80, а картину потребления рисует kubectl top pods, работающий благодаря встроенному metrics-server. Обновление образа тоже держится в семействе честных команд:
kubectl set image deployment/web web=nginx:stable
kubectl rollout status deployment/web
kubectl rollout undo deployment/web
Первая подменяет образ, вторая показывает раскатку в реальном времени, третья возвращает прошлое состояние, если свежий образ закапризничал. Дальше живёт декларация, а не память о набранных командах.
Ingress на встроенном Traefik и маршрутизация по имени хоста
Сервис внутри кластера это ещё не сайт: наружу его выпускает ingress, и в K3s эту роль уже исполняет Traefik, слушая порты 80 и 443 сервера. Правило входа описывается манифестом:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: site
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Применяется одной командой:
kubectl apply -f ingress.yaml
kubectl get ingress
kubectl describe ingress site
Дальше работает DNS: A-запись домена указывает на адрес сервера, и запросы по имени хоста попадают в сервис web. Проверить правило можно и до DNS, эмулируя имя хоста заголовком: