Деплой JavaScript (Node.js) на Kubernetes: базовое руководство на практике
Современная веб-разработка немыслима без контейнеризации и оркестрации. Если вы пишете на JavaScript (Node.js), рано или поздно встанет вопрос: как надежно запустить приложение в production, обеспечить его масштабирование и отказоустойчивость? Ответ — Kubernetes. Это не просто модный инструмент, а стандарт де-факто для управления контейнеризированными приложениями.
В этом руководстве мы разберем полный цикл деплоя простого Node.js приложения на Kubernetes. Вы узнаете, как упаковать код в Docker-образ, создать необходимые манифесты и запустить все в кластере. Материал рассчитан на разработчиков, которые уже знакомы с основами Node.js и хотят освоить DevOps-практики.
1. Подготовка Node.js приложения к контейнеризации
Прежде чем деплоить приложение на Kubernetes, его нужно упаковать в контейнер. Для этого создадим простое Express-приложение. Убедитесь, что у вас установлен Node.js и npm.
Создайте файл app.js:
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.json({ message: 'Hello from Node.js on Kubernetes!' });
});
app.get('/health', (req, res) => {
res.status(200).send('OK');
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
Важно добавить эндпоинт /health — Kubernetes будет использовать его для проверки работоспособности (liveness probe).
Теперь создадим Dockerfile в корне проекта:
FROM node:18-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
Соберите образ и проверьте его локально:
docker build -t my-node-app:latest .
docker run -p 3000:3000 my-node-app:latest
Откройте http://localhost:3000 — вы должны увидеть JSON-ответ.
2. Основные манифесты Kubernetes для Node.js
Kubernetes работает с декларативными конфигурациями (YAML). Для деплоя Node.js приложения нам понадобятся как минимум два основных ресурса: Deployment и Service.
2.1. Deployment
Deployment управляет репликами вашего приложения. Создайте файл 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: my-node-app:latest
ports:
- containerPort: 3000
env:
- name: PORT
value: "3000"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 3
periodSeconds: 5
Важные моменты:
replicas: 3— Kubernetes создаст 3 копии вашего приложения для отказоустойчивости.livenessProbe— проверяет, живо ли приложение. Если ответа нет, Kubernetes перезапустит контейнер.readinessProbe— проверяет, готово ли приложение принимать трафик. Пока проверка не пройдена, под не получает запросы.
2.2. Service
Service обеспечивает сетевой доступ к подам. Создайте 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
Тип ClusterIP делает сервис доступным только внутри кластера. Для внешнего доступа используйте NodePort или LoadBalancer, но в production чаще применяют Ingress.
3. Деплой и проверка в кластере
Предположим, у вас уже есть работающий кластер Kubernetes (например, Minikube для локальной разработки или managed-кластер в облаке).
Примените манифесты:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
Проверьте статус:
kubectl get pods
kubectl get deployments
kubectl get services
Если все прошло успешно, вы увидите три работающих пода и сервис. Чтобы протестировать приложение локально (на Minikube), выполните:
minikube service node-app-service
Эта команда откроет браузер с адресом вашего приложения. Если вы используете облачный кластер, настройте Ingress (см. следующий раздел).
4. Настройка Ingress и переменных окружения
Для внешнего доступа к приложению по доменному имени используйте Ingress. Это как «умный» роутер, который направляет трафик к нужным сервисам.
Создайте файл ingress.yaml:
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
Примените манифест: kubectl apply -f ingress.yaml. Не забудьте настроить DNS-запись, указывающую на IP вашего Ingress-контроллера.
4.1. Переменные окружения (ConfigMap и Secrets)
Хранить конфиденциальные данные (пароли, API-ключи) в манифестах — плохая практика. Используйте