k8s is a platform, with features that can be used to make things run more smoothly
SIGINT
and SIGKILL
are the 2 main ones to care about,
pod termination:
preStop
hook is calledSIGINT
is calledterminationGracePeriodSeconds
SIGKILL
is called 1func main() {
2 // register handlers
3
4 // spin off server
5 svr := &http.Server{}
6 go svr.ListenAndServe()
7
8 // block on waiting for signal
9 sigs := make(chan os.Signal)
10 signal.Notify(sigs, syscall.SIGINT, syscall.SIGKILL)
11 <-sigs
12
13 // handle graceful shutdown
14 svr.Shutdown(context.Background())
15}
liveness: you can only die once (unlike cats),
pod is restarted if it fails livenessProbe
readiness: transient service unavailability should be signalled here, failure will mean Service won't route to the pod, sometimes may be easier to just fail a liveliness and restart
deployment.yaml
:
1kind: Deployment
2...
3spec:
4 ...
5 template:
6 ...
7 spec:
8 ...
9 containers:
10 - name: liveness
11 ...
12 livenessProbe:
13 httpGet:
14 path: /health # /healthz
15 port: http
16 initialDelaySeconds: 3
17 periodSeconds: 3
18 readinessProbe:
19 httpGet:
20 path: /ready # /readyz
21 port: http
22 initialDelaySeconds: 3
23 periodSeconds: 3
k8s reads structured logs, fluentd is common
there is a tradeoff between structure logging for machines and text logs for humans
with logrus
1import (
2 log "github.com/sirupsen/logrus"
3)
4
5func init() {
6 switch os.Getenv("LOG_LEVEL") {
7 case "DEBUG":
8 log.SetLevel(log.DebugLevel)
9 case "INFO":
10 log.SetLevel(log.InfoLevel)
11 case "ERROR":
12 fallthrough
13 default:
14 log.SetLevel(log.ErrorLevel)
15 }
16
17 switch os.Getenv("LOG_FORMAT") {
18 case "JSON":
19 log.SetFormatter(&log.JSONFormatter{})
20 default:
21 log.SetFormatter(&log.TextFormatter{})
22 }
23}
24
25func main() {
26 log.Debugf("...")
27 log.Printf("...") // equiv to log.Infof
28 log.Errorf("...")
29}
metrics endpoint works with prometheus
prometheus has a go client library
1import (
2 "github.com/prometheus/client_golang/prometheus/promhttp"
3)
4func main() {
5 // default metrics
6 http.Handle("/metrics", promhttp.Handler())
7 http.ListenAndServe(":2112", nil)
8}
see opentracing, also jaeger
basically tracer := opentracing.Tracer
and span := tracer.StartSpan()
and span.Finish()