5.9 KiB
Running a Harbor registry
-
There are many open source registries available out there
-
We're going to show an end-to-end example using a very popular one:
-
We will:
-
install Harbor
-
create a private registry on Harbor
-
set up an automated build pipeline pushing images to Harbor
-
configure an app to use images from the private registry
-
Requirements
-
Virtually all registry clients require TLS when communicating with registries
(one exception: when the registry is on
localhost) -
This means that we'll need a valid TLS certificate for our registry
-
We can easily get one with cert-manager and e.g. Let's Encrypt
(as long as we can associate a domain with our ingress controller)
-
To run the demos in this chapter, we need a domain name!
Alternatives
-
We could configure our build pipeline to ignore certificates
(so that it can push images without complaining)
-
We could hack something so that the registry is available over
localhost -
Or we could add the registry's certificate everywhere
(in our build pipeline, on our container engines...)
-
These extra steps are out of scope for this chapter
-
We need a domain name!
Automating TLS certificates
-
Let's install Traefik:
kubectl apply -f ~/container.training/k8s/traefik.yml -
And cert-manager:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.1/cert-manager.yaml -
Edit the
ClusterIssuermanifest and apply it:vim ~/container.training/k8s/cm-clusterissuer.yaml kubectl apply -f ~/container.training/k8s/cm-clusterissuer.yaml⚠️ Make sure to update the cluster issuer name to
letsencrypt-production!
Checking that it works
-
Deploy a simple application and expose it with TLS:
kubectl create deployment blue --image jpetazzo/color --replicas 2 --port 80 kubectl expose deployment blue kubectl create ingress blue --rule=blue.`$DOMAIN`/*=blue:80,tls \ --annotation cert-manager.io/cluster-issuer=letsencrypt-production -
Check that the certificate was correctly issued:
kubectl get cert curl https://blue.`$DOMAIN`/
Deploying Harbor
-
There is a Helm chart (https://artifacthub.io/packages/helm/harbor/harbor)
-
Let's install it:
helm upgrade --install --repo https://helm.goharbor.io \ --namespace harbor --create-namespace harbor harbor \ --set persistence.enabled=false \ --set expose.ingress.hosts.core=harbor.`$DOMAIN` \ --set expose.ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-production \ --version 1.18.0 -
Wait until all pods are
Runningin theharbornamespace
Logging into Harbor
-
Go to https://harbor.$DOMAIN/
-
The default login is
admin -
The default password is
Harbor12345(yes, it would be a good idea to change that in production😁)
Creating a new repository
-
In Harbor, repositories are associated to "projects"
-
Create a new project named
dockercoins
Creating Harbor users
-
We will create two "robot accounts":
-
one with
pushpermission (for the build pipeline) -
one with
pullpermission (for our Kubernetes workloads)
-
-
Create a first robot account,
dockercoins-push-
don't give any systems permission
-
for project permissions, check
dockercoins -
then select permissions, check
pushandpull
-
-
Write down the user and password!
Setting up the build pipeline
-
This part requires a GitHub account
-
On GitHub, fork https://github.com/jpetazzo/dockercoins
(it has a GitHub Actions workflow that is almost ready to use!)
-
In your fork, go to settings / secrets and variables / actions
-
Create the following secrets:
REGISTRY_ADDRESS=harbor.$DOMAIN(make sure to enter the real domain of course!)REGISTRY_USERNAME= the user name generated by HarborREGISTRY_PASSWORD= the password generated by Harbor
Setting up the build pipeline
-
Edit
.github/workflows/automated-build.yaml -
Comment out the steps related to GitHub Container Registry and Docker Hub
-
Uncomment the steps related to the custom external registry
-
Commit
-
In your fork, click on the "Actions" button on top
-
You should see the workflow running
-
After a couple of minutes, it should (hopefully) report success
Creating the pull robot account
-
In Harbor, create another robot account
-
Let's name it
dockercoins-pull -
Again, don't give it any systems permission
-
Give it
pullpermissions for thedockercionsproject -
Write down the user and password
Create a Secret for the pull account
-
Let's create a Kubernetes Secret holding the registry credentials:
kubectl create secret docker-registry dockercoins-pull \ --docker-username '`robot$dockercoins-pull``' \ --docker-password `abcdefghijKLMNOPQRST` \ --docker-server harbor.`$DOMAIN` -
Make sure to quote the username (the
$will cause problems otherwise)
Use the Secret
-
We have two possibilities here:
-
add
imagePullSecretsto every Pod template that needs them -
add
imagePullSecretsto the ServiceAccount used by the Pods
-
-
Let's patch the default ServiceAccount:
kubectl patch serviceaccount default \ --patch 'imagePullSecrets: [ name: dockercoins-pull ]'
Use the private registry
-
Make a copy of
~/container.training/k8s/dockercoins.yml -
In that copy, replace every
dockercoins/*image withharbor.$DOMAIN/dockercoins/*(put the actual domain, not
$DOMAIN!) -
Apply that YAML
-
Check that the application is up and running
-
Check that the number of pulls has increased in the Harbor web UI
-
Congratulations, you've deployed an image from a self-hosted private registry! 🎉
???
:EN:- Hosting private images with Harbor :FR:- Héberger des images privées avec Harbor