النشر على Kubernetes
يُنشئ FORGE ملفات Kubernetes manifests جاهزة للإنتاج مع health probes وحدود الموارد والتوسع الأفقي التلقائي وتوفير شهادات TLS آلياً عبر cert-manager. هذه هي استراتيجية النشر المُوصى بها للتطبيقات التي تحتاج التوسع التلقائي والشفاء الذاتي والتحديثات المتدرجة وموازنة الحمل.
توليد Kubernetes Manifests
forge deploy:k8s \
--env=production \
--ssl=letsencrypt \
--email=admin@example.comخيارات الأمر
| الخيار | النوع | الافتراضي | الوصف |
|---|---|---|---|
--env | string | production | البيئة المستهدفة: staging أو production |
--domain | string | من forge.yaml | نطاق الإنتاج (مثل myapp.com) |
--ssl | string | letsencrypt | طريقة SSL: letsencrypt أو custom أو none |
--email | string | مطلوب لـ LE | البريد الإلكتروني لإشعارات Let's Encrypt |
--replicas | number | 2 | عدد نسخ pod لكل خدمة |
--namespace | string | {app-name} | Kubernetes namespace |
--registry | string | docker.io | سجل صور الحاويات |
--output | string | ./k8s | مجلد الإخراج للـ manifests |
أمثلة
forge deploy:k8s \
--env=production \
--domain=myapp.com \
--ssl=letsencrypt \
--email=admin@myapp.com \
--replicas=3 \
--namespace=myapp-prod \
--registry=ghcr.io/myorgforge deploy:k8s \
--env=staging \
--domain=staging.myapp.com \
--ssl=letsencrypt \
--email=admin@myapp.com \
--replicas=1 \
--namespace=myapp-stagingforge deploy:k8s \
--env=production \
--output=./infrastructure/k8s/productionبنية الملفات المُولّدة
k8s/
├── namespace.yaml # تعريف Namespace
├── configmap.yaml # الإعدادات غير الحساسة
├── secrets.yaml # البيانات الحساسة (مُشفّرة base64)
│
├── api/
│ ├── deployment.yaml # pods الـ API مع health probes
│ ├── service.yaml # خدمة ClusterIP للـ API
│ └── hpa.yaml # Horizontal Pod Autoscaler
│
├── web/
│ ├── deployment.yaml # pods تطبيق الويب
│ ├── service.yaml # خدمة ClusterIP للويب
│ └── hpa.yaml # Horizontal Pod Autoscaler
│
├── admin/
│ ├── deployment.yaml # pods تطبيق الإدارة
│ ├── service.yaml # خدمة ClusterIP للإدارة
│ └── hpa.yaml # Horizontal Pod Autoscaler
│
├── ingress.yaml # Ingress مع TLS termination
│
├── cert-manager/
│ ├── cluster-issuer.yaml # Let's Encrypt ClusterIssuer
│ └── certificate.yaml # طلب شهادة TLS
│
├── postgres/
│ ├── deployment.yaml # PostgreSQL (أو استخدم DB مُدارة)
│ ├── service.yaml # خدمة قاعدة البيانات
│ └── pvc.yaml # Persistent Volume Claim
│
├── redis/
│ ├── deployment.yaml # Redis cache
│ └── service.yaml # خدمة Redis
│
└── kustomization.yaml # Kustomize للنشر الموحّدAPI Deployment
الـ API deployment يتضمن health probes وحدود الموارد وإعدادات البيئة:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-api
namespace: myapp
labels:
app: myapp
component: api
spec:
replicas: 2
selector:
matchLabels:
app: myapp
component: api
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
template:
metadata:
labels:
app: myapp
component: api
spec:
containers:
- name: api
image: ghcr.io/myorg/myapp-api:latest
ports:
- containerPort: 8080
protocol: TCP
envFrom:
- configMapRef:
name: myapp-config
- secretRef:
name: myapp-secrets
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 2
startupProbe:
httpGet:
path: /health
port: 8080
failureThreshold: 30
periodSeconds: 2نقاط نهاية Health probe
الـ API المُولّد يتضمن ثلاث نقاط نهاية للصحة:
/health-- فحص liveness أساسي (هل العملية تعمل؟)/ready-- فحص readiness (هل الخدمة تقبل حركة المرور؟ يتحقق من اتصال قاعدة البيانات)/startup-- يُستخدم بواسطة startup probe للسماح بوقت تهيئة أطول
Ingress مع Let's Encrypt
مورد Ingress يوجّه حركة المرور للخدمة الصحيحة بناءً على اسم المضيف ويُعدّ TLS مع cert-manager:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
namespace: myapp
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
spec:
tls:
- hosts:
- myapp.com
- admin.myapp.com
- api.myapp.com
secretName: myapp-tls
rules:
- host: myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-web
port:
number: 3000
- host: admin.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-admin
port:
number: 3001
- host: api.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-api
port:
number: 8080إعدادات cert-manager
cert-manager يُؤتمت إصدار شهادات TLS وتجديدها من Let's Encrypt.
ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: admin@myapp.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-account-key
solvers:
- http01:
ingress:
class: nginxCertificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: myapp-tls
namespace: myapp
spec:
secretName: myapp-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- myapp.com
- admin.myapp.com
- api.myapp.comثبّت cert-manager أولاً
يجب تثبيت cert-manager في الـ cluster قبل تطبيق هذه الـ manifests:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.14.0/cert-manager.yaml
# Wait for cert-manager pods to be ready
kubectl wait --for=condition=ready pod \
-l app.kubernetes.io/instance=cert-manager \
-n cert-manager --timeout=120sHorizontal Pod Autoscaler
كل خدمة تتضمن HPA يوسّع pods بناءً على استخدام CPU والذاكرة:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-api-hpa
namespace: myapp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-api
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 2
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Pods
value: 1
periodSeconds: 120ConfigMap و Secrets
الإعدادات غير الحساسة تذهب في ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
namespace: myapp
data:
APP_NAME: myapp
RUST_LOG: info
API_PORT: "8080"
DB_HOST: myapp-postgres
DB_PORT: "5432"
DB_NAME: myapp
REDIS_URL: redis://myapp-redis:6379القيم الحساسة تذهب في Secret:
apiVersion: v1
kind: Secret
metadata:
name: myapp-secrets
namespace: myapp
type: Opaque
data:
DB_USER: bXlhcHA= # مُشفّر base64
DB_PASSWORD: c3Ryb25nLXBhc3N3b3Jk # مُشفّر base64
JWT_SECRET: ... # مُشفّر base64
FORGE_ENCRYPTION_KEY: ... # مُشفّر base64لا تُرسل الأسرار إلى نظام التحكم بالإصدارات
ملف secrets.yaml المُولّد يحتوي قيم بديلة. استبدلها ببيانات اعتماد حقيقية مُشفّرة بـ base64 قبل التطبيق. ضع في اعتبارك استخدام أداة إدارة أسرار مثل Sealed Secrets أو External Secrets Operator للإنتاج.
# تشفير قيمة للاستخدام في secrets.yaml
echo -n "my-strong-password" | base64النشر على الـ Cluster
تطبيق جميع الـ manifests مع Kustomize
# Apply everything at once
kubectl apply -k ./k8s/النشر خطوة بخطوة
# 1. Create namespace
kubectl apply -f k8s/namespace.yaml
# 2. Apply configs and secrets
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/secrets.yaml
# 3. Deploy cert-manager resources
kubectl apply -f k8s/cert-manager/
# 4. Deploy databases
kubectl apply -f k8s/postgres/
kubectl apply -f k8s/redis/
# 5. Wait for databases to be ready
kubectl wait --for=condition=ready pod \
-l component=postgres -n myapp --timeout=120s
# 6. Deploy application services
kubectl apply -f k8s/api/
kubectl apply -f k8s/web/
kubectl apply -f k8s/admin/
# 7. Apply ingress
kubectl apply -f k8s/ingress.yamlالتحقق من النشر
# Verify all pods are running
kubectl get pods -n myapp
# Check services
kubectl get svc -n myapp
# Check ingress and TLS
kubectl get ingress -n myapp
kubectl get certificate -n myapp
# View API logs
kubectl logs -f deployment/myapp-api -n myapp
# Run migrations
kubectl exec -it deployment/myapp-api -n myapp -- \
./forge-cli migrate
# Seed data
kubectl exec -it deployment/myapp-api -n myapp -- \
./forge-cli seedالتحديثات المتدرجة
# Update API image
kubectl set image deployment/myapp-api \
api=ghcr.io/myorg/myapp-api:v1.1.0 -n myapp
# Monitor rollout progress
kubectl rollout status deployment/myapp-api -n myapp
# Rollback if needed
kubectl rollout undo deployment/myapp-api -n myappاعتبارات الإنتاج
استخدم قاعدة بيانات مُدارة
لأحمال العمل الإنتاجية، استبدل PostgreSQL deployment بخدمة قاعدة بيانات مُدارة (AWS RDS أو Google Cloud SQL أو Azure Database for PostgreSQL). حدّث ConfigMap بتفاصيل اتصال قاعدة البيانات المُدارة وأزل manifests الـ k8s/postgres/.
ضبط الموارد
طلبات وحدود الموارد الافتراضية هي نقاط بداية. راقب pods الخاصة بك بـ kubectl top pods -n myapp واضبط بناءً على الاستخدام الفعلي.
| الخدمة | طلب CPU | حد CPU | طلب الذاكرة | حد الذاكرة |
|---|---|---|---|---|
| API | 100m | 500m | 256Mi | 512Mi |
| Web | 100m | 300m | 256Mi | 512Mi |
| Admin | 100m | 300m | 256Mi | 512Mi |
| PostgreSQL | 250m | 1000m | 512Mi | 1Gi |
| Redis | 50m | 200m | 128Mi | 256Mi |
المراقبة
تكامل مع stack المراقبة في الـ cluster:
# View resource usage
kubectl top pods -n myapp
# View HPA status
kubectl get hpa -n myapp
# View events for troubleshooting
kubectl get events -n myapp --sort-by='.lastTimestamp'الخطوات التالية
- النشر باستخدام Docker Compose -- نشر خادم واحد أبسط
- النشر عبر SSH -- النشر بدون حاويات
- شهادات SSL -- خيارات إعدادات SSL مُفصّلة