# راهنمای Ceph برای ابربان (Rook) این سند نصب، معماری واقعی روی کلاستر **abr**، مدیریت روزمره و عیب‌یابی **Rook-Ceph** را پوشش می‌دهد. - چارت و اسکریپت‌ها: [`backend/helm/cloudhost-ceph/`](backend/helm/cloudhost-ceph/) - README انگلیسی: [`backend/helm/cloudhost-ceph/README.md`](backend/helm/cloudhost-ceph/README.md) - رجیستری: [`RUNBOOK-HARBOR.fa.md`](RUNBOOK-HARBOR.fa.md) --- ## چرا Ceph؟ | نیاز | راه‌حل Ceph | |------|-------------| | PVC اپ/دیتابیس با **resize** | Block pool → StorageClass `rook-ceph-block` | | آپلود **zip** سورس کاربر | Object store (RGW) → StorageClass `rook-ceph-bucket` | یک کلاستر Ceph هر دو را پوشش می‌دهد؛ zip را روی PVC نگه ندارید — از **bucket** استفاده کنید. --- ## معماری روی abr (single-node) ``` registry.abrban.com ├── rook/ceph:v1.20.1 → Rook operator └── proxy-dockerhub/ceph/ceph:v19.2 → Ceph daemon (Squid) Node abr ├── /dev/loop6 (15Gi) → OSD (bluestore raw) ├── mon-a, mgr-a, osd-0, rgw → rook-ceph namespace └── RGW: rook-ceph-rgw-ceph-objectstore.rook-ceph.svc:80 ``` | محدودیت | توضیح | |---------|--------| | **۱ OSD** | replication=1؛ بدون HA | | **loop device** | دیسک خام نداریم؛ `/dev/loop6` از فایل `osd-loopback.img` | | **HEALTH_WARN** | طبیعی: `OSD count 1 < default size 3`، mon low space | | **ایمیج‌ها** | باید از قبل در Harbor mirror شده باشند (kubelet به docker.io دسترسی ندارد) | --- ## پیش‌نیازها ### پروفایل `single-node` (کلاستر فعلی abr) - Kubernetes 1.28+ (k3s + Traefik) - Harbor بالا و ایمیج‌های `rook/ceph` + `ceph/ceph` mirror شده - حداقل **۱۵ گیگ** فضا برای loop OSD (`/var/lib/rook/osd-loopback.img`) - `helm` 3.x و `kubectl` با دسترسی cluster-admin - Secret `registry-pull-secret` در `rook-ceph` با `harbor_registry_user` ### پروفایل `multi-node` (production) - حداقل **۳ نود** + دیسک خام (raw) - فایل values: `values-rook-cluster-multi-node.yaml` --- ## نصب (اولین بار — abr) ### ۱. آماده‌سازی loop device برای OSD روی نود تک‌دیسک، Rook به دیسک خام نیاز دارد. یک loop device بسازید: ```bash # روی نود (یا Job privileged — یک‌بار) truncate -s 15G /var/lib/rook/osd-loopback.img losetup --find --show /var/lib/rook/osd-loopback.img # → /dev/loop6 ``` ### ۲. فعال‌سازی loop در Rook operator ```bash kubectl -n rook-ceph patch cm rook-ceph-operator-config --type merge \ -p '{"data":{"ROOK_CEPH_ALLOW_LOOP_DEVICES":"true"}}' kubectl -n rook-ceph rollout restart deploy/rook-ceph-operator ``` ### ۳. mirror ایمیج‌ها (قبل از نصب cluster) | ایمیج | مسیر pull | |-------|-----------| | `rook/ceph:v1.20.1` | `registry.abrban.com/rook/ceph:v1.20.1` | | `quay.io/ceph/ceph:v19.2` | `registry.abrban.com/proxy-dockerhub/ceph/ceph:v19.2` | جزئیات mirror: [`RUNBOOK-HARBOR.fa.md`](RUNBOOK-HARBOR.fa.md) ### ۴. نصب operator ```bash helm repo add rook-release https://charts.rook.io/release helm repo update rook-release helm upgrade --install rook-ceph rook-release/rook-ceph \ -n rook-ceph --create-namespace \ --set image.repository=registry.abrban.com/rook/ceph \ --set image.tag=v1.20.1 \ --set imagePullSecrets[0].name=registry-pull-secret ``` ### ۵. نصب cluster ```bash cd backend/helm/cloudhost-ceph helm upgrade --install rook-ceph-cluster rook-release/rook-ceph-cluster \ -n rook-ceph \ -f values-rook-cluster-single-node.yaml \ --set cephClusterSpec.cephVersion.image=registry.abrban.com/proxy-dockerhub/ceph/ceph:v19.2 ``` > **توجه:** `values-rook-cluster-single-node.yaml` از `devices: [{name: "/dev/loop6"}]` استفاده می‌کند (نه directory — در Rook v1.20 حذف شده). ### ۶. extras (bucket + secret) ```bash kubectl create namespace cloudhost-builds 2>/dev/null || true helm upgrade --install cloudhost-ceph . \ -n cloudhost-builds -f values.yaml --no-hooks ``` اگر Job `bucket-sync` به‌خاطر `bitnami/kubectl` گیر کرد، secret را دستی بسازید: ```bash kubectl -n cloudhost-builds get secret app-sources -o yaml kubectl -n cloudhost-builds get cm app-sources -o yaml # BUCKET_NAME # → secret ceph-app-sources-credentials (کلیدهای SOURCE_STORAGE_*) ``` ### ۷. یکپارچه‌سازی backend ```bash # کپی secret به namespace پلتفرم (یک‌بار) kubectl -n cloudhost-builds get secret ceph-app-sources-credentials -o yaml \ | sed 's/namespace: cloudhost-builds/namespace: cloudhost/' \ | kubectl apply -f - # یا با Helm (پیشنهادی): helm upgrade cloudhost ./backend/helm/cloudhost-platform -n cloudhost \ --set backend.sourceStorage.enabled=true \ --set backend.env.PLATFORM_STORAGE_CLASS=rook-ceph-block \ --set backend.env.PLATFORM_CREATE_STORAGE_CLASS=false \ --set backend.env.PLATFORM_STORAGE_PROVISIONER=rook-ceph.rbd.csi.ceph.com ``` بدون Helm می‌توانید دستی patch کنید: ```bash kubectl -n cloudhost set env deploy/cloudhost-backend \ PLATFORM_STORAGE_CLASS=rook-ceph-block \ PLATFORM_CREATE_STORAGE_CLASS=false \ PLATFORM_STORAGE_PROVISIONER=rook-ceph.rbd.csi.ceph.com kubectl -n cloudhost patch deploy cloudhost-backend --type=json \ -p '[{"op":"add","path":"/spec/template/spec/containers/0/envFrom","value":[{"secretRef":{"name":"ceph-app-sources-credentials"}}]}]' ``` --- ## اسکریپت `install.sh` (نصب تمیز) برای نصب از صفر (بعد از آماده‌سازی loop + mirror): ```bash cd backend/helm/cloudhost-ceph ./scripts/install.sh single-node ./scripts/verify.sh ``` اسکریپت operator + cluster + extras را نصب می‌کند. روی abr حتماً **قبلش** loop device و mirror ایمیج را انجام دهید. --- ## خروجی‌های مهم ### StorageClassها | نام | کاربرد | |-----|--------| | `rook-ceph-block` | PVC اپ، DB، Redis، … | | `rook-ceph-bucket` | claim کردن bucket برای zip | ### Secret پلتفرم ```bash kubectl -n cloudhost-builds get secret ceph-app-sources-credentials -o yaml kubectl -n cloudhost get secret ceph-app-sources-credentials -o yaml # کپی در cloudhost ``` کلیدها: `SOURCE_STORAGE_ENDPOINT`, `SOURCE_STORAGE_BUCKET`, `SOURCE_STORAGE_ACCESS_KEY`, `SOURCE_STORAGE_SECRET_KEY` ### RGW endpoint ``` http://rook-ceph-rgw-ceph-objectstore.rook-ceph.svc.cluster.local:80 ``` --- ## مدیریت روزمره ### سلامت کلاستر ```bash kubectl -n rook-ceph get cephcluster kubectl -n rook-ceph exec deploy/rook-ceph-tools -- ceph status kubectl -n rook-ceph exec deploy/rook-ceph-tools -- ceph osd tree kubectl get sc | grep rook-ceph kubectl -n rook-ceph get pods ``` ### Dashboard ```bash kubectl -n rook-ceph get secret rook-ceph-dashboard-password -o jsonpath='{.data.password}' | base64 -d kubectl -n rook-ceph port-forward svc/rook-ceph-mgr-dashboard 8443:8443 # https://localhost:8443 ``` ### bucket و OBC ```bash kubectl -n cloudhost-builds get obc app-sources kubectl -n cloudhost-builds get cm app-sources ``` ### PVC جدید با Ceph ```yaml storageClassName: rook-ceph-block ``` فقط **اپ‌های جدید** (یا بعد از migration) از این StorageClass استفاده می‌کنند. PVCهای قدیمی روی `local-path` / `cloudhost-expandable` خودکار منتقل نمی‌شوند. --- ## راه‌اندازی مجدد (reinstall) ### ۱. حذف Helm ```bash cd backend/helm/cloudhost-ceph ./scripts/uninstall.sh # تایپ: delete-ceph ``` ### ۲. پاک‌سازی روی نود ```bash sudo losetup -d /dev/loop6 2>/dev/null || true sudo rm -f /var/lib/rook/osd-loopback.img sudo rm -rf /var/lib/rook ``` ### ۳. نصب مجدد loop device + mirror + `./scripts/install.sh single-node` --- ## عیب‌یابی ### CephCluster در `Progressing` / Detecting version ```bash kubectl -n rook-ceph get pods | grep detect-version kubectl -n rook-ceph describe pod -l job-name=rook-ceph-detect-version ``` | خطا | راه‌حل | |-----|--------| | `ceph/ceph:v19.2 not found` | mirror از quay.io؛ tag صحیح `v19.2` نه `v19.2.1` | | pull timeout | اولین pull بزرگ است (~500MB)؛ صبر یا image را از قبل روی نود بکشید | | Job `detect-version` Terminating گیر کرد | `kubectl -n rook-ceph delete job rook-ceph-detect-version --force --grace-period=0` | ### OSD بالا نمی‌آید (OSD count 0) ```bash kubectl -n rook-ceph logs -l app=rook-ceph-osd-prepare --tail=50 ``` | خطا | راه‌حل | |-----|--------| | `unsupported diskType loop` | `ROOK_CEPH_ALLOW_LOOP_DEVICES=true` | | `not picked by deviceFilter` | از `devices: [{name: "/dev/loop6"}]` استفاده کنید نه `deviceFilter` | | `no devices matched` | `losetup -a` روی نود؛ loop6 وجود دارد؟ | | `directories` در values | در Rook v1.20 کار نمی‌کند — loop یا raw disk | ### Volume mount روی rook-ceph-tools `rook-ceph-mon-endpoints` و `rook-ceph-mon` تا قبل از بالا آمدن mon ساخته نمی‌شوند — طبیعی است؛ بعد از Ready برطرف می‌شود. ### Helm timeout روی apiserver اگر `failed to download openapi` دیدید، بدون `--wait` نصب کنید و با `kubectl get cephcluster` پیگیری کنید. ### resize PVC ```bash kubectl get storageclass rook-ceph-block -o yaml | grep allowVolumeExpansion kubectl patch pvc -n --type merge \ -p '{"spec":{"resources":{"requests":{"storage":"5Gi"}}}}' ``` --- ## ارتقا (upgrade) ```bash helm repo update rook-release helm upgrade rook-ceph rook-release/rook-ceph -n rook-ceph \ --reuse-values --timeout 10m helm upgrade rook-ceph-cluster rook-release/rook-ceph-cluster \ -n rook-ceph \ -f values-rook-cluster-single-node.yaml \ --set cephClusterSpec.cephVersion.image=registry.abrban.com/proxy-dockerhub/ceph/ceph:v19.2 helm upgrade cloudhost-ceph . -n cloudhost-builds -f values.yaml ``` قبل از upgrade در production: [Rook upgrade guide](https://rook.io/docs/rook/latest/Upgrade/ceph-upgrade/) و snapshot. --- ## نکات امنیتی - RGW داخل کلاستر HTTP است — برای دسترسی خارجی ingress + TLS اضافه کنید. - Secret `ceph-app-sources-credentials` را فقط به backend بدهید. - `single-node` + ۱ OSD فقط staging است؛ production نیاز به ۳+ نود و دیسک جدا دارد. --- ## چک‌لیست بعد از نصب - [ ] `ceph status` — mon/mgr/osd/rgw up - [ ] `rook-ceph-block` و `rook-ceph-bucket` در `kubectl get sc` - [ ] `ceph-app-sources-credentials` در `cloudhost-builds` و `cloudhost` - [ ] env بک‌اند: `PLATFORM_STORAGE_CLASS=rook-ceph-block` - [x] `SOURCE_STORAGE_*` در backend از secret خوانده می‌شود (`backend.sourceStorage.enabled=true` در Helm) - [ ] اپ تست: آپلود zip و deploy با bucket فعال - [ ] اپ تست با PVC جدید deploy شده - [ ] ایمیج‌های Rook در Harbor موجود و pull تست شده