SEPEHR.SYS

Starting SEPEHR.SYS…

Loading

سپهر محسنی

مهندس نرم‌افزار فول‌استک و هوش مصنوعی

NOTES.TXT ×

راهنمای استقرار در Kubernetes: از توسعه تا Production

5′ · ۱۴ دی ۱۴۰۴

Kubernetes به استاندارد ارکستریشن کانتینرها تبدیل شده است. این راهنما استقرار اپلیکیشن‌ها روی Kubernetes را با پیکربندی‌های آمادهٔ Production پوشش می‌دهد؛ از استقرارهای پایه تا الگوهای پیشرفته.

مفاهیم پایهٔ Kubernetes

پیش از آنکه سراغ استقرار برویم، این مفاهیم کلیدی را بشناسید:

  • Pod - کوچک‌ترین واحد قابل استقرار؛ شامل یک یا چند کانتینر
  • Deployment - ReplicaSet‌ها را مدیریت می‌کند و امکان به‌روزرسانی اعلانی (Declarative) را فراهم می‌آورد
  • Service - Pod‌ها را در معرض ترافیک شبکه قرار می‌دهد
  • ConfigMap/Secret - پیکربندی خارجی و داده‌های حساس
  • Ingress - مسیریابی HTTP و توزیع بار (Load Balancing)

<Callout type="info"> Kubernetes از یک مدل اعلانی پیروی می‌کند؛ شما وضعیت مطلوب را توصیف می‌کنید و Kubernetes برای حفظ آن تلاش می‌کند. </Callout>

استقرار پایه

مانیفست Deployment

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: myregistry/my-app:1.0.0
          ports:
            - containerPort: 3000
          resources:
            requests:
              memory: "128Mi"
              cpu: "100m"
            limits:
              memory: "256Mi"
              cpu: "500m"
          env:
            - name: NODE_ENV
              value: "production"
            - name: DATABASE_URL
              valueFrom:
                secretKeyRef:
                  name: my-app-secrets
                  key: database-url
          livenessProbe:
            httpGet:
              path: /health
              port: 3000
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /ready
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 5

پیکربندی Service

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: ClusterIP

Ingress برای دسترسی از بیرون

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rate-limit: "100"
spec:
  tls:
    - hosts:
        - myapp.example.com
      secretName: my-app-tls
  rules:
    - host: myapp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-service
                port:
                  number: 80

مدیریت پیکربندی

ConfigMap‌ها

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-app-config
data:
  APP_NAME: "My Application"
  LOG_LEVEL: "info"
  CACHE_TTL: "3600"
  config.json: |
    {
      "features": {
        "newUI": true,
        "analytics": true
      },
      "limits": {
        "maxUploadSize": 10485760
      }
    }

Secret‌ها

# secrets.yaml
apiVersion: v1
kind: Secret
metadata:
  name: my-app-secrets
type: Opaque
stringData:
  database-url: "postgresql://user:pass@host:5432/db"
  api-key: "sk_live_xxxxx"
  jwt-secret: "your-jwt-secret"

<Note title="نکتهٔ امنیتی"> هرگز Secret‌ها را در سیستم کنترل نسخه commit نکنید. از ابزارهایی مانند Sealed Secrets، External Secrets Operator یا سرویس‌های مدیریت Secret ارائه‌دهندگان ابری استفاده کنید. </Note>

استفاده از ConfigMap‌ها و Secret‌ها

# deployment.yaml (partial)
spec:
  containers:
    - name: my-app
      envFrom:
        - configMapRef:
            name: my-app-config
        - secretRef:
            name: my-app-secrets
      volumeMounts:
        - name: config-volume
          mountPath: /app/config
          readOnly: true
  volumes:
    - name: config-volume
      configMap:
        name: my-app-config
        items:
          - key: config.json
            path: config.json

مقیاس‌گذاری خودکار افقی Pod‌ها (Horizontal Pod Autoscaling)

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 3
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 10
          periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0
      policies:
        - type: Percent
          value: 100
          periodSeconds: 15
        - type: Pods
          value: 4
          periodSeconds: 15
      selectPolicy: Max

به‌روزرسانی تدریجی (Rolling Update) و بازگردانی (Rollback)

استراتژی استقرار

# deployment.yaml (partial)
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%        # Max pods above desired count
      maxUnavailable: 25%  # Max pods unavailable during update

دستورات Rollback

# View rollout history
kubectl rollout history deployment/my-app

# Rollback to previous version
kubectl rollout undo deployment/my-app

# Rollback to specific revision
kubectl rollout undo deployment/my-app --to-revision=2

# Check rollout status
kubectl rollout status deployment/my-app

سیاست‌های شبکه (Network Policy)

# network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: my-app-network-policy
spec:
  podSelector:
    matchLabels:
      app: my-app
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              name: production
        - podSelector:
            matchLabels:
              app: nginx-ingress
      ports:
        - protocol: TCP
          port: 3000
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: postgres
      ports:
        - protocol: TCP
          port: 5432
    - to:
        - podSelector:
            matchLabels:
              app: redis
      ports:
        - protocol: TCP
          port: 6379
    # Allow DNS
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53

ذخیره‌سازی پایدار

PersistentVolumeClaim

# pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-app-storage
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 10Gi

StatefulSet برای دیتابیس‌ها

# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:16
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secrets
                  key: password
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: fast-ssd
        resources:
          requests:
            storage: 50Gi

مانیتورینگ با Prometheus

ServiceMonitor

# servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app-monitor
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: my-app
  endpoints:
    - port: http
      path: /metrics
      interval: 30s

PrometheusRule برای هشدارها

# prometheusrule.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: my-app-alerts
spec:
  groups:
    - name: my-app
      rules:
        - alert: HighErrorRate
          expr: |
            sum(rate(http_requests_total{app="my-app",status=~"5.."}[5m])) /
            sum(rate(http_requests_total{app="my-app"}[5m])) > 0.05
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: High error rate detected
            description: Error rate is above 5% for 5 minutes

        - alert: PodCrashLooping
          expr: |
            rate(kube_pod_container_status_restarts_total{pod=~"my-app.*"}[15m]) > 0
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: Pod is crash looping

یکپارچه‌سازی با CI/CD

استقرار با GitHub Actions

# .github/workflows/deploy.yml
name: Deploy to Kubernetes

on:
  push:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Set up kubectl
        uses: azure/setup-kubectl@v3

      - name: Configure kubectl
        run: |
          echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
          export KUBECONFIG=kubeconfig

      - name: Deploy to Kubernetes
        run: |
          kubectl set image deployment/my-app \
            my-app=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
          kubectl rollout status deployment/my-app

ساختار چارت Helm

my-app/
├── Chart.yaml
├── values.yaml
├── values-production.yaml
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   ├── hpa.yaml
│   └── _helpers.tpl

values.yaml

# values.yaml
replicaCount: 3

image:
  repository: myregistry/my-app
  tag: latest
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: myapp.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: my-app-tls
      hosts:
        - myapp.example.com

resources:
  limits:
    cpu: 500m
    memory: 256Mi
  requests:
    cpu: 100m
    memory: 128Mi

autoscaling:
  enabled: true
  minReplicas: 3
  maxReplicas: 20
  targetCPUUtilizationPercentage: 70

جمع‌بندی

Kubernetes ابزارهای قدرتمندی برای استقرار و مدیریت اپلیکیشن‌های کانتینری در مقیاس بزرگ در اختیار شما می‌گذارد. با رعایت این بهترین شیوه‌ها — مدیریت درست منابع، health check‌ها، مقیاس‌گذاری خودکار و سیاست‌های امنیتی — می‌توانید استقرارهایی مقاوم و آمادهٔ Production بسازید.

نکات کلیدی:

  • همیشه مقادیر requests و limits منابع را تعیین کنید
  • health check پیاده‌سازی کنید (پروب‌های liveness و readiness)
  • برای پیکربندی از ConfigMap‌ها و Secret‌ها استفاده کنید
  • برای مقیاس‌گذاری خودکار از HPA استفاده کنید
  • برای امنیت از Network Policy‌ها استفاده کنید
  • با Prometheus مانیتور کنید و هشدارها را تنظیم کنید

این یادداشت ترجمهٔ فارسی نوشتهٔ خودم است — نسخهٔ اصلی (انگلیسی) در dev.to