Files
homelab/cluster/platform/harbor
Hermes Agent service account 092d1ac209 Document robot credential management via 1Password and ExternalSecrets
Updated README to reflect the full workflow:
1. Robot account creation via Job
2. Secret regeneration and capture
3. Storage in 1Password (harbor-robot-accounts item)
4. Automatic sync via ExternalSecrets to K8s
2026-06-04 23:44:00 -05:00
..

Harbor Container Registry

Enterprise-class container registry deployed on the fastpass Kubernetes cluster.

Access

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:

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.

Managing Robot Credentials

Robot account secrets are managed through 1Password and synced via ExternalSecrets:

  1. Initial Setup: After running robot-accounts-sync.yaml, regenerate secrets to capture full values:

    # Regenerate tekton-builder secret (robot ID: 3)
    curl -k -u "admin:${HARBOR_ADMIN_PASSWORD}" -X PATCH \
      "https://the-seas.local.mk-labs.cloud/api/v2.0/robots/3" \
      -H "Content-Type: application/json" \
      -d '{"secret": ""}' | jq -r '.secret'
    
    # Regenerate fastpass-cluster secret (robot ID: 4)
    curl -k -u "admin:${HARBOR_ADMIN_PASSWORD}" -X PATCH \
      "https://the-seas.local.mk-labs.cloud/api/v2.0/robots/4" \
      -H "Content-Type: application/json" \
      -d '{"secret": ""}' | jq -r '.secret'
    
  2. Store in 1Password: Create item harbor-robot-accounts in mk-labs vault with fields:

    • tekton-builder-username: robot$tekton-builder
    • tekton-builder-password: (secret from above)
    • fastpass-cluster-username: robot$fastpass-cluster
    • fastpass-cluster-password: (secret from above)
  3. ExternalSecrets: Two ExternalSecrets automatically sync credentials from 1Password:

    • externalsecret-tekton-robot.yaml → creates harbor-tekton-robot secret
    • externalsecret-pull-secret.yaml → creates harbor-pull-secret secret

    Both create kubernetes.io/dockerconfigjson type secrets ready for use.

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

# 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

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:

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