1. k3s vs полный Kubernetes
k3s создан компанией Rancher (ныне часть SUSE) в 2019 году. Задача — сделать Kubernetes доступным для edge-устройств, IoT и небольших серверов. Сейчас это один из самых популярных дистрибутивов K8s с 28 000+ GitHub звёзд.
| Параметр | k3s | Kubernetes (K8s) |
|---|---|---|
| Бинарник | ~70 МБ (всё в одном) | 100+ МБ + множество компонентов |
| RAM (управляющий контур) | ~300–400 МБ | ~2 ГБ минимум |
| Установка | curl | sh — 1 минута | kubeadm / kops / 10–30 минут |
| База данных | SQLite (встроено) | etcd (отдельный процесс) |
| Ingress контроллер | Traefik (встроен) | Нет, ставится отдельно |
| Container runtime | containerd (встроен) | containerd / CRI-O (ставить отдельно) |
| CNI (сеть) | Flannel (встроен) | Нет, ставится отдельно |
| Kubernetes API | 100% совместим | Оригинал |
| Сертификация CNCF | Да | Да |
| Use case | VPS, обучение, edge, IoT | Крупные облачные кластеры |
100% совместимость с K8s
Манифесты YAML, Helm-чарты и kubectl работают одинаково в k3s и в полном Kubernetes. Что вы изучите на k3s — применимо в AWS EKS, Google GKE и любом другом кластере. Это главная причина использовать k3s для обучения.
2. Требования к VPS
Минимум
- • 512 МБ RAM
- • 1 vCPU
- • 5 ГБ диск
k3s + 1 приложение
Комфортно
- • 1–2 ГБ RAM
- • 1–2 vCPU
- • 20 ГБ диск
k3s + несколько сервисов
Продакшн
- • 4+ ГБ RAM
- • 2+ vCPU
- • 40+ ГБ SSD
10–15 сервисов, нагрузка
ОС: Ubuntu 22.04 LTS или 24.04 LTS (рекомендуется). Также поддерживаются Debian 11/12, RHEL/CentOS 8+, openSUSE. Нужен доступ по SSH с root или sudo.
Открыть порты в файрволе
Если на VPS есть UFW или облачный файрвол — откройте порты до установки:
# Порты для k3s
sudo ufw allow 6443/tcp # Kubernetes API
sudo ufw allow 80/tcp # HTTP (Traefik)
sudo ufw allow 443/tcp # HTTPS (Traefik)
sudo ufw allow 10250/tcp # Kubelet (для агент-нод)3. Установка за одну команду
k3s устанавливается одним curl-командой. Скрипт с официального сайта добавит systemd-сервис, установит kubectl, crictl и запустит кластер.
curl -sfL https://get.k3s.io | sh -Установка занимает 1–2 минуты. Скрипт скачает бинарник, создаст systemd-сервис и запустит k3s. После этого проверьте статус:
sudo systemctl status k3sПроверка узла кластера
sudo kubectl get nodesОжидаемый вывод:
NAME STATUS ROLES AGE VERSION
my-server Ready control-plane,master 2m v1.32.2+k3s1Статус Ready — кластер готов к работе.
Настройка kubectl без sudo
По умолчанию конфиг k3s доступен только root. Скопируйте его для текущего пользователя:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
# Теперь можно без sudo
kubectl get nodesВсе запущенные поды
kubectl get pods -AВы увидите системные поды: Traefik (ingress), CoreDNS, metrics-server и local-path-provisioner. Всё это k3s поднимает автоматически.
4. Первое приложение: деплой nginx
Задеплоим nginx с 2 репликами и откроем доступ через сервис. В Kubernetes приложения описываются в YAML-манифестах.
Создать манифест
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-demo
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
resources:
requests:
memory: "32Mi"
cpu: "50m"
limits:
memory: "64Mi"
cpu: "100m"
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
namespace: default
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80Применить манифест
kubectl apply -f nginx-demo.yamlПроверить результат
# Состояние подов
kubectl get pods
# Подробная информация (IP, нода)
kubectl get pods -o wide
# Сервис
kubectl get svc nginx-serviceОжидаемый вывод:
NAME READY STATUS RESTARTS AGE
nginx-demo-6d4cf56db6-2xk9b 1/1 Running 0 30s
nginx-demo-6d4cf56db6-m8w7c 1/1 Running 0 30sПроверить работу
Сервис типа ClusterIP доступен только внутри кластера. Для быстрой проверки:
kubectl port-forward service/nginx-service 8080:80 &
curl http://localhost:8080
# Ответ: <!DOCTYPE html><html>... (стандартная страница nginx)Масштабировать за секунду
kubectl scale deployment nginx-demo --replicas=5
kubectl get pods # 5 подов запустятся через несколько секундОбновить образ без downtime
kubectl set image deployment/nginx-demo nginx=nginx:1.27-alpine
kubectl rollout status deployment/nginx-demo # следить за прогрессомЧто происходит при rolling update
Kubernetes поочерёдно заменяет старые поды новыми — в любой момент работает хотя бы одна реплика. Если новый под не запускается — откат назад: kubectl rollout undo deployment/nginx-demo.
5. Основные команды kubectl
Весь Kubernetes управляется через kubectl. Вот шпаргалка по командам, которые нужны в повседневной работе:
kubectl get pods # поды kubectl get pods -A # все namespace-ы kubectl get pods -o wide # + IP и нода kubectl get deployments # деплойменты kubectl get services # сервисы (svc) kubectl get ingress # ингресс-правила kubectl get nodes # ноды кластера
kubectl describe pod <имя-пода> kubectl describe deployment nginx-demo kubectl describe node my-server
kubectl logs <имя-пода> # все логи kubectl logs <имя-пода> -f # в реальном времени kubectl logs <имя-пода> --tail=50 # последние 50 строк
kubectl exec -it <имя-пода> -- /bin/sh kubectl exec <имя-пода> -- env # переменные окружения
kubectl delete -f nginx-demo.yaml # по манифесту kubectl delete deployment nginx-demo # по имени kubectl delete pod <имя-пода> # конкретный под
kubectl get events --sort-by='.lastTimestamp' # полезно при отладке — видны ошибки и причины проблем
6. Ingress: маршрутизация по домену
k3s поставляется со встроенным Traefik — он автоматически становится Ingress Controller-ом. С помощью Ingress-ресурса вы настраиваете маршрутизацию: какой домен или путь ведёт к какому сервису.
Как это работает
Запрос приходит на IP вашего VPS → Traefik (порты 80/443) смотрит на Host-заголовок → маршрутизирует к нужному сервису внутри кластера. Один IP — множество доменов.
Ingress-правило для nginx-demo
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
spec:
ingressClassName: traefik
rules:
- host: example.ru # ваш домен
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80kubectl apply -f ingress-nginx.yaml
kubectl get ingress # проверить статусОжидаемый вывод — после применения в поле ADDRESS появится IP вашего VPS:
NAME CLASS HOSTS ADDRESS PORTS AGE
nginx-ingress traefik example.ru 203.0.113.10 80 10sНаправьте DNS вашего домена A-записью на IP VPS — и сайт станет доступен по адресу http://example.ru.
Дашборд Traefik
Traefik имеет встроенный дашборд с маршрутами и статусами сервисов:
kubectl port-forward -n kube-system service/traefik 9000:9000 &
# Открыть в браузере: http://localhost:9000/dashboard/7. HTTPS через cert-manager
Для автоматических TLS-сертификатов от Let's Encrypt используется cert-manager — стандартный оператор для управления сертификатами в Kubernetes. Он автоматически получает и обновляет сертификаты.
Шаг 1: установить cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
# Подождать запуска подов (30–60 секунд)
kubectl get pods -n cert-managerВсе три пода должны быть в статусе Running:
NAME READY STATUS AGE
cert-manager-xxx 1/1 Running 1m
cert-manager-cainjector-xxx 1/1 Running 1m
cert-manager-webhook-xxx 1/1 Running 1mШаг 2: создать ClusterIssuer
ClusterIssuer описывает источник сертификатов — Let's Encrypt. Укажите ваш email для уведомлений об истечении сертификата:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.ru # ← ваш email
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
ingressClassName: traefikkubectl apply -f clusterissuer.yaml
kubectl get clusterissuer # статус должен быть Ready: TrueШаг 3: обновить Ingress с TLS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: traefik
tls:
- hosts:
- example.ru
secretName: example-ru-tls # cert-manager создаст этот Secret
rules:
- host: example.ru
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80kubectl apply -f ingress-tls.yaml
# Следить за статусом сертификата
kubectl get certificate
kubectl describe certificate example-ru-tlscert-manager автоматически пройдёт HTTP-01 challenge, получит сертификат и сохранит в Secret. Через 1–2 минуты сайт будет доступен по HTTPS. Обновление происходит автоматически за 30 дней до истечения.
Staging vs Production
Для тестирования используйте staging-URL Let's Encrypt:https://acme-staging-v02.api.letsencrypt.org/directory. Staging не выдаёт доверенный сертификат, но нет лимита на запросы. Переключитесь на production только когда всё работает.
8. Добавление второй ноды
k3s легко масштабируется: добавьте второй VPS как агент-ноду. Рабочая нагрузка распределится автоматически. Управляющий контур остаётся только на сервер-ноде.
Шаг 1: получить токен с сервера
sudo cat /var/lib/rancher/k3s/server/node-token
# K10abc123def456::server:xxxxxxxxxxxxxxxxxxxxxxxxШаг 2: установить k3s-агент на второй VPS
curl -sfL https://get.k3s.io | K3S_URL=https://IP_СЕРВЕРА:6443 K3S_TOKEN=ВАШ_ТОКЕН sh -Шаг 3: проверить кластер
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# server-vps Ready control-plane,master 1d v1.32.2+k3s1
# agent-vps-2 Ready <none> 30s v1.32.2+k3s1Теперь Kubernetes сам решает, на какую ноду планировать поды. Для явного назначения используйте nodeSelector или affinity в манифесте.
Нужно ли несколько нод?
Для обучения и небольших проектов хватает одной ноды — Single-node кластер k3s вполне пригоден для продакшена при правильной настройке бэкапов. Несколько нод нужны для отказоустойчивости (если одна нода падает — поды переезжают на другую) или когда ресурсов одного VPS не хватает.
9. Удаление k3s
Установщик k3s автоматически создаёт скрипт удаления. Он останавливает сервисы, удаляет поды, очищает данные и убирает бинарники.
/usr/local/bin/k3s-uninstall.sh/usr/local/bin/k3s-agent-uninstall.shПосле удаления k3s останутся только данные в Persistent Volumes на внешних системах (если использовались). Данные кластера (SQLite) будут удалены.