انتقل إلى المحتوى الرئيسي

الفصل 7.1 - StatefulSets المتعمق

أهداف التعلم​

في نهاية هذا الفصل، ستكون قادرًا على:

  • فهم StatefulSets بعمق
  • نشر قواعد البيانات باستخدام StatefulSets
  • إدارة التوسع والتحديثات
  • فهم الحاويات التمهيدية في StatefulSets
  • تنفيذ النسخ المتماثل الرئيسي-التابع
  • إدارة النصاب القانوني وانتخاب القائد

مقدمة​

تعتبر StatefulSets أساسية للتطبيقات ذات الحالة. يعمق هذا الفصل في المفاهيم ويقدم حالات استخدام متقدمة.


بنية StatefulSet​

المكونات​


مثال: قاعدة بيانات PostgreSQL​

الخطوة 1: خدمة بدون رأس​

apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
clusterIP: None
selector:
app: postgres
ports:
- port: 5432
name: postgres

الخطوة 2: ConfigMap للتكوين​

apiVersion: v1
kind: ConfigMap
metadata:
name: postgres-config
data:
postgresql.conf: |
max_connections = 200
shared_buffers = 256MB
effective_cache_size = 1GB

الخطوة 3: Secret للاعتمادات​

apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
type: Opaque
data:
postgres-password: cG9zdGdyZXM= # base64
replication-password: cmVwbGljYXRpb24= # base64

الخطوة 4: StatefulSet​

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgres
spec:
serviceName: postgres
replicas: 3
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
initContainers:
- name: init-postgres
image: postgres:14
command:
- /bin/bash
- -c
- |
set -e
if [[ $HOSTNAME == "postgres-0" ]]; then
echo "Initializing primary database..."
else
echo "Waiting for primary to be ready..."
until pg_isready -h postgres-0.postgres; do
sleep 1
done
fi
env:
- name: PGHOST
value: postgres-0.postgres
containers:
- name: postgres
image: postgres:14
env:
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: postgres-password
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
ports:
- containerPort: 5432
name: postgres
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data
- name: postgres-config
mountPath: /etc/postgresql
volumes:
- name: postgres-config
configMap:
name: postgres-config
volumeClaimTemplates:
- metadata:
name: postgres-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "fast-ssd"
resources:
requests:
storage: 50Gi

الحاويات التمهيدية​

تعمل الحاويات التمهيدية قبل الحاويات الرئيسية ويمكنها:

  • تهيئة قاعدة البيانات
  • انتظار جاهزية الخدمات الأخرى
  • إعداد البيئة
  • التحقق من التبعيات

مثال:

spec:
template:
spec:
initContainers:
- name: wait-for-db
image: busybox:1.35
command:
- sh
- -c
- |
until nc -z postgres-0.postgres 5432; do
echo "Waiting for database..."
sleep 2
done
containers:
- name: app
image: my-app:1.0

النسخ المتماثل الرئيسي-التابع​

البنية​

التكوين:

spec:
template:
spec:
containers:
- name: postgres
env:
- name: POSTGRES_REPLICATION_MODE
value: "master" # لـ postgres-0
- name: POSTGRES_MASTER_HOST
value: "postgres-0.postgres" # لـ postgres-1, postgres-2

النصاب القانوني وانتخاب القائد​

للتطبيقات التي تتطلب نصابًا قانونيًا (مثل etcd، Consul):

apiVersion: apps/v1
kind: StatefulSet
metadata:
name: etcd
spec:
serviceName: etcd
replicas: 3 # النصاب: (3/2) + 1 = 2
template:
spec:
containers:
- name: etcd
image: quay.io/coreos/etcd:v3.5.0
env:
- name: ETCD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ETCD_INITIAL_CLUSTER
value: "etcd-0=http://etcd-0.etcd:2380,etcd-1=http://etcd-1.etcd:2380,etcd-2=http://etcd-2.etcd:2380"

النصاب القانوني: (N/2) + 1، حيث N = عدد النسخ


التوسع​

التوسع لأعلى​

kubectl scale statefulset postgres --replicas=5

العملية:

  1. إنشاء postgres-3
  2. انتظار جاهزية postgres-3
  3. إنشاء postgres-4
  4. انتظار جاهزية postgres-4

التوسع لأسفل​

kubectl scale statefulset postgres --replicas=2

العملية:

  1. حذف postgres-4 (الأخير)
  2. انتظار انتهاء postgres-4
  3. حذف postgres-3
  4. انتظار انتهاء postgres-3

مهم: بالنسبة لقواعد البيانات، تأكد من حفظ البيانات قبل التوسع لأسفل.


التحديثات​

التحديث المتداول​

spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0 # تحديث جميع الـ Pods

العملية:

  1. تحديث postgres-2 (الأخير)
  2. تحديث postgres-1
  3. تحديث postgres-0 (الأول)

تحديث جزئي (Canary)​

spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 2 # الاحتفاظ بـ postgres-0 و postgres-1 على الإصدار القديم

النتيجة: فقط postgres-2 يتم تحديثه.


الأوامر المفيدة​

الإدارة​

# عرض StatefulSets
kubectl get statefulset
kubectl get sts

# التفاصيل
kubectl describe statefulset postgres

# عرض الـ Pods
kubectl get pods -l app=postgres

# سجلات Pod محدد
kubectl logs postgres-0

التوسع​

# التوسع لأعلى
kubectl scale statefulset postgres --replicas=5

# التوسع لأسفل
kubectl scale statefulset postgres --replicas=2

التحديثات​

# تحديث الصورة
kubectl set image statefulset/postgres postgres=postgres:15

# عرض حالة التحديث
kubectl rollout status statefulset/postgres

# التراجع
kubectl rollout undo statefulset/postgres

الممارسات الجيدة​

1. النسخ الاحتياطي المنتظم​

إعداد النسخ الاحتياطي التلقائي للأحجام.

2. المراقبة​

مراقبة حالة كل Pod ومقاييس الأداء.

3. النصاب القانوني المناسب​

استخدام عدد فردي من النسخ لتجنب التعادلات.

4. الحاويات التمهيدية​

استخدام الحاويات التمهيدية للتهيئة والتحقق.

5. خدمة بدون رأس​

دائمًا إنشاء خدمة بدون رأس لاكتشاف DNS.


الملخص​

في هذا الفصل، تعلمت:

StatefulSets المتعمق: التطبيقات ذات الحالة مع هويات ثابتة
قواعد البيانات: نشر PostgreSQL مع النسخ المتماثل
الحاويات التمهيدية: التهيئة قبل الحاويات الرئيسية
النسخ المتماثل: تكوين الرئيسي-التابع
النصاب القانوني: الحساب والتكوين للتطبيقات الموزعة
التوسع: ترتيب مضمون (تصاعدي/تنازلي)
التحديثات: RollingUpdate وتحديثات جزئية
الممارسات الجيدة: النسخ الاحتياطي، المراقبة، النصاب القانوني


الخطوات التالية​

الفصل 7.2: DaemonSets
الفصل 7.3: Jobs
الفصل 7.4: CronJobs


الفصل تم إنشاؤه في: ديسمبر 2024