نشر Kubernetes
Kubernetes هو نظام تشغيل لتنسيق الحاويات—مع التحجيم التلقائي والتحديثات المتداولة وقدرات الشفاء الذاتي—مما يضمن بقاء التطبيقات متاحة دائمًا.
1. ما ستتعلمه
- K8s Deployment وReplicaSet: استراتيجيات التحديثات المتداولة والتراجع
- أنواع Service (ClusterIP / NodePort / LoadBalancer) وتوجيه Ingress
- ConfigMap / Secret: إدارة تهيئة التطبيق والمعلومات الحساسة
- مجسات Liveness/Readiness وفحوصات الصحة
- Bob يستخدم Helm Charts لإدارة تهيئة نشر K8s لـ OrderFlow
2. قصة حقيقية لعمليات السحابة الأصلية
(1) نقطة الألم: العمليات اليدوية تغرق
بيئة الإنتاج لـ OrderFlow تعمل على ثلاثة خوادم، وBob يدير حاويات Docker يدويًا على كل خادم. عندما تعطل أحد الخوادم، بدأ Bob حاوية جديدة يدويًا على خادم آخر في الساعة 3 صباحًا. خلال أحداث المبيعات الكبيرة، يلزم التحجيم. يبدأ Bob حاويات إضافية يدويًا ثم يهيئ موازنة التحميل؛ كل عملية تحجيم تستغرق 30 دقيقة. يطلب Charlie التحجيم التلقائي، لكن Bob يقول، "لا أستطيع فعل ذلك."
(2) حل Kubernetes
تهيئة تعريفية في K8s، إدارة آلية:
apiVersion: apps/v1
kind: Deployment
metadata:
name: orderflow
spec:
replicas: 3
template:
spec:
containers:
- name: orderflow
image: orderflow-service:latest
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
العقدة معطلة؟ يعيد K8s تشغيل Pod تلقائيًا على عقدة أخرى. ذروة حركة المرور؟ يقوم HPA بالتحجيم التلقائي.
(3) الإيرادات
بعد أن نشر Bob OrderFlow باستخدام K8s: أعطال العقد يتم استردادها تلقائيًا (انخفض MTTR من ساعتين إلى 30 ثانية)، وHPA يقوم بالتحجيم التلقائي (انخفض وقت التحجيم من 30 دقيقة إلى دقيقتين). لم يعد Bob يضطر لإصلاح الخوادم في منتصف الليل.
3. موارد K8s الأساسية
(1) تبعيات الموارد
graph TD
A[Ingress<br/>الوصول الخارجي] --> B[Service<br/>موازن حمل داخلي]
B --> C[Deployment<br/>قالب Pod]
C --> D[ReplicaSet<br/>نسخ Pod]
D --> E[Pod<br/>مجموعة حاويات]
E --> F[Container<br/>تطبيق OrderFlow]
G[ConfigMap] --> F
H[Secret] --> F
| المورد | المسؤوليات | التشبيه |
|---|---|---|
| Pod | أصغر وحدة نشر، تحتوي على حاويات | مجموعة عمليات |
| Deployment | إدارة عدد نسخ Pod وسياسات التحديث | مدير العمليات |
| Service | يوفر نقطة وصول مستقرة لـ Pods | موازن حمل |
| Ingress | قواعد توجيه HTTP | وكيل عكسي Nginx |
| ConfigMap | تهيئة غير حساسة | ملف تهيئة |
| Secret | تهيئة حساسة | ملف تهيئة مشفر |
4. Deployment والتحديثات المتداولة
(1) ▶ مثال: نشر OrderFlow
apiVersion: apps/v1
kind: Deployment
metadata:
name: orderflow
labels:
app: orderflow
spec:
replicas: 3
selector:
matchLabels:
app: orderflow
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
template:
metadata:
labels:
app: orderflow
spec:
containers:
- name: orderflow
image: registry.example.com/orderflow-service:1.0.0
ports:
- containerPort: 8080
- containerPort: 8081
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: orderflow-config
key: database.host
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: orderflow-secrets
key: database.password
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
الناتج:
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
| المعامل (التحديث المتداول) | المعنى | القيمة الموصى بها |
|---|---|---|
maxUnavailable |
الحد الأقصى لعدد Pods غير المتاحة | 1 (أو 25%) |
maxSurge |
الحد الأقصى لعدد النسخ التي تتجاوز الهدف | 1 (أو 25%) |
(2) ▶ مثال: التحديثات المتداولة والتراجع
# تحديث إصدار الصورة (يحفز تحديثًا متداولًا)
kubectl set image deployment/orderflow orderflow=registry.example.com/orderflow-service:2.0.0
# التحقق من حالة النشر
kubectl rollout status deployment/orderflow
# التراجع إلى الإصدار السابق
kubectl rollout undo deployment/orderflow
# عرض تاريخ النشر
kubectl rollout history deployment/orderflow
الناتج:
# تم تنفيذ الأمر بنجاح
5. Service وIngress
(1) ▶ مثال: تعريف Service
# خدمة ClusterIP (وصول داخلي)
apiVersion: v1
kind: Service
metadata:
name: orderflow
spec:
selector:
app: orderflow
ports:
- name: http
port: 80
targetPort: 8080
- name: management
port: 8081
targetPort: 8081
type: ClusterIP
الناتج:
تم تطبيق التهيئة بنجاح
| نوع الخدمة | نطاق الوصول | السيناريوهات المطبقة |
|---|---|---|
| ClusterIP | داخل المجموعة | استدعاءات بين الخدمات المصغرة |
| NodePort | خارج المجموعة (IP العقدة:المنفذ) | وصول خارجي بسيط |
| LoadBalancer | موازن حمل مزود السحابة | بيئة الإنتاج (السحابة) |
| ExternalName | DNS CNAME | الإشارة إلى خدمة خارجية |
(2) ▶ مثال: توجيه Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orderflow-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: api.orderflow.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: orderflow
port:
number: 80
tls:
- hosts:
- api.orderflow.example.com
secretName: orderflow-tls
الناتج:
Deployment.apps/my-app created
Service/my-app-service exposed
Ingress/my-app-ingress created
6. ConfigMap وSecret
(1) ▶ مثال: ConfigMap وSecret
# ConfigMap: تهيئة غير حساسة
apiVersion: v1
kind: ConfigMap
metadata:
name: orderflow-config
data:
database.host: "mysql-service"
database.name: "orderflow"
redis.host: "redis-service"
spring.profiles.active: "prod"
management.server.port: "8081"
---
# Secret: تهيئة حساسة (مشفرة بـ base64)
apiVersion: v1
kind: Secret
metadata:
name: orderflow-secrets
type: Opaque
data:
database.password: b3JkZXJmbG93MTIz # base64 لـ "orderflow123"
redis.password: cmVkaXNwYXNz # base64 لـ "redispass"
jwt.private-key: LS0tLS1CRUdJTi... # base64 للمفتاح الخاص
الناتج:
تم تطبيق التهيئة بنجاح
| البُعد | ConfigMap | Secret |
|---|---|---|
| نوع البيانات | نص عادي | مشفر بـ Base64 |
| المحتوى المطبق | تهيئة غير حساسة | كلمات المرور، المفاتيح، الشهادات |
| طريقة التخزين | etcd (نص عادي) | etcd (مشفر) |
| حد الحجم | 1MB | 1MB |
7. مجسات Liveness وReadiness
(1) ▶ مثال: تهيئة المجسات
spec:
containers:
- name: orderflow
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
startupProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
الناتج:
أصبحت التهيئة سارية المفعول.
# application-prod.yml: تفعيل مجموعات liveness/readiness
management:
endpoint:
health:
show-details: always
group:
liveness:
include: livenessState
readiness:
include: readinessState, db, redis
| نوع المسبار | الغرض | عواقب الفشل |
|---|---|---|
livenessProbe |
التحقق من تشغيل العملية | إعادة تشغيل الحاوية |
readinessProbe |
التحقق من الجاهزية لاستقبال حركة المرور | الإزالة من Service |
startupProbe |
التحقق من انتهاء تشغيل التطبيق | تعطيل المجسات الأخرى أثناء التشغيل |
8. مثال شامل: نشر OrderFlow الكامل على K8s
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: orderflow
---
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: orderflow-config
namespace: orderflow
data:
SPRING_PROFILES_ACTIVE: "prod"
DB_HOST: "mysql-service"
DB_NAME: "orderflow"
REDIS_HOST: "redis-service"
MANAGEMENT_SERVER_PORT: "8081"
---
# k8s/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: orderflow-secrets
namespace: orderflow
type: Opaque
data:
DB_PASSWORD: b3JkZXJmbG93MTIz
---
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: orderflow
namespace: orderflow
spec:
replicas: 3
selector:
matchLabels: { app: orderflow }
strategy:
rollingUpdate: { maxUnavailable: 1, maxSurge: 1 }
template:
metadata:
labels: { app: orderflow }
spec:
containers:
- name: orderflow
image: registry.example.com/orderflow-service:1.0.0
ports:
- { containerPort: 8080 }
- { containerPort: 8081 }
envFrom:
- configMapRef: { name: orderflow-config }
- secretRef: { name: orderflow-secrets }
resources:
requests: { memory: "512Mi", cpu: "250m" }
limits: { memory: "1Gi", cpu: "500m" }
livenessProbe:
httpGet: { path: /actuator/health/liveness, port: 8080 }
initialDelaySeconds: 60; periodSeconds: 30; failureThreshold: 3
readinessProbe:
httpGet: { path: /actuator/health/readiness, port: 8080 }
initialDelaySeconds: 30; periodSeconds: 10; failureThreshold: 3
---
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
name: orderflow
namespace: orderflow
spec:
selector: { app: orderflow }
ports:
- { name: http, port: 80, targetPort: 8080 }
type: ClusterIP
---
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: orderflow-ingress
namespace: orderflow
spec:
ingressClassName: nginx
rules:
- host: api.orderflow.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service: { name: orderflow, port: { number: 80 } }
❓ أسئلة شائعة
maxUnavailable في استراتيجية التحديث المتداول إلى 0؛ 3) استخدم خطاف preStop للإيقاف الأنيق (sleep 10—انتظر تصريف حركة المرور)؛ 4) نفذ إيقافًا أنيقًا في التطبيق (server.shutdown=graceful).kubectl describe pod <name> تحقق من الأحداث؛ 2) kubectl logs <name> تحقق من سجلات الحاوية؛ 3) kubectl get events --sort-by=.metadata.creationTimestamp تحقق من أحداث المجموعة.📖 ملخص
- يدير Deployment نسخ Pod والتحديثات المتداولة؛ maxUnavailable وmaxSurge يتحكمان في وتيرة التحديث
- Service: يوفر نقطة وصول مستقرة إلى Pods—داخليًا عبر ClusterIP، خارجيًا عبر LoadBalancer
- Ingress يهيئ توجيه HTTP وTLS، وهو ما يعادل وكيلًا عكسيًا في K8s
- تُستخدم ConfigMaps لإدارة التهيئة غير الحساسة، بينما تُستخدم Secrets لإدارة المعلومات الحساسة (مشفرة بـ Base64)
- مجسات Liveness وReadiness وStartup تراقب حالات الحياة والجاهزية والتشغيل على التوالي
- تهيئة تعريفية + تحديثات متداولة = نشر بدون توقف
📝 تمارين
-
تمرين أساسي (الصعوبة: ⭐): اكتب ملفات YAML لـ Deployment وService لـ OrderFlow، وانشرها في مجموعة K8s محلية (minikube أو kind)، وتحقق من إمكانية الوصول إلى التطبيق.
-
تمرين متقدم (الصعوبة: ⭐⭐): أضف تهيئات ConfigMap وSecret وIngress لتمكين الوصول عبر نطاق خارجي. هيئ مجسات Liveness وReadiness لمحاكاة فشل Pod والتحقق من الاسترداد التلقائي.
-
تحدٍ (الصعوبة: ⭐⭐⭐): استخدم Helm Chart لإدارة نشر K8s لـ OrderFlow، مع دعم استبدال المتغيرات عبر
values.yaml(إصدار الصورة، عدد النسخ، تهيئة الموارد)، ونفذ تحديثات متداولة عبرhelm upgradeوتراجعات عبرhelm rollback.



