Введение: Почему Kubernetes для Node.js?
Современные веб-приложения на JavaScript (Node.js) требуют высокой доступности, масштабируемости и отказоустойчивости. Когда ваше приложение выходит за рамки одного сервера, ручное управление становится кошмаром. Здесь на помощь приходит Kubernetes (K8s) — система оркестрации контейнеров, которая автоматизирует развертывание, масштабирование и управление приложениями.
В этом руководстве мы пройдем полный путь: от простого Node.js приложения до его запуска в продакшн-подобном окружении на Kubernetes. Вы узнаете, как упаковать код в Docker-образ, создать необходимые ресурсы K8s (Pod, Deployment, Service) и настроить доступ извне.
1. Подготовка приложения на Node.js
Для начала создадим простое Express-приложение. Оно будет отвечать на HTTP-запросы и выводить имя хоста контейнера (полезно для проверки балансировки нагрузки).
1.1. Файл app.js
const express = require('express');
const os = require('os');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({
message: 'Hello from Node.js on Kubernetes!',
hostname: os.hostname(),
timestamp: new Date().toISOString()
});
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
1.2. Файл package.json
{
"name": "k8s-node-app",
"version": "1.0.0",
"dependencies": {
"express": "^4.18.2"
},
"scripts": {
"start": "node app.js"
}
}
2. Контейнеризация: Docker-образ
Kubernetes работает с контейнерами. Создадим минимальный Dockerfile для нашего Node.js приложения. Используем официальный образ Node.js и многоступенчатую сборку для оптимизации размера.
2.1. Dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Соберите образ и отправьте его в Docker Hub или другой реестр:
docker build -t your-dockerhub/k8s-node-app:v1 .
docker push your-dockerhub/k8s-node-app:v1
3. Деплой на Kubernetes
Теперь перейдем к самому главному — созданию ресурсов Kubernetes. Мы будем использовать Deployment (для управления Pod'ами) и Service (для сетевого доступа).
3.1. Создание Deployment
Deployment гарантирует, что нужное количество Pod'ов с вашим приложением всегда запущено. Создайте файл deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: node-app-deployment
labels:
app: node-app
spec:
replicas: 3
selector:
matchLabels:
app: node-app
template:
metadata:
labels:
app: node-app
spec:
containers:
- name: node-app
image: your-dockerhub/k8s-node-app:v1
ports:
- containerPort: 3000
env:
- name: PORT
value: "3000"
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
3.2. Создание Service
Service обеспечивает стабильный IP-адрес и DNS-имя для доступа к Pod'ам. Создайте service.yaml:
apiVersion: v1
kind: Service
metadata:
name: node-app-service
spec:
selector:
app: node-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: ClusterIP
3.3. Запуск на кластере
Выполните команды (предварительно убедитесь, что у вас настроен kubectl и есть доступ к кластеру):
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# Проверка статуса
kubectl get pods
kubectl get deployments
kubectl get services
4. Доступ к приложению извне
Сервис типа ClusterIP доступен только внутри кластера. Чтобы открыть приложение внешнему миру, используйте один из двух способов.
4.1. NodePort (для тестов)
Измените тип сервиса на NodePort в service.yaml:
type: NodePort
После применения, приложение будет доступно по адресу http://<IP-узла>:<NodePort>. Порт можно узнать командой kubectl get svc.
4.2. Ingress (для продакшна)
Ingress — это более гибкий и правильный способ. Он работает на уровне HTTP/HTTPS и позволяет настраивать маршрутизацию. Пример Ingress-контроллера (требуется предустановленный ingress-nginx):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: node-app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: node-app-service
port:
number: 80
Примените Ingress и настройте DNS запись myapp.example.com на IP вашего Ingress-контроллера.
Заключение
Мы прошли полный цикл деплоя JavaScript (Node.js) приложения на Kubernetes: от написания кода и создания Docker-образа до развертывания в кластере с использованием Deployment, Service и Ingress. Теперь ваше приложение обладает встроенной отказоустойчивостью, масштабированием и простотой обновления.
Это лишь базовое руководство. В реальных проектах вам пригодятся ConfigMap и Secrets для управления конфигурацией, Horizontal Pod Autoscaler для автоматического масштабирования по нагрузке, а также