edge-status-api
A small Go HTTP service used to practise deploying applications to Kubernetes, including container builds, Helm packaging, health probes and resource configuration.
- Go
- Kubernetes
- Helm
- Talos
- Docker
A small Go HTTP service deployed to my Talos Kubernetes cluster. I kept the application simple so I could focus on the deployment workflow: building the container, packaging it with Helm and configuring how Kubernetes runs and exposes it.
Why I kept the application simple
I wanted the gap between “I wrote a program” and “it is serving traffic in a cluster” under a microscope. An application with a database in it hides that gap. You end up debugging migrations instead of the deploy.
So the app does almost nothing, and the container, the chart, the probes and the service exposure get all of the attention.
The endpoints
Go standard library, net/http, JSON out of five routes:
| Endpoint | Purpose |
|---|---|
/ | Basic response to check the service is up |
/health | Liveness probe |
/ready | Readiness probe |
/version | Service name, version, hostname and timestamp |
/info | The application’s configured environment values |
Configuration comes from environment variables: PORT, APP_VERSION, SITE_NAME.
Defaults are set so it runs locally with nothing else in place.
Container and chart
The Dockerfile has two stages, one to compile and one to run on Alpine. The runtime image has no Go toolchain and no source in it.
The chart is a Deployment, a Service and a ConfigMap, with CPU and memory requests and limits set, on NodePort 30080 in the lab.
helm install edge-status-api ./chart -n trapp-lab --create-namespace
kubectl -n trapp-lab rollout status deploy/edge-status-api
curl http://<worker-ip>:30080/version/version returns the pod’s hostname, which is most of the reason it exists. After
a rollout I can see which pod answered me instead of guessing whether I’m still
talking to the old one.
Health probes: current behaviour and limitations
The service has separate liveness and readiness endpoints, but both currently return fixed responses. They confirm that the HTTP service can respond; they do not check downstream dependencies or more detailed application health. If dependencies are added, the readiness check will need to reflect whether the service can handle requests.
Writing the chart is also what made me stop skipping past resource requests and limits. It is very easy to deploy something with neither and never find out until the node is the thing that fails.
Next improvement: run as a non-root user
The runtime container currently runs as root. A next step is to configure a non-root user and an appropriate Kubernetes security context.