Skip to content

Today I learned

Learn something new every day

Menu
  • Home
  • About
  • Hello World! and Why I Started This Blog
Menu

How to Make Your Kubernetes Dev Cycle Faster

Posted on 27/04/202325/04/2023 by Sagi Rosenthal

Today I learned how to release a new version for dev testing faster. By leveraging external tools, and installing in-cluster components you can enhance your dev cycle, deploy new versions at the speed of light, and, eventually, bring new features in less time.

Usually, the development cycle consists of shorter and longer cycles. You start with writing several functions and then check the basic operation with a unittest or two. Your next step will probably be to create a version of it. But is not always enough. Your product might not easily be tested as a binary or in a stand-alone run through the IDE.

And anyway, you will want eventually to test it on your dev cluster. The environment in a Kubernetes cluster is different than your local laptop. Sometimes the liveness and readiness probes will fail with the new feature. That is if the cluster managed to even start your new image. These are the things you want to make sure to be working before creating a PR.

About the Dev Cycle

When you unittest your function at the start of the developing process, you encounter a lot of errors and issues. Undeclared variable, wrong return type, missing dependency… All can be solved easily with a slight change, and to rerun the test. The period from changing this small line to the feedback of the other error from the test I call the “dev cycle”. At the beginning of the feature, it is short since we check it with a simple unittest that compiles within a second. But later, when a deployment to a cluster is needed… You can sit back and relax as running it through the build pipeline can take more than a few minutes.

The Solution

In order to make this cycle shorter and faster, you can choose from many solutions. One of them is to use Skaffold. It handles the workflow for building, pushing, and deploying your application to Kubernetes. But for some use cases, it may be complex to use. For example, I’m my workplace we have a very specific upgrade strategy that cannot be copied with Helm or kubectl. Or when working with several components it makes the initialization of Skaffold painful.

The other solution is to run a container registry inside the cluster. Which have a lot of pros:

  • You don’t need permission to push. Sometimes companies only allow formal pipelines to push so this overrides this issue.
  • You leverage the build-cache as you can push locally-built images.
  • Save money, as you store fewer images (do you ever delete old and stale images from the company registry? I don’t think so…).
  • Faster push and way faster pull as the bandwidth to your cluster is usually larger and pulling from inside the cluster is lightning-fast.
  • Unlimited API queries. Usually, dockerhub allows 100-200 pulls per 6 hours or 5000 if you have paid account. The local registry does not have this limit.
  • you can use whatever name you want for images and tags.

Let’s start! In order to create a local registry we will need several components: a namespace (optional), a deployment, Volume (persistent volume claim), and a service. I used bare-metal Kubernetes and a virtual (kind/docker) one so if you want to host it in your cloud provider things might be different.

apiVersion: v1
kind: Namespace
metadata:
  name: docker-registry
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: registry-pvc
  namespace: docker-registry
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: registry
  namespace: docker-registry
spec:
  replicas: 1
  selector:
    matchLabels:
      app: registry
  template:
    metadata:
      labels:
        app: registry
    spec:
      containers:
      - name: registry
        image: registry:2
        ports:
        - containerPort: 5000
        volumeMounts:
        - name: registry-storage
          mountPath: /var/lib/registry
      volumes:
      - name: registry-storage
        persistentVolumeClaim:
          claimName: registry-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: registry
  namespace: docker-registry
  labels:
    app: registry
spec:
  type: NodePort
  ports:
  - port: 5000
    targetPort: 5000
    nodePort: 30500
  selector:
    app: registry

in order to push you’ll need to tag your images with <clusterIP>:30500/<image_name>:<image_tag> and pulling from inside the cluster should be the same.

A final note: your deployment may vary and you’ll want to use a load-balancer instead of a node port, or you might have an HTTPS issue. But trust me, invest a few minutes to resolve these issues once, and you’ll gain back hundreds of hours back. It made my deployment 10 times faster. From 10-20 minutes to 1-2.

Further Reading

Skaffold – https://skaffold.dev/
Docker registry image – https://hub.docker.com/_/registry
Adding TLS certificate – https://docs.docker.com/registry/deploying/#run-an-externally-accessible-registry
Remove images from the registry – https://gist.github.com/jaytaylor/86d5efaddda926a25fa68c263830dac1

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

CAPTCHA


Recent Posts

  • How to Sell Stuff Online
  • How to Make Your Kubernetes Dev Cycle Faster
  • How To Be A Valuable Team Member
  • Don’t Make, Go Generate It
  • Why You Should Monkey Patch Your Next Unit-Test

Archives

  • July 2023
  • April 2023
  • January 2023
  • November 2022
  • August 2022
  • July 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022

Categories

  • Go
  • Learning
  • Software Utilities
Join the updates channel
© 2026 Today I learned | Powered by Minimalist Blog WordPress Theme