Some tasks in DevOps are repetitive and boring, setting up a TLS-enabled Docker registry is one of those things, however today I'm going to show you just how easy it can be thanks to open-source automation tools like k3sup.
"k3sup" or (ketchup) is a Kubernetes bootstrapping tool which also has its own apps ecosystem. Each app wraps a helm chart, or a templated Kubernetes manifest file crafted for the job at hand.
First decide whether you want to set this up locally, or on a cluster with a public IP address. Both are fair-game and can get a TLS certificate, the public cluster can use a NodePort, or a LoadBalancer, and private clusters can use the inlets project to provide an IP from a VM in the cloud.
Bill of materials
Pictured: a registry on public cloud using an IngressController with a LoadBalancer.
- A Kubernetes cluster, local, remote or on public cloud - this also works on a Raspberry Pi
- An existing domain-name - or buy one from 1 USD
- nginx-ingress, Traefik, or another IngressController - to serve HTTPS traffic
- cert-manager - to obtain TLS certificates
- docker-registry - an open source Docker registry
- inlets-operator (optional) - required if running on-premises or on your laptop
curl -sLS https://get.k3sup.dev | sh sudo install k3sup /usr/local/bin/ k3sup --help
Note: Windows users should use Git Bash, find out more at https://k3sup.dev
Get a domain
You may already have a domain, if you don't you can pay between 1 USD and 10 USD for this and then it's yours for a year.
My favourites are:
You can also bring your own existing domain. Why is that needed? It's how TLS certificates work, and a proper Docker registry needs a certificate for encryption.
All-in-one for cloud users
k3sup app install nginx-ingress k3sup app install cert-manager k3sup app install docker-registry k3sup app install docker-registry-ingress \ --email firstname.lastname@example.org \ --domain reg.example.com
Each command installs the upstream helm chart using defaults and provides several popular overrides, just run
k3sup app install APP --help for more.
docker-registry-ingress app generates a cert-manager ClusterIssuer and an Ingress record for the Registry.
Did you know? You can read all the code on GitHub, and star/fork the project.
What if you use Traefik instead? That's fine, just add your
--ingress-class to the
k3sup app install docker-registry-ingress \ --email email@example.com \ --domain reg.example.com \ --ingress-class traefik
Does your cloud not support
LoadBalancer? Install Nginx in host mode to make use of the node's IP address, try
k3sup app install nginx-ingress --help for more settings.
Private clusters / local use
If you're running a cluster on your Raspberry Pi cluster, laptop with Minikube, KinD, or k3d, or in the lab, then don't worry, you can still use the steps above, but you'll need to create a tunnel for your IngressController.
You can use the inlets-operator to create a cloud host and a secure Cloud Native tunnel between your local Kubernetes Services and the Internet. Any service of type LoadBalancer will be exposed automatically on the cheapest VM available from your IaaS provider. For DigitalOcean that's as low as 5 USD / mo.
Pictured: a registry running on a private cluster using a secure Cloud Native Tunnel to obtain a public IP address.
If you want to use TLS, and that's what this tutorial is about, then you'll need inlets-pro, inlets OSS can be used if you want an insecure tunnel, or if you are happy to configure everything on your own.
Set your licence in
Get an encrypted tunnel and public IP for your cluster by using a cloud host/VM as an exit-node
Create an access token for one of the supported cloud providers such as DigitalOcean. Get free DigitalOcean credits here if you don't have an account yet.
Save your access token as a file:
~/access-token.txt - you can create this in your dashboard under "Api".
Set the region to your closest, for me that's
k3sup app install inlets-operator \ --license $LICENSE \ --provider digitalocean \ --acces-token-file ~/access-token.txt \ --region lon1
You'll now be able to see your IP address go from "Pending" to a real IP for any LoadBalancer in your cluster.
kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) traefik LoadBalancer 10.43.217.239 126.96.36.199 80:31563/TCP,443:32156/TCP
In my example the IP for use is
188.8.131.52, which will route through to my Raspberry Pi in my house.
If you want to use GCP or another cloud, find out the flags and options in the helm chart and use
--set key=valueor run
k3sup app install NAME --help. For instance, the provider for Packet.com also requires a
Setup your DNS
Next, set up a DNS A record between the IP address of Nginx, or your custom IngressController and the domain you used for the
docker-registry-ingress app i.e.
Well, that's it, we're done now and there's nothing more to see. Enjoy your Docker registry.
docker tag alpine:3.11 reg.example.com/alpine:3.11 docker push reg.example.com/alpine:3.11 docker pull reg.example.com/alpine:3.11
If you're planning on using the registry with Kubernetes, then you will need to configure an ImagePullSecret for your Pods, you can also configure this at the namespace-level for a ServiceAccount.
If you run into any issues, then feel free to join the
#k3sup channel on OpenFaaS Slack
What else can I do?
Check out the other apps for k3sup, or feel free to suggest your own additionals. Most of the apps are multi-arch which means they can run on Intel and ARM (think Raspberry Pi, Ampere, or AWS Graviton).
We're adding new apps all the time, so checkout the list and keep up to date with
k3sup app install --help
k3sup also bootstraps Kubernetes clusters using
ssh, it can be a great way of getting up and running in a short period of time. You can find a list of blog posts and tutorials in the project README
Try one of my other tutorials for inlets or inlets-pro:
- Share work with clients using inlets
- Get kubectl access to your private cluster from anywhere
- Build a 10 USD Raspberry Pi Tunnel Gateway
Connect with me: