🚢 Add small hands-on chapter about Harbor

This commit is contained in:
Jérôme Petazzoni
2025-11-11 18:13:05 +01:00
parent 570ec8b25e
commit 890b76e119
2 changed files with 254 additions and 0 deletions

253
slides/k8s/harbor.md Normal file
View File

@@ -0,0 +1,253 @@
# 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:
[Harbor](https://goharbor.io) (https://goharbor.io)
- 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:
```bash
kubectl apply -f ~/container.training/k8s/traefik.yml
```
- And cert-manager:
```bash
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.19.1/cert-manager.yaml
```
- Edit the `ClusterIssuer` manifest and apply it:
```bash
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:
```bash
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:
```bash
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:
```bash
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 `Running` in the `harbor` namespace
---
## 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 `push` permission (for the build pipeline)
- one with `pull` permission (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 `push` and `pull`
- 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 Harbor
`REGISTRY_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 `pull` permissions for the `dockercions` project
- Write down the user and password
---
## Create a Secret for the `pull` account
- Let's create a Kubernetes Secret holding the registry credentials:
```bash
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 `imagePullSecrets` to every Pod template that needs them
- add `imagePullSecrets` to the ServiceAccount used by the Pods
- Let's patch the default ServiceAccount:
```bash
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 with `harbor.$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

View File

@@ -101,6 +101,7 @@ content:
#- k8s/exercise-helm.md
- k8s/gitlab.md
- k8s/ytt.md
- k8s/harbor.md
-
- k8s/netpol.md
- k8s/authn-authz.md