Kubernetes на минималках: поднимаем k3s
Kubernetes — мощный инструмент, но у него репутация монстра, который жрёт ресурсы и требует целой команды для поддержки. Отчасти это справедливо для полноразмерных кластеров на kubeadm. Но есть k3s — дистрибутив Kubernetes от Rancher, который умещается в один бинарник на 70 МБ и отлично работает на VPS с 2 ГБ RAM. Я использую его для self-hosted проектов, и за полтора года ни разу не пожалел.
Почему k3s
Kubernetes бывает разный. Вот чем k3s отличается от стандартной установки:
- Один бинарник — никаких отдельных etcd, kube-scheduler, kube-controller-manager. Всё в одном процессе. Вместо etcd по умолчанию используется SQLite (для single-node) или встроенный etcd (для HA).
- Минимальные ресурсы — серверная нода потребляет ~500 МБ RAM. Для сравнения, куберовый control plane на kubeadm — от 2 ГБ.
- Батарейки в комплекте — из коробки идут Traefik (ingress controller), CoreDNS, local-path-provisioner (persistent volumes), metrics-server. Не нужно ставить полдюжины аддонов сразу после установки.
- Полная совместимость — это сертифицированный Kubernetes. Все манифесты, Helm-чарты и операторы работают без изменений.
Установка
Установка k3s — одна команда. Серьёзно:
curl -sfL https://get.k3s.io | sh - Через 30 секунд у вас работающий кластер. Kubeconfig лежит в /etc/rancher/k3s/k3s.yaml, а kubectl уже в PATH.
# Проверяем, что кластер работает
sudo kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# vps-01 Ready control-plane,master 45s v1.29.3+k3s1
sudo kubectl get pods -A
# Traefik, CoreDNS, metrics-server — всё запущено Для удобства настроим доступ без sudo:
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
export KUBECONFIG=~/.kube/config Если хотите управлять кластером с локальной машины, скопируйте kubeconfig и замените 127.0.0.1 на IP сервера:
scp user@vps:/etc/rancher/k3s/k3s.yaml ~/.kube/k3s-config
sed -i 's/127.0.0.1/YOUR_VPS_IP/' ~/.kube/k3s-config
export KUBECONFIG=~/.kube/k3s-config Деплоим первое приложение
Развернём простое веб-приложение. Для этого нужны три ресурса: Deployment, Service и Ingress.
Deployment
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
labels:
app: demo
spec:
replicas: 2
selector:
matchLabels:
app: demo
template:
metadata:
labels:
app: demo
spec:
containers:
- name: app
image: nginx:1.25-alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 5 Service
# app-service.yaml
apiVersion: v1
kind: Service
metadata:
name: demo-app
spec:
selector:
app: demo
ports:
- port: 80
targetPort: 80 Ingress
# app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-app
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt
spec:
rules:
- host: demo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo-app
port:
number: 80
tls:
- hosts:
- demo.example.com
secretName: demo-tls Применяем:
kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml
kubectl apply -f app-ingress.yaml
# Проверяем статус
kubectl get pods
kubectl get svc
kubectl get ingress Traefik как Ingress Controller
k3s ставит Traefik из коробки. Это удобно, но конфигурация по умолчанию довольно минимальна. Для Let’s Encrypt нужно подправить настройки.
Traefik в k3s управляется через HelmChartConfig:
# traefik-config.yaml
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
additionalArguments:
- "--certificatesresolvers.letsencrypt.acme.email=you@example.com"
- "--certificatesresolvers.letsencrypt.acme.storage=/data/acme.json"
- "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
ports:
websecure:
tls:
enabled: true
logs:
access:
enabled: true kubectl apply -f traefik-config.yaml
# Traefik перезапустится автоматически Helm: пакетный менеджер для Kubernetes
Вручную писать манифесты для каждого приложения — не масштабируется. Helm решает эту проблему: это пакетный менеджер, который позволяет устанавливать приложения из готовых чартов с кастомизацией через values.
# Установка Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Добавляем репозиторий
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# Ищем чарт
helm search repo bitnami/postgresql
# Устанавливаем PostgreSQL
helm install my-db bitnami/postgresql
--set auth.postgresPassword=secretpass
--set primary.persistence.size=10Gi
--namespace databases
--create-namespace Для продакшена лучше хранить values в файле и версионировать:
# postgres-values.yaml
auth:
postgresPassword: secretpass
database: myapp
primary:
persistence:
size: 10Gi
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 512Mi
cpu: 500m
metrics:
enabled: true helm install my-db bitnami/postgresql -f postgres-values.yaml -n databases --create-namespace Persistent Volumes
k3s из коробки поставляет local-path-provisioner — StorageClass, который создаёт PV на локальном диске ноды. Для single-node это идеально.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-data
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 5Gi Данные хранятся в /opt/local-path-provisioner/ на ноде. Для продакшена стоит настроить бэкапы этой директории.
Если нужно что-то серьёзнее — Longhorn (тоже от Rancher) даёт репликацию, снепшоты и бэкапы в S3. Ставится одной командой:
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.6.0/deploy/longhorn.yaml Мониторинг
k3s ставит metrics-server автоматически. Базовые метрики доступны через kubectl:
# Потребление ресурсов нодами
kubectl top nodes
# Потребление ресурсов подами
kubectl top pods -A
# Подробнее по конкретному namespace
kubectl top pods -n default --sort-by=memory Для полноценного мониторинга я ставлю kube-prometheus-stack через Helm:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install monitoring prometheus-community/kube-prometheus-stack
--namespace monitoring
--create-namespace
--set prometheus.prometheusSpec.retention=30d
--set grafana.adminPassword=admin Это даёт Prometheus, Grafana и Alertmanager с преднастроенными дашбордами для Kubernetes. На VPS с 4 ГБ RAM стек мониторинга занимает около 500 МБ — терпимо.
Полезные команды на каждый день
# Статус всех ресурсов в namespace
kubectl get all -n default
# Описание пода (события, причины ошибок)
kubectl describe pod <pod-name>
# Логи пода (follow, последние 50 строк)
kubectl logs -f --tail=50 <pod-name>
# Зайти в контейнер
kubectl exec -it <pod-name> -- /bin/sh
# Перезапустить deployment (rolling restart)
kubectl rollout restart deployment/<name>
# Откатиться на предыдущую ревизию
kubectl rollout undo deployment/<name>
# Отслеживать статус деплоя
kubectl rollout status deployment/<name> Итог
k3s снижает порог входа в Kubernetes до минимума. Один VPS, одна команда для установки — и у вас полноценный кластер с ingress-контроллером, storage provisioner и метриками. Для self-hosted проектов, домашних лабораторий и даже небольших продакшен-сред — это оптимальный выбор. А если потребуется масштабирование, k3s поддерживает HA-кластер из нескольких нод через встроенный etcd. Но это тема для отдельной статьи.