Important
This operator does not install Harbor in “real” clusters.
It assumes Harbor is already running and introduces a HarborConnection CRD
that stores connection details for that instance.
All other CRDs reference a HarborConnection.
harbor-operator is a Kubernetes operator that lets you manage Harbor resources — registries, projects, users, and members — as Kubernetes Custom Resources (CRs).
Instead of clicking around in the Harbor UI, you describe your desired state in YAML. The operator then reconciles that state with your Harbor instance via its API.
-
HarborConnection
Connection details for an existing Harbor instance (base URL, optional credentials). All other CRs reference this. -
Registry
Represents a Harbor “target registry” (e.g. GHCR) and its configuration. -
Project
Represents a Harbor project, including metadata (public/private, auto-scan, etc.). -
User
Represents a Harbor user and (optionally) its lifecycle. -
Member
Represents membership of a user or group in a Harbor project with a given role.
- Go
- Docker (or compatible container runtime)
- kubectl
- A Kubernetes cluster (Kind is fine for dev)
This repo ships with a Kind-based dev environment that:
- Creates a Kind cluster
- Installs Traefik
- Installs Harbor via the official Helm chart
- Builds and deploys harbor-operator into that cluster
This is just for development convenience. In a real environment, you bring your own Harbor.
Add this line to /etc/hosts (or your platform’s hosts file):
127.0.0.1 core.harbor.domainmake kind-upThis will:
- Create a Kind cluster using
hack/kind-configuration.yaml - Install Traefik (NodePorts 30080/30443 by default)
- Install Harbor via Helm
- Build a local
harbor-operator:localimage, load it into Kind, and deploy it
If you also want sample CRs applied:
make kind-up-with-samplesApply or remove sample CRs (in config/samples):
# Apply sample HarborConnection, Registry, Project, etc.
make samples-apply
# Delete all Harbor CRs (HarborConnection last) in all namespaces
make clean-samples
clean-samplesremoves all custom resources in theharbor.harbor-operator.ioAPI group, not just the manifests inconfig/samples/.
If you change the operator code:
make kind-redeployThis will:
- Delete all Harbor CRs managed by the operator (HarborConnection last)
- Remove the operator deployment and CRDs
- Rebuild the image
- Load it into Kind
- Reinstall CRDs and redeploy the operator
To delete only the Kind cluster:
make kind-downFor a non-Kind cluster, you typically:
-
Make sure an image of the operator is available to the cluster (e.g. build+push in CI to
ghcr.io/.../harbor-operator:<tag>). -
Install CRDs:
make install
-
Configure the operator image in
config/manager/kustomization.yamlor via:cd config/manager kustomize edit set image controller=<your-registry>/harbor-operator:<tag>
-
Deploy the operator:
make deploy
-
Create a
HarborConnectionand anyRegistry/Project/User/MemberCRs you need.
If you want to ship a single install.yaml that contains CRDs plus the operator deployment:
make build-installerThis will:
- Set the image in
config/managertoharbor-operator:local(or whateverIMG_LOCALis) - Build
config/defaultwith kustomize - Write the result to
dist/install.yaml
You can then install with:
kubectl apply -f dist/install.yamlIf you publish this file (e.g. in a GitHub release), users can install via a raw URL.
If you want to remove Harbor-managed resources, CRDs, and the operator:
# Remove Harbor CRs (HarborConnection last)
make clean-samples
# Remove CRDs for the harbor.harbor-operator.io API group
make uninstall
# Remove the operator deployment
make undeployIn a Kind dev cluster, a full reset is just:
make kind-reset
# or
make kind-down-
Format and vet:
make fmt vet
-
Run tests:
make test -
Run linters:
make lint
Open a PR with a clear description of what you changed and why.