تطوير الويب

تخزين مستمرّ مع Rook-Ceph على Kubernetes خطوة بخطوة

10 دقائق للقراءة

مقال مرتبط · هذا الدليل جزء من سلسلة Kubernetes منزلي على Proxmox VE. الدليل السابق: Cilium CNI eBPF. الدليل التالي: Argo CD GitOps.

دون تخزين مستمرّ، عنقود Kubernetes لا يستطيع تشغيل سوى أحمال بلا حالة: نفقد كلّ البيانات بمجرّد إعادة تشغيل pod. لاستضافة قاعدة PostgreSQL، أو Vaultwarden، أو Nextcloud، أو MinIO، يلزم مزوِّد CSI (Container Storage Interface) يُنتج volumes مستمرّة عند الطلب. Rook هو مُشَغِّل Kubernetes يُنسِّق Ceph — تخزين موزَّع من فئة المؤسّسات — مباشرة داخل العنقود، على أقراص الـ workers. الإصدار 1.19.5 الصادر في ربيع 2026 يدعم Ceph Squid 19.2.0+ وKubernetes 1.30 كحدّ أدنى. يُثبّت هذا الدليل Rook 1.19، ينشر عنقود Ceph بثلاث OSDs، ويعرض StorageClass للكتل RBD، نظام ملفّات مشترك CephFS، وbucket S3 ObjectStore.

الخطوة 1 — تحضير الأقراص على الـ workers

Ceph يتطلّب أقراصًا مخصَّصة، بلا نظام ملفّات ولا تجزئة قائمة. على الـ workers Talos الثلاثة، أضفنا في الدليل السابق قرصًا ثانيًا بـ 32 جيغا (/dev/sdb). تحقّق من نظافة هذه الأقراص من محطّة العمل.

for ip in 192.168.1.71 192.168.1.72 192.168.1.73; do
  echo "=== Worker $ip ==="
  talosctl -n $ip get disks
done
# الخرج يجب إدراج sda (32 جيغا، نظام Talos) وsdb (32 جيغا، فارغ)

إن ظهر sdb بتجزئات سابقة من اختبار، امسحه نظيفًا قبل أن يتبنّاه Rook. الأمر wipefs غير موجود على Talos لانعدام shell، لكنّ Rook يفعل ذلك تلقائيًّا عبر CRD CephCluster.spec.storage.useAllDevices=true شريطة أن يكون القرص غير مُوَنَّت.

الخطوة 2 — تثبيت مُشَغِّل Rook

مُشَغِّل Rook يُثَبَّت عبر Helm من المستودع الرسمي. هو المتحكّم الذي يُفسِّر CRDs CephCluster، CephBlockPool، CephFilesystem، وCephObjectStore.

helm repo add rook-release https://charts.rook.io/release
helm repo update

kubectl create namespace rook-ceph

helm install rook-ceph rook-release/rook-ceph \
  --version v1.19.5 \
  --namespace rook-ceph \
  --set crds.enabled=true \
  --set monitoring.enabled=true \
  --set csi.enableRBDDriver=true \
  --set csi.enableCephFSDriver=true

Helm يُنشئ CRDs، نشر rook-ceph-operator، وحسابات RBAC الضرورية. تحقّق من أنّ المُشَغِّل في Running قبل المتابعة: kubectl get pods -n rook-ceph -w. احسب دقيقة إلى دقيقتين. إن دار الـ pod في CrashLoopBackOff، افحص السجلّات؛ السبب النمطي هو CRD قائم من تثبيت سابق.

الخطوة 3 — إعلان عنقود Ceph

عنقود Ceph يُعلَن عبر CRD CephCluster. المنفست أدناه ينشر ثلاثة moniteurs (واحد لكلّ worker)، ثلاثة مديرين، ويتبنّى تلقائيًّا الأقراص المتاحة.

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    image: quay.io/ceph/ceph:v19.2.3
    allowUnsupported: false
  dataDirHostPath: /var/lib/rook
  skipUpgradeChecks: false
  mon:
    count: 3
    allowMultiplePerNode: false
  mgr:
    count: 2
    modules:
    - name: pg_autoscaler
      enabled: true
  dashboard:
    enabled: true
    ssl: true
  monitoring:
    enabled: true
  storage:
    useAllNodes: false
    useAllDevices: false
    nodes:
    - name: talos-wk-1
      devices:
      - name: sdb
    - name: talos-wk-2
      devices:
      - name: sdb
    - name: talos-wk-3
      devices:
      - name: sdb
kubectl apply -f cephcluster.yaml

# تابع الإقلاع (5 إلى 10 دقائق)
kubectl -n rook-ceph get cephcluster -w
# Phase يتقدّم: Creating ← Failing ← Connecting ← Ready

حين تُبيّن المرحلة Ready، Ceph يعمل. ثلاثة pods rook-ceph-mon، اثنان rook-ceph-mgr، وثلاثة rook-ceph-osd يجب أن تكون في Running. إن لم يُقلِع OSD، تحقّق من وجود القرص الهدف على الـ worker المُقابل وأنّه حرّ.

الخطوة 4 — فحص صحّة عنقود Ceph

Rook يكشف pod toolbox مُجَهَّزًا بـ Ceph CLI. أداة التشخيص الرئيسية لفهم ما يجري على مستوى عنقود Ceph نفسه.

kubectl apply -f \
  https://raw.githubusercontent.com/rook/rook/v1.19.5/deploy/examples/toolbox.yaml

kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- ceph status
# الخرج يجب الإشارة إلى health: HEALTH_OK و3 osds up

رؤية HEALTH_OK مع ثلاثة OSDs up وثلاثة moniteurs in quorum يُؤكِّد أنّ عنقود Ceph سليم. HEALTH_WARN مقبول مؤقّتًا (PGs في طور التوضع مثلًا) لكن لا يجب أن يستمرّ أكثر من بضع دقائق بعد التثبيت.

الخطوة 5 — إنشاء StorageClass للكتل RBD

RBD (RADOS Block Device) هو شكل كتلي لـ Ceph، نظير قرص افتراضي مُلحَق بـ pod. وضع التخزين الأكثر استعمالًا لقواعد البيانات والأحمال التي تتطلّب وصولًا ReadWriteOnce.

apiVersion: ceph.rook.io/v1
kind: CephBlockPool
metadata:
  name: replicapool
  namespace: rook-ceph
spec:
  failureDomain: host
  replicated:
    size: 3
    requireSafeReplicaSize: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-ceph-block
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: rook-ceph.rbd.csi.ceph.com
parameters:
  clusterID: rook-ceph
  pool: replicapool
  imageFormat: "2"
  imageFeatures: layering
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-rbd-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-rbd-node
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
  csi.storage.k8s.io/fstype: ext4
allowVolumeExpansion: true
reclaimPolicy: Delete
kubectl apply -f cephblockpool.yaml

kubectl get sc
# rook-ceph-block يجب أن يظهر بـ "(default)"

الـ StorageClass rook-ceph-block مُعلَنة افتراضية: كلّ PVC يُنشَأ دون storageClassName صريح سيستعملها. التكرار ×3 يضمن بقاء volume قابلًا للوصول حتى إن سقط worker (وهو ما سنختبره لاحقًا).

الخطوة 6 — اختبار توفير volume

الاختبار الكلاسيكي إنشاء PVC، نشر pod يستعمله، كتابة ملفّ، حذف الـ pod، إعادة إنشائه، والتحقّق من بقاء الملفّ.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: app
    image: busybox
    command: ["sh", "-c", "echo persistent-data > /data/hello.txt && sleep 3600"]
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: test-pvc
kubectl apply -f test-pvc.yaml

# تحقّق من ربط PVC بـ PV
kubectl get pvc test-pvc
# STATUS يجب أن يصير Bound بعد بضع ثوانٍ

# اقرأ الملفّ
kubectl exec test-pod -- cat /data/hello.txt
# يجب عرض: persistent-data

# دمِّر الـ pod وأعد إنشاءه
kubectl delete pod test-pod
kubectl apply -f test-pvc.yaml

kubectl exec test-pod -- cat /data/hello.txt
# يجب أن يظلّ يعرض: persistent-data

الملفّ الذي ينجو من تدمير الـ pod يُؤكِّد أنّ volume RBD مُوَفَّر، مُوَنَّت، ومستمرّ. هي إثبات المفهوم الأدنى الذي يُصادِق على سلسلة CSI كاملة.

الخطوة 7 — تفعيل CephFS لمشاركة الملفّات

للأحمال التي تتطلّب وصولًا ReadWriteMany (Nextcloud، WordPress متعدّد)، CephFS يُوفّر نظام ملفّات مشتركًا. يُفَعَّل عبر CRD CephFilesystem وStorageClass مخصَّصة.

apiVersion: ceph.rook.io/v1
kind: CephFilesystem
metadata:
  name: myfs
  namespace: rook-ceph
spec:
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  dataPools:
  - name: data0
    failureDomain: host
    replicated:
      size: 3
  metadataServer:
    activeCount: 1
    activeStandby: true
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: rook-cephfs
provisioner: rook-ceph.cephfs.csi.ceph.com
parameters:
  clusterID: rook-ceph
  fsName: myfs
  pool: myfs-data0
  csi.storage.k8s.io/provisioner-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/provisioner-secret-namespace: rook-ceph
  csi.storage.k8s.io/controller-expand-secret-name: rook-csi-cephfs-provisioner
  csi.storage.k8s.io/controller-expand-secret-namespace: rook-ceph
  csi.storage.k8s.io/node-stage-secret-name: rook-csi-cephfs-node
  csi.storage.k8s.io/node-stage-secret-namespace: rook-ceph
allowVolumeExpansion: true
reclaimPolicy: Delete

بعد kubectl apply، الـ StorageClass rook-cephfs تُتيح إنشاء PVCs بوضع RWX. عدّة pods على عقد مختلفة يمكنها وَنت نفس الـ volume في الآن نفسه، وهو ما لا يُتيحه RBD.

الخطوة 8 — كشف bucket S3 متوافق عبر ObjectStore

Ceph يُوفّر خدمة متوافقة مع S3 عبر RGW (RADOS Gateway). مفيد جدًّا لاستضافة artefacts البناء، نسخ Velero، أو وسائط تطبيق ويب.

apiVersion: ceph.rook.io/v1
kind: CephObjectStore
metadata:
  name: my-store
  namespace: rook-ceph
spec:
  metadataPool:
    failureDomain: host
    replicated:
      size: 3
  dataPool:
    failureDomain: host
    erasureCoded:
      dataChunks: 2
      codingChunks: 1
  preservePoolsOnDelete: false
  gateway:
    port: 80
    instances: 1
# ملاحظة: EC k=2 m=1 الحدّ الأدنى المطلوب لـ 3 مضيفين في failure domain host.
# فقدان مضيف يستهلك التكرار. لـ homelab جدّي، خَطِّط لـ 4 مضيفين (k+m+1)
# أو الانتقال إلى replicated x3 إن قبلت تكلفة المساحة الإضافية.
kubectl apply -f cephobjectstore.yaml

# أنشئ user S3 (يُولِّد access_key وsecret_key)
kubectl -n rook-ceph exec deploy/rook-ceph-tools -- \
  radosgw-admin user create --uid=homelab --display-name="Homelab User"
# دوِّن access_key وsecret_key من الخرج

endpoint الـ S3 قابل للوصول عبر الخدمة rook-ceph-rgw-my-store. للوصول من الخارج، سننشئ Ingress في دليل الرصد. للاختبارات الفورية، port-forward يكفي.

الخطوة 9 — اختبار الصمود لفقدان OSD

قيمة التخزين المُكرَّر تُقاس حين يسقط قرص أو عقدة. نُوقِف عاتيًا worker للتحقّق من بقاء volumes متاحة.

# على Proxmox، أوقف worker
qm stop 1101

# من المحطّة، راقب Ceph
kubectl -n rook-ceph exec deploy/rook-ceph-tools -- ceph status
# health يمرّ إلى HEALTH_WARN، 1 OSD down، لكنّ العنقود يعمل

# تحقّق من أنّ PVC لا يزال صالحًا
kubectl exec test-pod -- cat /data/hello.txt
# يجب أن يبقى يعرض: persistent-data

# أعد تشغيل الـ worker
qm start 1101
sleep 60
kubectl -n rook-ceph exec deploy/rook-ceph-tools -- ceph status
# health يعود إلى HEALTH_OK بعد دقائق (recovery تلقائي)

ملفّ hello.txt الذي يبقى قابلًا للقراءة بينما ثلث التخزين offline يُظهر القيمة الحقيقية لـ Rook-Ceph: homelab ينجو من عطل مادي دون تدخّل بشري. هذا ما لا نملكه مع local-path-provisioner أو NFS على خادم وحيد.

أخطاء شائعة وحلولها

العَرَض السبب الحلّ
OSDs تبقى Pending أقراص مُجَزَّأة سلفًا أو مُوَنَّتة امسح الأقراص (على Talos عبر reset كامل للعقدة) أو غيِّر القرص الهدف
HEALTH_WARN مستمرّ بعد التثبيت عدد PGs قليل أو PG في طور التوضع فعِّل pg_autoscaler وانتظر؛ وإلّا اضبط osd_pool_default_pg_num
PVCs تبقى Pending StorageClass غير افتراضي، أو CSI provisioner ساقط تحقّق من kubectl get sc وpods csi-rbdplugin-provisioner
pods مع PVC لا تُقلِع بعد reboot عقدة قفل RBD غير مُحَرَّر في Ceph rbd lock list ثم rbd lock remove عبر toolbox
أداء متَدَنٍّ بعد إضافة OSD rebalancing جارٍ، طبيعي انتظر أو أبطئ rebalance بـ osd_max_backfills=1

لاستكمال المسار

التخزين المستمرّ في مكانه: كتل RBD لقواعد البيانات، CephFS للمشاركة، ObjectStore لـ S3. أيّ حِمل يُنشَر من الآن سيستطيع طلب volumes دائمة. الخطوة التالية أتمتة نشر هذه الأحمال عبر GitOps. دليل Bootstrap GitOps مع Argo CD على Kubernetes يُفَصِّل تركيب Argo CD 3.4 وبنية مستودع Git المُرافق. للنظرة العامّة، عُد إلى الدليل الرئيسي.

مصادر وتوثيق رسمي

  • توثيق Rook 1.19: rook.io/docs/v1.19
  • Quickstart Rook-Ceph: rook.io/quickstart
  • توثيق Ceph Squid: docs.ceph.com/squid
  • Charts Helm Rook: artifacthub.io/rook-ceph
  • CephObjectStore وS3: rook.io/object-storage
  • مواصفات CRD CephCluster: rook.io/ceph-cluster-crd

الخطوة 10 — تفعيل لوحة Ceph والوصول عبر Ingress

لوحة Ceph تُوفّر واجهة ويب تُظهر صحّة العنقود، استعمال كلّ pool، أداء كلّ OSD، والتنبيهات الجارية. مُفَعَّلة في CRD CephCluster (الحقل dashboard.enabled: true) لكن غير مكشوفة خارج العنقود افتراضيًّا. ننشئ Ingress مع cert-manager للوصول HTTPS عبر اسم DNS محلّي.

# استرد كلمة سرّ admin للوحة
kubectl -n rook-ceph get secret rook-ceph-dashboard-password \
  -o jsonpath="{['data']['password']}" | base64 --decode
# هذه الكلمة تُتيح الوصول الأوّلي، غيِّرها فور أوّل دخول

# أنشئ Service ClusterIP يكشف اللوحة
kubectl -n rook-ceph patch service rook-ceph-mgr-dashboard \
  --type='merge' -p '{"spec":{"type":"ClusterIP"}}'

الـ Ingress المرافق سيُشير إلى هذه الخدمة على المنفذ 8443. ضبط cert-manager لـ Let’s Encrypt سيُفَصَّل في دليل الرصد، الذي ينطبق أيضًا على Grafana وعلى لوحة Ceph. بمجرّد التركيب، URL https://ceph.lan يفتح الواجهة الكاملة.

الخطوة 11 — فهم الاستهلاك وتخطيط النموّ

عامل التكرار 3 المستخدم حتى الآن يعني أنّ كلّ بايت مفيد يحتلّ ثلاثة بايتات على القرص. مع ثلاث OSDs بـ 32 جيغا، المساحة المفيدة الكلّية حوالي 30 جيغا (مع احتساب مساحة نظام Ceph). للانتقال إلى 100 جيغا قابلة للاستعمال، يجب إمّا إضافة ثلاث OSDs بـ 32 جيغا (واحدة لكلّ worker)، أو استبدال الأقراص بأكبر.

إضافة OSD تتمّ بتعديل CRD CephCluster لإعلان القرص الجديد. Rook يُقلِع تلقائيًّا pod OSD جديدًا ويبدأ rebalancing: Ceph يُعيد توزيع البيانات ليكون الحِمل موزَّعًا بانتظام بين كلّ OSDs. rebalancing شفّاف للأحمال؛ يستهلك ببساطة عرض نطاق شبكي وCPU لبضع دقائق إلى ساعات حسب الحجم.

# راقب rebalancing من toolbox
kubectl -n rook-ceph exec deploy/rook-ceph-tools -- ceph status
# misplaced objects ينخفض تدريجيًّا نحو 0

kubectl -n rook-ceph exec deploy/rook-ceph-tools -- ceph osd df
# يعرض الاستعمال لكلّ OSD: يجب التقارب نحو توزيع موحَّد

توزيع موحَّد على كلّ OSDs يُؤكِّد أنّ rebalancing انتهى وأنّ العنقود يستعمل كامل السعة المضافة. لنموّ كبير (> 50% من السعة المضافة)، الأفضل توزيع الإضافة على أيّام لئلّا تُشبَع الشبكة أثناء rebalancing.

الخطوة 12 — نسخ إعداد Ceph احتياطيًّا

كما مع Cilium، يجب وضع إعداد Rook-Ceph تحت إدارة الإصدارات للسماح بإعادة البناء. CRDs CephCluster وCephBlockPool وCephFilesystem وCephObjectStore والـ StorageClasses المُرافقة تُصدَّر وتُلتزَم في مستودع Git لـ Argo CD (الدليل التالي). الأسرار التي يُولّدها Rook (admin keyring، dashboard password) تبقى في العنقود؛ في حال إعادة البناء، يُولّد Rook جديدة.

mkdir -p homelab-gitops/storage
kubectl -n rook-ceph get cephcluster rook-ceph -o yaml > homelab-gitops/storage/cephcluster.yaml
kubectl -n rook-ceph get cephblockpool replicapool -o yaml > homelab-gitops/storage/cephblockpool.yaml
kubectl -n rook-ceph get cephfilesystem myfs -o yaml > homelab-gitops/storage/cephfilesystem.yaml
kubectl -n rook-ceph get cephobjectstore my-store -o yaml > homelab-gitops/storage/cephobjectstore.yaml
kubectl get sc rook-ceph-block rook-cephfs -o yaml > homelab-gitops/storage/storageclasses.yaml

cd homelab-gitops
git add storage/
git commit -m "Initial Rook-Ceph configuration"

رؤية الملفّات الستّة مُضافة لجذر المستودع والـ commit مُنشأ يُتيح إعادة بناء إعداد Ceph في أقلّ من خمس دقائق على عنقود جديد، شريطة وجود أقراص متاحة. هذه قاعدة الصمود التشغيلي: الإعداد يعيش في Git، والعنقود لا يفعل سوى تحقيق نسخة منه.

مقالات ذات صلة

Sponsoriser ce contenu

Cet emplacement est à vous

Position premium en fin d'article — c'est l'instant où les lecteurs sont le plus engagés. Réservez cet espace pour votre marque, votre formation ou votre offre.

Recevoir nos tarifs
Publicité