mirror of
https://github.com/jpetazzo/container.training.git
synced 2026-07-16 03:19:18 +00:00
🚢 Add small hands-on chapter about Harbor
This commit is contained in:
253
slides/k8s/harbor.md
Normal file
253
slides/k8s/harbor.md
Normal 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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user