Develop Kubernetes native applications in Golang with autorecompile and autorestart

Do you develop or plan to develop a Kubernetes native application in Golang, controller or operator? Such application strongly depends on being inside Kubernetes and development outside of Kubernetes may be a real hassle. Usually you have to build an image over and over again and restart the pod (with imagePullPolicy set to Always). This is very boring and time consuming procedure.

Two years ago I developed an image to auto-recompile and auto-restart Go application, named go-reflex,  but it was intented to be used by docker-compose. Today I gave it a try with Kubernetes, namely with kind (Kubernetes in Docker) and it turned out it works like a charm. In this article I will describe how to set this up and save your time for something creative (i.e. beer drinking).

As a first step, install kind and create local cluster:

GO111MODULE="on" go get sigs.k8s.io/kind@v0.8.1

Now create a kind config file config.yaml:

apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
  - role: control-plane
    extraMounts:
      - hostPath: /path/to/your/project/root
        containerPath: /app

Modify hostPath to match your project root directory and create the cluster:

kind create cluster --config=config.yaml

Follow the instructions how to configure kubectl. Now deploy your pod to the cluster using the following manifest (deploy.yaml):

apiVersion: v1
kind: Pod
metadata:
  name: your-app-name
  namespace: default
spec:
  containers:
    - image: acim/go-reflex:1.15.0-r0
      name: your-app-name
      env:
      - name: RACE_DETECTOR
        value: "1"
      volumeMounts:
        - mountPath: /app
          name: app
  restartPolicy: Never
  volumes:
    - hostPath:
        path: /app
      name: app

Replace your-app-name with the name you want. Finally create this object within the kind cluster:

kubectl apply -f deploy.yaml

Connect to your application using standard kubectl port forwarding:

kubectl port-forward your-app-name 3000:3000

Replace the second port number with correct port number where your application listens on and access it in browser or some REST client on port 3000 on your localhost.

Try to modify some .go file in your application repository and notice that your application is going to be automatically recompiled and restarted inside the cluster. You can track this by following the logs:

kubectl logs -f your-app-name

That's all, you are ready to make another great Kubernetes operator.

Note: Take care that your main package is in the root directory of the project, otherwise this won't work out of the box. In some other scenario you would have to make your own Dockerfile upon the original one from go-reflex.