Kubernetes: Own Your Docker Registry Already!
I’ll have to admit it, I absolutely love Kubernetes! Having the ability to deploy a close to full environment on my local machine is a real treat. You can hone your deployment recipes and configurations along with your code from the Get-go.
That said, there is a bit of a pain point currently. Having to push Docker images to a remote registry to later download them back to my local machine is a royal pain in the ass. What I would rather have, is a local Docker Registry that both Docker and Kubernetes know about and from which I can push/pull my Docker images .
The following walks you thru on how to achieve this and hopefully makes your local dev K8s adventures a little bit more sane…
Docker Registry Deployment
The first thing we need to do is define a K8s deployment for our local Docker registry. For this we will use the official Docker image.
# configs/registry/dp.yml kind: Deployment apiVersion: extensions/v1beta1 metadata: name: registry labels: app: registry spec: replicas: 1 template: metadata: labels: app: registry spec: containers: - name: registry image: docker.io/registry:2 ports: - containerPort: 5000 name: client
Docker Registry Service
Next, we define a service to front our registry. Node that we are making this service externally available so we can access it from our localhost.
# configs/registry/svc.yml kind: Service apiVersion: v1 metadata: name: registry labels: app: registry spec: type: LoadBalancer selector: app: registry ports: - name: client port: 5000 targetPort: client status: loadBalancer: ingress: - ip: 0.0.0.0
Now let’s schedule our recipes.
ku create -f config/registry/dp.yml -f config/registry/svc.yml
Retrieve Docker Registry Service Host/Port
Next, we need to record our registry service NodePort and Vagrant minion IP. Let’s assume the NodePort will be 30123 and our Vagrant minion IP is 10.10.10.1
ku describe svc registry | grep NodePort ku describe no | grep Address
Configure Your DockerMachine
The Docker registry should be up and running and accessible from our localhost. The key now is to tell docker-machine to use that registry instead of the default.
# Create a new machine using your own Docker registry docker-machine create --driver virtualbox --engine-insecure-registry 10.10.10.1:30123 k8s
Building And Pushing Our Service Image
Say we have our coolio Blee service for which we’ve have an associated Dockerfile. We need to push our service image to our new K8s registry.
# Switch to your new docker machine eval $(docker-machine env k8s) # Build and tag your image docker build -f Dockerfile --rm -t 10.10.10.1:30123/blee:0.0.1 . # Publish image to your own registry docker push 10.10.10.1:30123/blee # List out your new image docker images
Create Your New Service Deployment
Next, we will define a deployment for our Blee service and tell Kubernetes to use the image from our own Docker registry.
#configs/blee/dp/yml kind: Deployment apiVersion: extensions/v1beta1 metadata: name: blee labels: app: blee spec: replicas: 1 template: metadata: labels: app: blee spec: containers: - name: blee image: 10.10.10.1:30123/blee:0.0.1 ports: - containerPort: 3500 name: client
Now deploy it!
ku create -f configs/blee/dp.yml
We can now test out our new service, tweak the image and deployment, perform rolling update with a great rate of speed and convenience. No longer do we need to hang out while the image is being pulled or pushed. We can rinse and repeat this process to our heart content til we get it just right. Once satisfied with our image and k8s recipes, we can officially deploy to our favorite external Docker hub and prepare for mass consumption!