Ответ
Я деплою Node.js приложения в Kubernetes по следующему паттерну, уделяя внимание безопасности, наблюдаемости и отказоустойчивости.
1. Создание Docker-образа:
# Использую многостадийную сборку для минимизации образа
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build # если есть сборка (TypeScript, React и т.д.)
FROM node:18-alpine
WORKDIR /app
ENV NODE_ENV=production
USER node # Запуск от непривилегированного пользователя
COPY --from=builder --chown=node:node /app/package*.json ./
COPY --from=builder --chown=node:node /app/node_modules ./node_modules
COPY --from=builder --chown=node:node /app/dist ./dist # или /app для простых приложений
EXPOSE 3000
CMD ["node", "dist/server.js"]
2. Манифесты Kubernetes:
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-app
labels:
app: nodejs-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: nodejs-app
template:
metadata:
labels:
app: nodejs-app
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "3000"
spec:
containers:
- name: app
image: my-registry.example.com/nodejs-app:v1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
name: http
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "3000"
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
service.yaml (ClusterIP для внутреннего трафика):
apiVersion: v1
kind: Service
metadata:
name: nodejs-app-service
spec:
selector:
app: nodejs-app
ports:
- port: 80
targetPort: 3000
protocol: TCP
type: ClusterIP
3. Деплой и управление:
- Храню манифесты в Git.
- Использую
kubectl apply -f k8s/. - Для управления секретами —
SealedSecretsили внешний Vault. - Настраиваю Horizontal Pod Autoscaler (HPA) на основе CPU/памяти или кастомных метрик Prometheus.
- Внешний доступ настраиваю через Ingress-контроллер (nginx-ingress, traefik) с TLS-терминацией.
- Настраиваю сбор логов приложения (stdout/stderr) через DaemonSet с Fluent Bit и метрик через Prometheus.