# راهنمای Harbor — `registry.abrban.com` این سند معماری فعلی، نصب، مدیریت روزمره و عیب‌یابی **Harbor** روی کلاستر abr را پوشش می‌دهد. - چارت/values: [`backend/helm/cloudhost-harbor/`](backend/helm/cloudhost-harbor/) - اسکریپت نصب: [`backend/helm/cloudhost-harbor/scripts/install-harbor-registry.sh`](backend/helm/cloudhost-harbor/scripts/install-harbor-registry.sh) --- ## معماری فعلی (خلاصه) ``` registry.abrban.com (Traefik + TLS wildcard) ├── / → harbor-portal (UI) ├── /api/, /service/, /c/ → harbor-core (API + auth) ├── /v2/proxy-dockerhub/ → harbor-registry (ایمیج‌های mirror‌شده Ceph/Rook) ├── /v2/rook/ → harbor-registry └── /v2/* → registry قدیمی (ایمیج‌های platform: backend, nixpacks, …) ``` | کامپوننت | نقش | |----------|-----| | **Harbor** | UI، proxy-cache، ذخیره ایمیج‌های جدید | | **registry قدیمی** (`Deployment/registry`) | هنوز بالاست؛ ایمیج‌های platform قبل از Harbor اینجاست | | **registry-egress-proxy** | secret با `HTTP_PROXY` / `HTTPS_PROXY` برای pull از docker.io/quay از داخل کلاستر | | **registry-pull-secret** | auth kubelet برای pull از `registry.abrban.com` | > Harbor و registry قدیمی **هم‌زمان** روی یک hostname هستند؛ مسیر `/v2/` با Ingress split می‌شود. --- ## پیش‌نیازها - Secret `abrban-wildcard-tls` در namespace `cloudhost` - Secret `registry-egress-proxy` در namespace `cloudhost` (پروکسی egress) - Helm repo: `helm repo add harbor https://helm.goharbor.io` --- ## نصب / ارتقا ```bash cd backend/helm/cloudhost-harbor ./scripts/install-harbor-registry.sh ``` اسکریپت: 1. Harbor را با values + proxy از `registry-egress-proxy` نصب می‌کند 2. Ingress قدیمی `registry` را حذف می‌کند (بعد از نصب باید دستی دوباره route شود — بخش Ingress) 3. `Deployment/registry` را scale به 0 می‌کند (برای rollback نگه داشته می‌شود) ### Ingress بعد از نصب (الزامی) Harbor به **چند مسیر** نیاز دارد. Ingress نهایی باید شبیه این باشد: | Path | Service | Port | |------|---------|------| | `/` | `harbor-portal` | 80 | | `/api/`, `/service/`, `/c/`, `/chartrepo/` | `harbor-core` | 80 | | `/v2/proxy-dockerhub/`, `/v2/rook/` | `harbor-registry` | 5000 | | `/v2/` (بقیه) | `registry` (قدیمی) | 5000 | بدون split روی `/v2/`، یا UI 404 می‌دهد یا kubelet ایمیج platform را پیدا نمی‌کند. --- ## دسترسی و credentialها | کاربرد | کاربر | منبع | |--------|-------|------| | UI / API مدیریت | `admin` | `kubectl -n cloudhost get secret harbor-core -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' \| base64 -d` | | push/pull داخلی به harbor-registry | `harbor_registry_user` | secret `harbor-core` → `REGISTRY_CREDENTIAL_PASSWORD` | | pull kubelet (ایمیج‌های platform) | `cloudhost` | secret `registry-pull-secret` (namespace `cloudhost`) | | pull kubelet (ایمیج‌های Rook/Ceph) | `harbor_registry_user` | secret `registry-pull-secret` (namespace `rook-ceph`) | URL: https://registry.abrban.com/ --- ## پروژه‌های proxy-cache | پروژه | upstream | کاربرد | |-------|----------|--------| | `proxy-dockerhub` | docker.io | Rook، Ceph، bitnami، … | | `proxy-quay` | quay.io | cephcsi و … | | `proxy-k8s` | registry.k8s.io | CSI sidecarها | ایجاد از UI: **Administration → Registries → New Endpoint** سپس **Projects → New Project** با نوع Proxy Cache. > health check بعضی endpointها (مثلاً quay) از UI timeout می‌خورد؛ از داخل `harbor-core` با curl و proxy ممکن است OK باشد. در صورت نیاز endpoint را با type `docker-registry` بسازید. ### proxy در Harbor پروکسی از secret `registry-egress-proxy` در ConfigMapهای `harbor-core` و `harbor-jobservice-env` تزریق می‌شود. **مهم:** Go (harbor-core/jobservice) به `http_proxy` / `https_proxy` **lowercase** هم نیاز دارد. اگر health check upstream `unhealthy` ماند، هر دو حالت uppercase و lowercase را در ConfigMap بگذارید و podها را restart کنید: ```bash kubectl -n cloudhost rollout restart deploy/harbor-core deploy/harbor-jobservice ``` --- ## mirror دستی ایمیج (وقتی proxy-cache کار نمی‌کند) روی abr، pull مستقیم از docker.io/quay از kubelet ممکن نیست. ایمیج‌های حیاتی را با Job داخل کلاستر mirror کنید: **مقصد push:** `harbor-registry.cloudhost.svc.cluster.local:5000` (HTTP، با `harbor_registry_user`) **مثال مسیرها در registry:** | ایمیج upstream | مسیر در registry | |----------------|------------------| | `rook/ceph:v1.20.1` | `rook/ceph:v1.20.1` | | `quay.io/ceph/ceph:v19.2` | `proxy-dockerhub/ceph/ceph:v19.2` | ```bash # لیست ایمیج‌های داخل harbor-registry kubectl -n cloudhost exec deploy/harbor-portal -- \ curl -s -u "harbor_registry_user:$(kubectl -n cloudhost get secret harbor-core -o jsonpath='{.data.REGISTRY_CREDENTIAL_PASSWORD}' | base64 -d)" \ http://harbor-registry:5000/v2/_catalog ``` > push مستقیم به `harbor-registry:5000` metadata در Harbor UI را به‌روز نمی‌کند؛ برای kubelet کافی است چون `/v2/` به harbor-registry route شده. --- ## مدیریت روزمره ### وضعیت ```bash kubectl -n cloudhost get pods | grep harbor kubectl -n cloudhost get ingress registry -o yaml | grep -A3 'path:' curl -sk -o /dev/null -w "%{http_code}\n" https://registry.abrban.com/ curl -sk -u admin: https://registry.abrban.com/api/v2.0/systeminfo ``` ### لاگ‌ها ```bash kubectl -n cloudhost logs deploy/harbor-core --tail=50 kubectl -n cloudhost logs deploy/harbor-jobservice --tail=50 kubectl -n cloudhost logs deploy/harbor-registry -c registry --tail=50 ``` ### ارتقا Harbor ```bash helm repo update harbor ./scripts/install-harbor-registry.sh # Ingress split را دوباره تأیید کنید ``` ### rollback به registry قدیمی ```bash kubectl -n cloudhost scale deploy/registry --replicas=1 # Ingress را فقط به service registry:5000 برگردانید helm uninstall harbor -n cloudhost ``` --- ## عیب‌یابی | علامت | علت محتمل | اقدام | |-------|-----------|--------| | `https://registry.abrban.com/` → 404 | Ingress فقط به `harbor-core` وصل است | `/` → `harbor-portal` | | `ImagePullBackOff` برای `cloudhost-backend` | `/v2/` به Harbor رفته، ایمیج platform آنجا نیست | `/v2/` (عمومی) → `registry` قدیمی | | `not found` برای `proxy-dockerhub/...` | ایمیج mirror نشده | Job skopeo یا proxy-cache | | push با 499/503 | Traefik timeout | push از داخل کلاستر به `harbor-registry:5000` | | registry endpoint `unhealthy` | proxy lowercase یا timeout health check | patch ConfigMap + restart؛ یا mirror دستی | | `authentication required` روی pull | pull secret اشتباه namespace | `cloudhost` vs `harbor_registry_user` در `rook-ceph` | ### تست pull ```bash # platform (cloudhost user) curl -sk -u "cloudhost:" https://registry.abrban.com/v2/cloudhost-backend/tags/list # rook/ceph (harbor_registry_user) curl -sk -u "harbor_registry_user:" https://registry.abrban.com/v2/rook/ceph/tags/list ``` --- ## چک‌لیست بعد از نصب - [ ] Portal روی `/` پاسخ 200 - [ ] `/api/v2.0/systeminfo` پاسخ JSON - [ ] Ingress split `/v2/` درست است - [ ] پروژه‌های `proxy-dockerhub`, `proxy-k8s`, `proxy-quay` ساخته شده - [ ] `registry-pull-secret` در `cloudhost` و `rook-ceph` به‌روز است - [ ] ایمیج‌های Rook/Ceph mirror شده و pull تست شده