diff --git a/slides/k8s/harbor.md b/slides/k8s/harbor.md new file mode 100644 index 00000000..50081384 --- /dev/null +++ b/slides/k8s/harbor.md @@ -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