Chuyển đến nội dung chính

LESSON 39: HARBOR REGISTRY & IMAGE SECURITY

Deploy Harbor private registry, Trivy vulnerability scanning, image signing with cosign, replication policies, and container image supply chain security.

🔒 DevSecOps — Lesson 39 LESSON 39: HARBOR REGISTRY & IMAGE SECURITY

Deploy Microservices On-Premises with Kubernetes HA

Part 9: Security Hardening

xdev.asia

🎯 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

  1. Harbor: Enterprise container registry with scanning, signing, replication
  2. Trivy: Auto-scan on push, block critical vulnerabilities
  3. Cosign: Sign images in CI/CD, verify with Kyverno
  4. Robot accounts: Least privilege pull access
  5. Image digests: Use sha256 digest for immutable references
  6. 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.