Олег Марков
Развёртывание и конфигурация сервера в Kubernetes
Введение
Kubernetes — это современная платформа оркестрации контейнеров, которая помогает управлять развертыванием, масштабированием и эксплуатацией приложений в контейнерах. С его помощью вы сможете автоматизировать многие задачи по конфигурации и запуску серверов, что особенно важно как для разработки, так и для поддержки продуктивной среды. В этой статье мы подробно рассмотрим процесс развёртывания сервера в Kubernetes, разберём различные способы конфигурации, приведём примеры YAML-манифестов и обсудим типичные задачи, с которыми сталкиваются разработчики при работе с этой системой.
Базовые понятия Kubernetes, важные для развертывания
Кратко о Pod, Deployment, Service и Namespace
Перед тем как перейти к практике, напомню ключевые термины:
- Pod — минимальная единица запуска в Kubernetes, обычно содержит один контейнер (чаще всего), но может и несколько.
- Deployment — более высокий уровень абстракции. Контроллер, который следит за тем, чтобы необходимое количество pod-ов с нужной конфигурацией было постоянно в кластере.
- Service — объект, который обеспечивает стабильную точку доступа к одному или нескольким pod-ам, скрывая возможные изменения их IP-адресов.
- Namespace — разграничение областей в кластере, удобно для разделения ресурсов между командами и окружениями.
Подобные абстракции обеспечивают гибкость, масштабируемость и удобство эксплуатации серверов в Kubernetes.
Развёртывание сервера: шаг за шагом
Подготовка Docker-образа для вашего сервера
До того как вы начнёте работу с Kubernetes, необходимо упаковать ваше серверное приложение в Docker-образ. Это позволит Kubernetes управлять экземплярами вашего сервера как с контейнерами. Пример Dockerfile для простого HTTP-сервера на Node.js:
# Используем официальный образ Node.js
FROM node:18-alpine
# Создаем рабочую директорию
WORKDIR /usr/src/app
# Копируем package.json и устанавливаем зависимости
COPY package*.json ./
RUN npm ci
# Копируем исходные файлы приложения
COPY . .
# Запуск приложения
CMD [ "node", "server.js" ]
Соберите образ и загрузите его в Docker Registry:
docker build -t myregistry/myserver:1.0 .
docker push myregistry/myserver:1.0
Составление Deployment-манифеста
Для развертывания вашего сервера используется объект Deployment. Вот как может выглядеть минимальный манифест:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-deployment
spec:
replicas: 2 # Сколько экземпляров сервера будет работать одновременно
selector:
matchLabels:
app: myserver
template:
metadata:
labels:
app: myserver
spec:
containers:
- name: myserver
image: myregistry/myserver:1.0 # Ваш образ сервера
ports:
- containerPort: 8080 # Порт, на котором работает сервер внутри контейнера
Применить его можно так:
kubectl apply -f deployment.yaml
Открытие доступа через Service
По умолчанию pod-ы не доступны извне кластера. Для публикации сервера необходимо создать Service. Вот пример простейшего Service для HTTP-приложения:
apiVersion: v1
kind: Service
metadata:
name: myserver-service
spec:
selector:
app: myserver # Соотносим Service с pod-ами по label
ports:
- protocol: TCP
port: 80 # Внешний порт, по которому обращаются клиенты
targetPort: 8080 # Порт в контейнере
type: ClusterIP # Варианты: ClusterIP, NodePort, LoadBalancer, ExternalName
Для тестирования внутри кластера используйте тип ClusterIP
. Если сервис должен быть доступен снаружи, укажите NodePort
или (в облаке) LoadBalancer
.
Пример запуска и проверки
Смотрите, я показываю прямую последовательность действий:
Примените deployment:
kubectl apply -f deployment.yaml
Примените service:
kubectl apply -f service.yaml
Убедитесь, что pod-ы запущены:
kubectl get pods
Посмотрите, как работает service:
При использовании `NodePort` доступ к серверу можно получить по адресу:kubectl get service
Выведите значение порта командой:http://<NODE_IP>:<NODE_PORT>
kubectl describe service myserver-service
Расширенная конфигурация сервера в Kubernetes
Использование ConfigMap и Secret для конфигурации приложения
Хранить параметры конфигурации лучше всего в объектах ConfigMap
(для не секретных данных) и Secret
(для паролей, токенов и приватных ключей).
Пример ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: myserver-config
data:
APP_ENV: production
LOG_LEVEL: info
Пример Secret:
apiVersion: v1
kind: Secret
metadata:
name: myserver-secret
type: Opaque
data:
DB_PASSWORD: cGFzc3dvcmQ= # base64 для "password"
Подключить их к Pod-у можно через переменные окружения:
env:
- name: APP_ENV
valueFrom:
configMapKeyRef:
name: myserver-config
key: APP_ENV
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: myserver-secret
key: DB_PASSWORD
Монтирование томов: хранение данных
Если серверу нужно хранить данные (например, база данных, кэш, файлы), используется Volume. Пример с использованием PersistentVolumeClaim
:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myserver-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
В Pod-е:
volumes:
- name: server-storage
persistentVolumeClaim:
claimName: myserver-pvc
containers:
- name: myserver
image: myregistry/myserver:1.0
volumeMounts:
- mountPath: /data
name: server-storage
Теперь контейнер будет сохранять (и получать) файлы из директории /data
на постоянное хранилище.
Настройка ресурсов и лимитов
Ресурсы (resources.requests
и resources.limits
) помогают Kubernetes корректно планировать ваши серверы и предотвращать выделение им лишних или недостаточных ресурсов.
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
requests
— минимально гарантированные ресурсы.limits
— максимальные допустимые ресурсы для контейнера.
Прописывание readiness и liveness probes
Readiness probe сообщает Kubernetes, когда контейнер готов принимать трафик. Liveness probe позволяет перезапускать "зависший" контейнер. Вот как они настраиваются:
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
Этот пример полезен для HTTP-сервера, отдающего /health
-эндпоинт.
Масштабирование сервера (об авто- и ручном скейлинге)
Поменять количество реплик можно вручную:
kubectl scale deployment myserver-deployment --replicas=5
Для автоматического масштабирования (например, по нагрузке по CPU) используется Horizontal Pod Autoscaler (HPA):
kubectl autoscale deployment myserver-deployment --cpu-percent=80 --min=2 --max=10
Проверьте HPA:
kubectl get hpa
Нюансы работы в разных окружениях
Namespaces
Создайте отдельные namespaces для разных сред (dev, staging, prod):
kubectl create namespace prod
kubectl apply -f deployment.yaml --namespace=prod
Переменные окружения для разных конфигураций
Для отличающихся конфигураций удобно использовать разные ConfigMap/Secret для каждого namespace или окружения.
Интеграция с CI/CD
Большинство современных CI/CD-систем (например, GitHub Actions, GitLab CI, Jenkins) поддерживают автоматическое применение изменений манифестов в кластер. YAML-файлы удобно хранить в системе контроля версий.
Отправка логов и мониторинг
Kubernetes интегрируется с системами мониторинга (Prometheus, Grafana) и сбора логов (ELK, Loki). Для этого в кластере часто развертываются sidecar-контейнеры или DaemonSet-ы для агрегации логов.
Настройка Rolling Update и Rollback
По умолчанию Deployment использует стратегию rolling update, обновляя поды по очереди. Если вы опубликовали нерабочую версию — легко откатиться:
kubectl rollout undo deployment myserver-deployment
Защита и безопасность (RBAC, ограничение доступа)
Ограничьте доступ к кластеру и объектам через роли и сервис-аккаунты (RBAC):
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
Назначаете роль конкретному сервис-аккаунту или пользователю через RoleBinding.
Секреты и чувствительные данные
Не храните секретные данные в открытых yaml-файлах. Используйте kubectl для генерации секретов:
kubectl create secret generic myserver-secret --from-literal=DB_PASSWORD=mypassword
Это обеспечит безопасное хранение чувствительных данных.
Заключение
Развёртывание и конфигурация серверов в Kubernetes устроены так, чтобы упростить управление контейнеризированными приложениями, гарантировать масштабируемость, отказоустойчивость и быстрый отклик на изменяющиеся требования. Используя возможности Deployment, Service, ConfigMap, Secret, Volumes и другие компоненты Kubernetes, вы легко адаптируете свои приложения под разные среды и сценарии эксплуатации. Пример пошаговой настройки сервера выше закладывает фундамент — дальше вы сможете соединить этот опыт с другими возможностями платформы для решения собственных задач.
Частозадаваемые технические вопросы по теме статьи и ответы на них
1. Как быстро посмотреть логи всех pod-ов моего deployment-а в Kubernetes?
Выведите список pod-ов с помощью kubectl get pods -l app=myserver
, затем используйте цикл:sh
for pod in $(kubectl get pods -l app=myserver -o name); do kubectl logs $pod; done
2. Как передать секреты (пароли) без записи их напрямую в YAML-файл?
Создайте секрет из командной строки:sh
kubectl create secret generic db-secret --from-literal=DB_PASS=superpassword
и подключайте через env.valueFrom.secretKeyRef
в манифестах.
3. Как узнать внутренний IP-адрес pod-а или service?
Используйте:sh
kubectl get pod <имя-pod> -o wide
kubectl get svc <имя-service>
для вывода IP-адресов.
4. Как быстро перезапустить все pod-ы deployment-а без изменения образа?
Используйте аннотацию, чтобы форсировать rollout:sh
kubectl rollout restart deployment myserver-deployment
5. Как ограничить доступ к серверу только с определённых IP или сетей?
Примените NetworkPolicy. Пример YAML:
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-specific-ip
spec:
podSelector: {}
ingress:
- from:
- ipBlock:
cidr: 192.168.1.0/24
``` Этот policy позволит доступ только с подсети 192.168.1.0/24.
Постройте личный план изучения Kubernetes до уровня Middle — бесплатно!
Kubernetes — часть карты развития DevOps
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Kubernetes
Лучшие курсы по теме

Kubernetes и Helm
Антон Ларичев
Docker и Ansible
Антон Ларичев