Enterprise Harbor Registry on RKE2 with SUSE Application Collection: Complete Setup Guide

Introduction: Enterprise Container Management with Harbor on RKE2

Harbor, as a CNCF graduated project, provides enterprise-grade container registry capabilities that go far beyond basic image storage. When deployed on RKE2 (Rancher Kubernetes Engine 2) using SUSE Application Collection, it creates a powerful foundation for enterprise container management with built-in security, compliance, and operational features.

This comprehensive guide will walk you through deploying Harbor registry on RKE2 using SUSE Application Collection, covering everything from cluster preparation to production-ready security configurations.

Why Harbor on RKE2 for Enterprise

This combination provides critical enterprise capabilities:

  • Security Scanning: Built-in Trivy and Clair vulnerability scanning
  • Content Trust: Docker Content Trust and Notary integration
  • Multi-tenancy: Project-based RBAC and policy enforcement
  • Compliance: Audit logging and governance features
  • High Availability: Enterprise-grade reliability and scalability

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                    RKE2 Kubernetes Cluster                     │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐  ┌─────────────────┐  ┌──────────────┐  │
│  │   Control Plane │  │   Worker Nodes  │  │  Longhorn    │  │
│  │   - etcd        │  │   - Harbor Pods │  │  Storage     │  │
│  │   - kube-api    │  │   - Registry    │  │  - Database  │  │
│  │   - scheduler   │  │   - Notary      │  │  - Redis     │  │
│  │   - controller  │  │   - Trivy       │  │  - Registry  │  │
│  └─────────────────┘  └─────────────────┘  └──────────────┘  │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐  ┌─────────────────┐  ┌──────────────┐  │
│  │  Ingress Nginx  │  │  Cert Manager   │  │  Monitoring  │  │
│  │  - SSL Term     │  │  - TLS Certs    │  │  - Prometheus│  │
│  │  - Load Balance │  │  - Let's Encrypt│  │  - Grafana   │  │
│  └─────────────────┘  └─────────────────┘  └──────────────┘  │
└─────────────────────────────────────────────────────────────┘

Prerequisites and Requirements

Infrastructure Requirements

  • Kubernetes Cluster: RKE2 v1.24+ with 3+ control plane nodes, 3+ worker nodes
  • Memory: 16GB per node minimum (32GB recommended)
  • CPU: 4 cores per node minimum (8 cores recommended)
  • Storage: SSD-based storage with 500GB+ capacity
  • Network: High-bandwidth connectivity (10Gbps recommended)

Software Prerequisites

  • Rancher Management Server: v2.7+ with SUSE Application Collection
  • Longhorn Storage: v1.4+ for persistent storage
  • Ingress Controller: NGINX Ingress Controller
  • Cert Manager: v1.10+ for TLS management

Step 1: Cluster Preparation and Validation

First, validate your RKE2 cluster meets Harbor’s requirements:

# Check cluster status and resources
kubectl get nodes -o wide
kubectl top nodes

# Verify storage classes
kubectl get storageclass

# Test DNS resolution
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup kubernetes.default

Label nodes for Harbor workload placement:

# Label nodes for Harbor components
kubectl label nodes worker-node-1 harbor.io/workload=core
kubectl label nodes worker-node-2 harbor.io/workload=core
kubectl label nodes worker-node-3 harbor.io/workload=database

Step 2: SUSE Application Collection Setup

Add the SUSE Application Collection repository:

# Add SUSE Application Collection repository
helm repo add suse-application-collection https://registry.suse.com/repository/suse-application-collection/
helm repo update

# Verify Harbor chart availability
helm search repo suse-application-collection/harbor
helm show chart suse-application-collection/harbor

Step 3: Longhorn Storage Configuration

Create optimized storage classes for Harbor components:

# harbor-storage-classes.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-harbor-db
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
parameters:
  numberOfReplicas: "3"
  staleReplicaTimeout: "2880"
  diskSelector: "ssd"
  nodeSelector: "harbor.io/workload=database"
  dataLocality: "strict-local"
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: longhorn-harbor-registry
provisioner: driver.longhorn.io
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
parameters:
  numberOfReplicas: "2"
  staleReplicaTimeout: "2880"
  diskSelector: "ssd,hdd"
  nodeSelector: "harbor.io/workload=core"
  dataLocality: "best-effort"
# Apply storage classes
kubectl apply -f harbor-storage-classes.yaml

Step 4: Network and Ingress Setup

Configure NGINX Ingress with Harbor-specific optimizations:

# nginx-harbor-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-configuration
  namespace: ingress-nginx
data:
  proxy-body-size: "1024m"
  proxy-connect-timeout: "600"
  proxy-send-timeout: "600"
  proxy-read-timeout: "600"
  proxy-buffering: "off"
  proxy-request-buffering: "off"
  upstream-keepalive-connections: "32"
  upstream-keepalive-timeout: "60"

Step 5: Certificate Management

Configure cert-manager for automatic TLS certificates:

# letsencrypt-clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod-harbor
spec:
  acme:
    email: admin@yourdomain.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod-harbor-key
    solvers:
    - http01:
        ingress:
          class: nginx
# Apply ClusterIssuer
kubectl apply -f letsencrypt-clusterissuer.yaml

Step 6: Harbor Installation

Create Harbor namespace and values configuration:

# Create dedicated namespace
kubectl create namespace harbor-system
kubectl label namespace harbor-system name=harbor-system

Create comprehensive Harbor values file:

# harbor-values.yaml
global:
  externalURL: https://harbor.yourdomain.com
  storageClass: "longhorn-harbor-registry"

database:
  type: internal
  internal:
    password: "HarborDB123!"
    persistence:
      enabled: true
      storageClass: "longhorn-harbor-db"
      size: 20Gi
    nodeSelector:
      harbor.io/workload: database

redis:
  type: internal
  internal:
    nodeSelector:
      harbor.io/workload: core

core:
  nodeSelector:
    harbor.io/workload: core

jobservice:
  nodeSelector:
    harbor.io/workload: core

registry:
  storage:
    type: filesystem
    persistence:
      enabled: true
      storageClass: "longhorn-harbor-registry"
      size: 100Gi
  nodeSelector:
    harbor.io/workload: core

trivy:
  enabled: true
  nodeSelector:
    harbor.io/workload: core

notary:
  enabled: true

ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod-harbor"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size: "1024m"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
  hosts:
    - name: harbor.yourdomain.com
      tls: true
      tlsSecret: harbor-tls
    - name: notary.yourdomain.com
      tls: true
      tlsSecret: notary-tls

Deploy Harbor using Helm:

# Install Harbor
helm upgrade --install harbor \
  suse-application-collection/harbor \
  --namespace harbor-system \
  --values harbor-values.yaml \
  --timeout 20m \
  --wait

# Monitor deployment
kubectl get pods -n harbor-system -w

Step 7: Authentication Configuration

Initial Admin Setup

# Get admin password
kubectl get secret harbor-core -n harbor-system -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 -d

Access Harbor UI at https://harbor.yourdomain.com and change the default password.

LDAP Integration

Configure LDAP authentication in Harbor UI:

  1. Administration → Configuration → Authentication
  2. Select “LDAP” auth mode
  3. Configure LDAP settings:
LDAP URL: ldaps://ldap.yourdomain.com:636
Search DN: cn=harbor-service,ou=Service Accounts,dc=yourdomain,dc=com
Search Password: [service-account-password]
Base DN: dc=yourdomain,dc=com
Filter: (objectClass=person)
UID: sAMAccountName

Robot Account Creation

Create robot accounts for CI/CD automation via Harbor UI or API:

  1. Navigate to Projects → [Project Name] → Robot Accounts
  2. Create new robot account with push/pull permissions
  3. Save credentials for CI/CD integration

Step 8: Security Hardening

Network Security

# harbor-network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: harbor-network-policy
  namespace: harbor-system
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: ingress-nginx
    ports:
    - protocol: TCP
      port: 8080
  - from:
    - namespaceSelector:
        matchLabels:
          name: harbor-system
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: kube-system
    ports:
    - protocol: UDP
      port: 53
  - to: []
    ports:
    - protocol: TCP
      port: 443

Pod Security Standards

# Apply pod security standards
kubectl label namespace harbor-system \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

Step 9: RKE2 Container Runtime Integration

Configure RKE2’s containerd to use Harbor as private registry:

# /etc/rancher/rke2/registries.yaml
mirrors:
  "harbor.yourdomain.com":
    endpoint:
      - "https://harbor.yourdomain.com"
configs:
  "harbor.yourdomain.com":
    auth:
      username: "robot$harbor-system+ci-cd-robot"
      password: "[robot-token]"
    tls:
      insecure_skip_verify: false
# Restart RKE2 services
sudo systemctl restart rke2-server  # On control plane nodes
sudo systemctl restart rke2-agent   # On worker nodes

Create image pull secrets for Kubernetes:

# Create image pull secret
kubectl create secret docker-registry harbor-registry-secret \
  --docker-server=harbor.yourdomain.com \
  --docker-username="robot\$harbor-system+ci-cd-robot" \
  --docker-password="[robot-token]" \
  --namespace=default

Step 10: Monitoring and Observability

Enable Harbor metrics for Prometheus:

# Add to harbor-values.yaml
metrics:
  enabled: true
  serviceMonitor:
    enabled: true
    interval: 30s
    labels:
      release: prometheus

Key Harbor metrics to monitor:

  • harbor_up: Service availability
  • harbor_project_total: Number of projects
  • harbor_repository_total: Repository count
  • harbor_artifact_total: Artifact count
  • harbor_quota_usage_bytes: Storage usage

Verification and Testing

Verify your Harbor deployment:

# Check all pods are running
kubectl get pods -n harbor-system

# Verify services and ingress
kubectl get svc,ingress -n harbor-system

# Test external access
curl -I https://harbor.yourdomain.com
curl -I https://notary.yourdomain.com

# Test Docker login
docker login harbor.yourdomain.com

Troubleshooting Common Issues

Certificate Problems

# Check certificate status
kubectl describe certificate harbor-tls -n harbor-system

# Check cert-manager logs
kubectl logs -n cert-manager deployment/cert-manager

Storage Issues

# Check PVC status
kubectl get pvc -n harbor-system

# Check Longhorn volumes
kubectl get volumes -n longhorn-system

Performance Problems

# Check resource utilization
kubectl top pods -n harbor-system

# Monitor database performance
kubectl exec -it harbor-database-0 -n harbor-system -- psql -U postgres -c "SELECT * FROM pg_stat_activity;"

Production Best Practices

Backup Strategy

  • Configure Longhorn automatic snapshots
  • Implement database backup automation
  • Test restore procedures regularly

High Availability

  • Deploy across multiple availability zones
  • Configure anti-affinity rules
  • Implement load balancer health checks

Security Maintenance

  • Regular vulnerability scanning
  • Certificate rotation automation
  • Access audit and review

Conclusion and Next Steps

You now have a production-ready Harbor container registry deployed on RKE2 using SUSE Application Collection. This enterprise-grade setup provides:

  • Secure container registry with vulnerability scanning and content trust
  • High availability with replicated storage and multi-node deployment
  • Enterprise authentication via LDAP/OIDC integration
  • Automated certificate management with cert-manager
  • Comprehensive monitoring and alerting capabilities

This foundation provides the enterprise container management platform needed for modern cloud-native applications. The combination of Harbor’s security features with RKE2’s hardened Kubernetes distribution creates a robust platform suitable for demanding production environments.

Ready for GitOps?

In the next part of this series, we’ll cover ArgoCD installation and integration with Harbor, including:

  • ArgoCD deployment via SUSE Application Collection
  • Private registry integration with Harbor
  • GitOps workflows and security policies
  • Automated CI/CD pipeline configurations

This Harbor registry will serve as the foundation for your complete GitOps workflow, providing secure image storage and distribution for your Kubernetes applications.