As asked
Write a Go HTTP server that exposes /healthz for liveness and /readyz for readiness probes. The readiness probe should return 503 during startup and during shutdown. Implement graceful shutdown that gives in-flight requests 30 seconds to complete after SIGTERM before the process exits.
Sample answer outline
The solution uses a sync/atomic or channel-based ready flag that starts as false and flips to true after initialization. The /readyz handler checks the flag. On SIGTERM, the flag flips to false (so Kubernetes stops routing traffic), then http.Server.Shutdown is called with a 30-second context. Strong answers handle the race between Kubernetes removing the endpoint and the pod receiving SIGTERM by adding a pre-stop sleep.
Reference implementation (go)
package main
import (
"context"
"net/http"
"os/signal"
"sync/atomic"
"syscall"
"time"
)
var ready atomic.Bool
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
mux.HandleFunc("/readyz", func(w http.ResponseWriter, r *http.Request) {
if ready.Load() {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusServiceUnavailable)
}
})
srv := &http.Server{Addr: ":8080", Handler: mux}
// TODO: implement graceful shutdown on SIGTERM
_ = signal.NotifyContext
_ = syscall.SIGTERM
_ = time.Second
_ = context.Background
srv.ListenAndServe()
}Expect these follow-ups
- What is the difference between liveness and readiness in terms of Kubernetes behavior when each probe fails?
- How do you add a startup probe and why is it useful for slow-starting JVM applications?