Go to file
Lauri Võsandi 0c9710cb13
All checks were successful
continuous-integration/drone Build is passing
Add logging for image mutation
2022-12-22 22:01:20 +02:00
app Add logging for image mutation 2022-12-22 22:01:20 +02:00
crds Initial commit 2022-12-15 06:43:56 +02:00
templates Schedule only on amd64 nodes 2022-12-20 09:16:54 +02:00
.drone.yml Initial commit 2022-12-15 06:43:56 +02:00
.gitignore Initial commit 2022-12-15 06:43:56 +02:00
Chart.yaml Initial commit 2022-12-15 06:43:56 +02:00
Dockerfile Initial commit 2022-12-15 06:43:56 +02:00
README.md Update README 2022-12-15 10:28:31 +02:00
values.yaml Update README 2022-12-15 10:28:31 +02:00

harbor-operator

Background

Note that this project is NOT connected to official Harbor operator.

The main reason we decided to write our own operator was that the official operator was missing all the features we wanted to have and mainlining such features would likely take months.

This operator is higly opinionated way to deploy Harbor in a Kubernetes cluster using Helm:

  • Only one Harbor instance per Kubernetes cluster
  • Nearly all components deployed in HA fashion
  • Automates Harbor project creation via ClusterHarborProject CRD
    • Create per user projects with quotas and password protection
    • Create proxy cache projects with quotas and password protection
  • Designed to work in conjunction with https://git.k-space.ee/k-space/sandbox-dashboard:
    • Sandbox template repository contains HarborCredential definitions
    • Sandbox dashboard adds ClusterUser resources when user logs in
  • Automate push/pull credential provisioning using HarborCredential CRD-s, to simplify working with Skaffold
  • Pod admission mutation webhook to rewrite Pod images to use proxy caches defined via ClusterHarborProject definitions with cache: true.

Caveats:

  • User must have logged in with OIDC first before ClusterHarborProjectMember CRD will have effect and it will take operator several minutes to pick up the change.

Instantiating Harbor projects

To instantiate proxy cache project:

---
apiVersion: codemowers.io/v1alpha1
kind: ClusterHarborRegistry
metadata:
  name: quay.io
spec:
  type: quay
  endpoint: https://quay.io
---
apiVersion: codemowers.io/v1alpha1
kind: ClusterHarborRegistry
metadata:
  name: docker.io
spec:
  type: docker-hub
  endpoint: https://docker.io
---
apiVersion: codemowers.io/v1alpha1
kind: ClusterHarborProject
metadata:
  name: docker.io
spec:
  cache: true
  public: true
  quota: 10737418240
---
apiVersion: codemowers.io/v1alpha1
kind: ClusterHarborProject
metadata:
  name: quay.io
spec:
  cache: true
  public: true
  quota: 10737418240

To instantiate Harbor project:

apiVersion: codemowers.io/v1alpha1
kind: ClusterHarborProject
metadata:
  name: k-space
spec:
  cache: false
  public: true
  quota: 10737418240

Deploying push/pull secrets into namespaces

Once everything is running you can easily provision Harbor project push and pull secrets into namespaces:

---
apiVersion: codemowers.io/v1alpha1
kind: HarborCredential
metadata:
  name: kaniko
spec:
  project: foobar
  key: config.json
  permissions:
    - resource: repository
      action: pull
    - resource: tag
      action: create
    - resource: repository
      action: push
---
apiVersion: codemowers.io/v1alpha1
kind: HarborCredential
metadata:
  name: regcred
spec:
  project: foobar
  type: kubernetes.io/dockerconfigjson
  key: .dockerconfigjson
  permissions:
    - resource: repository
      action: pull

Uninstalling

The finalizers will likely block deletion of resources:

for j in $(
    kubectl get harborcredentials -o name;
    kubectl get clusterharborprojectmembers -o name;
    kubectl get clusterharborprojects -o name;
    kubectl get clusterharborregistries -o name ); do
  echo "Removing $j"
  kubectl patch $j --type json --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
  kubectl delete $j
done