راهنمای استقرار در Kubernetes: از توسعه تا Production
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: ClusterIPIngress برای دسترسی از بیرون
# 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: 10GiStatefulSet برای دیتابیسها
# 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: 30sPrometheusRule برای هشدارها
# 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.tplvalues.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