🎯 LESSON OBJECTIVE__HTMLTAG_66___
- ✅ Harbor architecture and components
- ✅ Deploy Harbor HA on K8s
- ✅ Trivy vulnerability scanning automatically
- ✅ Image signing and verification (cosign + Notation)
- ✅ Replication policies (multi-site)
- ✅ Supply chain security best practices
PART 1: HARBOR ARCHITECTURE
Harbor Components:
┌──────────────────────────────────────────────┐
│ Harbor │
│ │
│ ┌────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Core │ │ Portal │ │ Job Service │ │
│ │ (API) │ │ (Web UI)│ │ (async tasks)│ │
│ └────┬───┘ └──────────┘ └──────────────┘ │
│ │ │
│ ┌────▼───┐ ┌──────────┐ ┌──────────────┐ │
│ │Registry│ │ Trivy │ │ Notary/ │ │
│ │(images)│ │ (scanner)│ │ Cosign │ │
│ └────┬───┘ └──────────┘ └──────────────┘ │
│ │ │
│ ┌────▼────────────────────────────────────┐ │
│ │ Storage Backend │ │
│ │ (S3/Ceph RGW/local filesystem) │ │
│ └─────────────────────────────────────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │PostgreSQL│ │ Redis │ │
│ │(metadata)│ │ (cache) │ │
│ └──────────┘ └──────────┘ │
└──────────────────────────────────────────────┘
PART 2: DEPLOY HARBOR HA
# Install Harbor:
helm repo add harbor https://helm.goharbor.io
helm repo update
helm install harbor harbor/harbor \
--namespace harbor \
--create-namespace \
-f harbor-values.yaml
# harbor-values.yaml:
expose:
type: ingress
tls:
enabled: true
certSource: secret
secret:
secretName: harbor-tls
ingress:
hosts:
core: harbor.local
className: istio
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
externalURL: https://harbor.local
persistence:
enabled: true
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
storageClass: ceph-block
size: 100Gi
database:
storageClass: ceph-block
size: 10Gi
redis:
storageClass: ceph-block
size: 5Gi
trivy:
storageClass: ceph-block
size: 5Gi
# Use external PostgreSQL (CloudNativePG):
database:
type: external
external:
host: postgresql-rw.database
port: "5432"
username: harbor
password: harbor-password
sslmode: require
# Use external Redis:
redis:
type: external
external:
addr: redis-master.database:6379
password: redis-password
# Trivy scanner:
trivy:
enabled: true
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1
memory: 1Gi
# HA replicas:
core:
replicas: 2
portal:
replicas: 2
registry:
replicas: 2
jobservice:
replicas: 2
PART 3: VULNERABILITY SCANNING
# Configure auto-scan on push:
# Harbor UI → Administration → Configuration → Scanner
# ✅ Automatically scan images on push
# Manual scan via API:
curl -X POST "https://harbor.local/api/v2.0/projects/myproject/repositories/order-service/artifacts/sha256:abc123/scan" \
-H "Authorization: Basic $(echo -n admin:password | base64)"
# Get scan results:
curl "https://harbor.local/api/v2.0/projects/myproject/repositories/order-service/artifacts/sha256:abc123/additions/vulnerabilities" \
-H "Authorization: Basic $(echo -n admin:password | base64)"
# Block images with critical CVEs (Harbor project policy):
# Harbor UI → Project → Configuration:
# ✅ Prevent vulnerable images from running
# Severity: Critical, High
# Integrate with Kyverno:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: check-harbor-vulnerability
spec:
validationFailureAction: Enforce
rules:
- name: check-scan-status
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "Images must be scanned and free of critical vulnerabilities"
deny:
conditions:
any:
- key: "{{ images.containers.*.registry }}"
operator: AnyIn
value: ["harbor.local"]
PART 4: IMAGE SIGNING
# Generate cosign key pair:
cosign generate-key-pair
# Sign image after push:
cosign sign --key cosign.key harbor.local/myproject/order-service:v1.0
# Verify signature:
cosign verify --key cosign.pub harbor.local/myproject/order-service:v1.0
# Sign with annotations:
cosign sign --key cosign.key \
-a "git_sha=$(git rev-parse HEAD)" \
-a "pipeline=github-actions" \
-a "signed_by=ci-bot" \
harbor.local/myproject/order-service:v1.0
# CI/CD pipeline with signing:
# .github/workflows/build.yml
jobs:
build:
steps:
- name: Build & Push
run: |
docker build -t harbor.local/myproject/order-service:${{ github.sha }} .
docker push harbor.local/myproject/order-service:${{ github.sha }}
- name: Sign Image
run: |
cosign sign --key env://COSIGN_PRIVATE_KEY \
harbor.local/myproject/order-service:${{ github.sha }}
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
- name: Scan Image
run: |
trivy image --severity CRITICAL,HIGH \
--exit-code 1 \
harbor.local/myproject/order-service:${{ github.sha }}
PART 5: REPLICATION & GARBAGE COLLECTION
# Replication policy (pull from Docker Hub):
# Harbor UI → Administration → Replications → New Rule:
# Name: dockerhub-proxy
# Direction: Pull-based
# Source: Docker Hub
# Destination: harbor.local/proxy-cache
# Trigger: Event-based (on-demand)
# Garbage collection (remove untagged blobs):
# Harbor UI → Administration → Clean Up → GC
# Schedule: Weekly
# ✅ Delete untagged artifacts
# K8s CronJob for GC:
apiVersion: batch/v1
kind: CronJob
metadata:
name: harbor-gc
namespace: harbor
spec:
schedule: "0 2 * * 0" # Sunday 2AM
jobTemplate:
spec:
template:
spec:
containers:
- name: gc
image: curlimages/curl:latest
command:
- /bin/sh
- -c
- |
curl -X POST "https://harbor.local/api/v2.0/system/gc/schedule" \
-H "Authorization: Basic $(echo -n admin:password | base64)" \
-H "Content-Type: application/json" \
-d '{"parameters":{"delete_untagged":true},"schedule":{"type":"Manual"}}'
restartPolicy: OnFailure
PART 6: KUBERNETES INTEGRATION
# Create pull secret:
kubectl create secret docker-registry harbor-creds \
--docker-server=harbor.local \
--docker-username=robot\$myproject+pull \
--docker-password="robot-token" \
-n default
# Use robot account (least privilege):
# Harbor UI → Project → Robot Accounts → New
# Name: pull-only
# Permissions: Pull only
# Deployment with Harbor image:
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
template:
spec:
imagePullSecrets:
- name: harbor-creds
containers:
- name: app
image: harbor.local/myproject/order-service:v1.0
# Use digest for immutability:
# image: harbor.local/myproject/order-service@sha256:abc123...
💡 KEY TAKEAWAYS
- Harbor: Enterprise container registry with scanning, signing, replication
- Trivy: Auto-scan on push, block critical vulnerabilities
- Cosign: Sign images in CI/CD, verify with Kyverno
- Robot accounts: Least privilege pull access
- Image digests: Use sha256 digest for immutable references
- GC: Regular garbage collection to reclaim storage
🎯 EXERCISE
Exercise 1: Harbor Setup__HTMLTAG_132___
- Deploy Harbor, create project__HTMLTAG_135___
- Push image, verify auto-scan__HTMLTAG_137___
- Configure blocking policy for critical CVEs
Exercise 2: Image Signing Pipeline__HTMLTAG_142___
- Generate cosign keys
- Build CI pipeline: build → scan → sign → push
- Configure Kyverno to verify signatures__HTMLTAG_149___
📚 NEXT POST
In Lesson 40: Canary & Blue-Green Deployment, we will start Section 10 — Deployment Patterns & Auto-Scaling.