Files
homelab/cluster/platform/harbor/README.md
Hermes Agent service account 8d18f42b2e Update Harbor README with robot accounts documentation
Documents robot account management via GitOps:
- tekton-builder and fastpass-cluster robot accounts
- Manual Job execution (PostSync hooks don't work with multi-source)
- Credential retrieval and storage in 1Password
- ImagePullSecret creation for K8s clusters
2026-06-04 23:38:50 -05:00

141 lines
4.2 KiB
Markdown

# Harbor Container Registry
Enterprise-class container registry deployed on the fastpass Kubernetes cluster.
## Access
- **URL:** https://the-seas.local.mk-labs.cloud
- **Namespace:** harbor
## Credentials
- **Admin:** Stored in 1Password (mk-labs vault)
- **Robot Accounts:** Managed via robot-accounts-sync.yaml Job
## Robot Accounts
Two system-level robot accounts for automated operations:
### tekton-builder (robot$tekton-builder)
- **Purpose:** Tekton CI/CD pipeline builds
- **Permissions:** Push + Pull + Read artifacts (all projects)
- **Usage:** Push built container images from pipelines
### fastpass-cluster (robot$fastpass-cluster)
- **Purpose:** Kubernetes cluster image pulls
- **Permissions:** Pull + Read artifacts (all projects)
- **Usage:** Pull images for pod deployments
### Syncing Robot Accounts
Robot accounts are defined in `robot-accounts-sync.yaml` as an idempotent Kubernetes Job.
**To sync robot accounts after Harbor deployment or configuration changes:**
```bash
kubectl apply -f cluster/platform/harbor/robot-accounts-sync.yaml
kubectl logs -n harbor -l job-name=harbor-robot-accounts-sync -f
```
The Job:
- Creates missing robot accounts
- Skips existing accounts (idempotent)
- Uses harbor-credentials ExternalSecret for admin password
- Can be run repeatedly without side effects
**Note:** ArgoCD PostSync hooks don't currently trigger with multi-source applications, so the Job must be run manually after initial deployment or when robot account definitions change.
### Retrieving Robot Credentials
Robot account secrets are only returned on creation. To regenerate a secret:
```bash
curl -k -u "admin:${HARBOR_ADMIN_PASSWORD}" -X PATCH \
"https://the-seas.local.mk-labs.cloud/api/v2.0/robots/<robot_id>" \
-H "Content-Type: application/json" \
-d '{"secret": ""}' | jq -r '.secret'
```
Store secrets in 1Password (mk-labs vault, item: `harbor-robot-accounts`).
## Network & TLS
### DNS Name
- **Hostname:** the-seas.local.mk-labs.cloud
DNS resolves to the NGINX Ingress Controller IP (10.1.71.80).
### TLS Certificate
- Issued by Let's Encrypt (letsencrypt-prod)
- Managed automatically by cert-manager via Ingress annotation
- Certificate name: harbor-tls
- Auto-renewed before expiration
### Routing
- **Ingress Controller:** NGINX (nginx-ingress)
- **Protocol:** HTTPS (port 443)
- **Backend:** Harbor NGINX service on port 80
- TLS termination at Ingress level
## Architecture
- **Storage Backend:** NFS CSI (nfs.csi.k8s.io)
- Registry: 10Gi PVC
- Jobservice: 1Gi PVC
- **Database:** Embedded PostgreSQL (StatefulSet)
- **Cache:** Embedded Redis (StatefulSet)
- **Vulnerability Scanning:** Trivy (StatefulSet)
## Docker Client Configuration
### Trust Harbor Certificate
```bash
# Copy Harbor CA certificate from Kubernetes
kubectl get secret harbor-tls -n harbor -o jsonpath='{.data.tls\.crt}' | base64 -d > harbor-ca.crt
# Install to system trust store
sudo cp harbor-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# Install for Docker registry-specific trust
sudo mkdir -p /etc/docker/certs.d/the-seas.local.mk-labs.cloud
sudo cp harbor-ca.crt /etc/docker/certs.d/the-seas.local.mk-labs.cloud/ca.crt
```
### Login and Test
```bash
docker login the-seas.local.mk-labs.cloud
docker pull alpine:latest
docker tag alpine:latest the-seas.local.mk-labs.cloud/library/alpine:test
docker push the-seas.local.mk-labs.cloud/library/alpine:test
```
## Kubernetes ImagePullSecret
Create a Secret for the fastpass-cluster robot account:
```bash
kubectl create secret docker-registry harbor-pull-secret \
--docker-server=the-seas.local.mk-labs.cloud \
--docker-username='robot$fastpass-cluster' \
--docker-password='<secret-from-1password>' \
--namespace=<target-namespace>
```
Or manage via ExternalSecret referencing 1Password.
## Deployment Details
- **Helm Chart:** goharbor/harbor v1.19.1 (Harbor v2.15.1)
- **Deployment Method:** ArgoCD multi-source (Helm chart + repo manifests)
- **Sync Policy:** Automated (prune + selfHeal enabled)
- **Sync Wave:** 7 (depends on cert-manager, external-dns, ESO)
## References
- Upstream Helm Chart: https://github.com/goharbor/harbor-helm
- Harbor Documentation: https://goharbor.io/docs/
- API Reference: https://the-seas.local.mk-labs.cloud/devcenter-api-2.0