Деплой JavaScript (Node.js) на Kubernetes: пошаговое руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему 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 для автоматического масштабирования по нагрузке, а также

Блоги

Рекомендаций по книгам