Skip to content

Commit

Permalink
Add support for Kubernetes liveness/readiness probes.
Browse files Browse the repository at this point in the history
  • Loading branch information
wi1dcard committed Mar 17, 2024
1 parent 4c307fa commit 480707b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
33 changes: 31 additions & 2 deletions fingerproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/url"
"os"
"os/signal"
"strings"
"syscall"
"time"

Expand Down Expand Up @@ -139,6 +140,7 @@ func Run() {
envWithDefault("CERT_FILENAME", "tls.crt"),
"TLS certificate filename, equivalent to $CERT_FILENAME",
)

flagKeyFilename := flag.String(
"certkey-filename",
envWithDefault("CERTKEY_FILENAME", "tls.key"),
Expand All @@ -151,7 +153,18 @@ func Run() {
"Listening address of Prometheus metrics, equivalent to $METRICS_LISTEN_ADDR",
)

flagVerboseLogs := flag.Bool("verbose", false, "Enable verbose logs")
flagEnableKubernetesProbe := flag.Bool(
"enable-kubernetes-probe",
envWithDefaultBool("ENABLE_KUBERNETES_PROBE", true),
"Enable kubernetes liveness/readiness probe support, equivalent to $ENABLE_KUBERNETES_PROBE",
)

flagVerboseLogs := flag.Bool(
"verbose",
envWithDefaultBool("VERBOSE", false),
"Enable verbose logs, equivalent to $VERBOSE",
)

flagVersion := flag.Bool("version", false, "Print version and exit")
flag.Parse()

Expand All @@ -173,8 +186,13 @@ func Run() {

InitFingerprint(*flagVerboseLogs)

handler := GetReverseProxyHTTPHandler(forwardTo)
if *flagEnableKubernetesProbe {
handler.IsProbeRequest = reverseproxy.IsKubernetesProbeRequest
}

server := DefaultProxyServer(
GetReverseProxyHTTPHandler(forwardTo),
handler,
tlsConfig,
*flagVerboseLogs,
)
Expand All @@ -193,3 +211,14 @@ func envWithDefault(key string, defaultVal string) string {
}
return defaultVal
}

func envWithDefaultBool(key string, defaultVal bool) bool {
if envVal, ok := os.LookupEnv(key); ok {
if strings.ToLower(envVal) == "true" {
return true
} else if strings.ToLower(envVal) == "false" {
return false
}
}
return defaultVal
}
22 changes: 21 additions & 1 deletion pkg/reverseproxy/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"net/http/httputil"
"net/url"
"strings"
)

type HTTPHandler struct {
Expand All @@ -19,8 +20,18 @@ type HTTPHandler struct {

// optional, but in fact required, injecting fingerprint headers to outbound requests
HeaderInjectors []HeaderInjector

// optional, if IsProbeRequest returns true, handler will respond with
// a HTTP 200 OK instead of forwarding requests, useful for kubernetes
// liveness/readiness probes. defaults to nil, which disables this behavior
IsProbeRequest func(*http.Request) bool
}

const (
ProbeStatusCode = http.StatusOK
ProbeResponse = "OK"
)

func NewHTTPHandler(to *url.URL, reverseProxy *httputil.ReverseProxy, headerInjectors []HeaderInjector) *HTTPHandler {
f := &HTTPHandler{
To: to,
Expand Down Expand Up @@ -55,10 +66,19 @@ func (f *HTTPHandler) rewriteFunc(r *httputil.ProxyRequest) {
}

func (f *HTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
// TODO: add liveness probe
if f.IsProbeRequest != nil && f.IsProbeRequest(req) {
w.WriteHeader(ProbeStatusCode)
w.Write([]byte(ProbeResponse))
return
}
f.ReverseProxy.ServeHTTP(w, req)
}

func IsKubernetesProbeRequest(r *http.Request) bool {
// https://github.com/kubernetes/kubernetes/blob/656cb1028ea5af837e69b5c9c614b008d747ab63/pkg/probe/http/request.go#L91
return strings.HasPrefix(r.UserAgent(), "kube-probe/")
}

func (f *HTTPHandler) logf(format string, args ...any) {
if f.ReverseProxy.ErrorLog != nil {
f.ReverseProxy.ErrorLog.Printf(format, args...)
Expand Down

0 comments on commit 480707b

Please sign in to comment.