mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #110174 from deads2k/readyz-agnhost
add readyz handling to netexec
This commit is contained in:
commit
78a4ba6af8
@ -1 +1 @@
|
|||||||
2.37
|
2.38
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||||
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
netutils "k8s.io/utils/net"
|
netutils "k8s.io/utils/net"
|
||||||
)
|
)
|
||||||
@ -89,9 +90,13 @@ var CmdNetexec = &cobra.Command{
|
|||||||
shutdown.
|
shutdown.
|
||||||
- "wait": The amount of time to wait before starting shutdown. Acceptable values are
|
- "wait": The amount of time to wait before starting shutdown. Acceptable values are
|
||||||
golang durations. If 0 the process will start shutdown immediately.
|
golang durations. If 0 the process will start shutdown immediately.
|
||||||
- "/healthz": Returns "200 OK" if the server is ready, "412 Status Precondition Failed"
|
- "/healthz": Returns "200 OK" if the server is healthy, "412 Status Precondition Failed"
|
||||||
otherwise. The server is considered not ready if the UDP server did not start yet or
|
otherwise. The server is considered not ready if the UDP server did not start yet or
|
||||||
it exited.
|
it exited.
|
||||||
|
- "/readyz": Returns "200 OK" if the server is ready to receive traffic, "412 Status Precondition Failed", if the
|
||||||
|
server is not yet ready to receive traffic, but may be ready later, and "503" if the server is shutting down.
|
||||||
|
When a sig-term is observed, the /readyz will report 503, but healthz will report 200 to indicate that the
|
||||||
|
server is healthy (don't kill it), but the it should not be sent traffic (remove from endpoints).
|
||||||
- "/hostname": Returns the server's hostname.
|
- "/hostname": Returns the server's hostname.
|
||||||
- "/hostName": Returns the server's hostname.
|
- "/hostName": Returns the server's hostname.
|
||||||
- "/redirect": Returns a redirect response to the given "location", with the optional status "code"
|
- "/redirect": Returns a redirect response to the given "location", with the optional status "code"
|
||||||
@ -161,11 +166,18 @@ func (a *atomicBool) get() bool {
|
|||||||
func main(cmd *cobra.Command, args []string) {
|
func main(cmd *cobra.Command, args []string) {
|
||||||
exitCh := make(chan shutdownRequest)
|
exitCh := make(chan shutdownRequest)
|
||||||
|
|
||||||
if delayShutdown > 0 {
|
sigTermReceived := make(chan struct{})
|
||||||
|
go func() {
|
||||||
termCh := make(chan os.Signal, 1)
|
termCh := make(chan os.Signal, 1)
|
||||||
signal.Notify(termCh, syscall.SIGTERM)
|
signal.Notify(termCh, syscall.SIGTERM)
|
||||||
|
|
||||||
|
<-termCh
|
||||||
|
close(sigTermReceived)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if delayShutdown > 0 {
|
||||||
go func() {
|
go func() {
|
||||||
<-termCh
|
<-sigTermReceived
|
||||||
log.Printf("Sleeping %d seconds before terminating...", delayShutdown)
|
log.Printf("Sleeping %d seconds before terminating...", delayShutdown)
|
||||||
time.Sleep(time.Duration(delayShutdown) * time.Second)
|
time.Sleep(time.Duration(delayShutdown) * time.Second)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
@ -174,7 +186,7 @@ func main(cmd *cobra.Command, args []string) {
|
|||||||
|
|
||||||
if httpOverride != "" {
|
if httpOverride != "" {
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
addRoutes(mux, exitCh)
|
addRoutes(mux, sigTermReceived, exitCh)
|
||||||
|
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
overrideReq, err := http.NewRequestWithContext(r.Context(), "GET", httpOverride, nil)
|
overrideReq, err := http.NewRequestWithContext(r.Context(), "GET", httpOverride, nil)
|
||||||
@ -185,7 +197,7 @@ func main(cmd *cobra.Command, args []string) {
|
|||||||
mux.ServeHTTP(w, overrideReq)
|
mux.ServeHTTP(w, overrideReq)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
addRoutes(http.DefaultServeMux, exitCh)
|
addRoutes(http.DefaultServeMux, sigTermReceived, exitCh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDP server
|
// UDP server
|
||||||
@ -213,7 +225,7 @@ func main(cmd *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func addRoutes(mux *http.ServeMux, exitCh chan shutdownRequest) {
|
func addRoutes(mux *http.ServeMux, sigTermReceived chan struct{}, exitCh chan shutdownRequest) {
|
||||||
mux.HandleFunc("/", rootHandler)
|
mux.HandleFunc("/", rootHandler)
|
||||||
mux.HandleFunc("/clientip", clientIPHandler)
|
mux.HandleFunc("/clientip", clientIPHandler)
|
||||||
mux.HandleFunc("/header", headerHandler)
|
mux.HandleFunc("/header", headerHandler)
|
||||||
@ -221,6 +233,7 @@ func addRoutes(mux *http.ServeMux, exitCh chan shutdownRequest) {
|
|||||||
mux.HandleFunc("/echo", echoHandler)
|
mux.HandleFunc("/echo", echoHandler)
|
||||||
mux.HandleFunc("/exit", func(w http.ResponseWriter, req *http.Request) { exitHandler(w, req, exitCh) })
|
mux.HandleFunc("/exit", func(w http.ResponseWriter, req *http.Request) { exitHandler(w, req, exitCh) })
|
||||||
mux.HandleFunc("/healthz", healthzHandler)
|
mux.HandleFunc("/healthz", healthzHandler)
|
||||||
|
mux.HandleFunc("/readyz", readyzHandler(sigTermReceived))
|
||||||
mux.HandleFunc("/hostname", hostnameHandler)
|
mux.HandleFunc("/hostname", hostnameHandler)
|
||||||
mux.HandleFunc("/redirect", redirectHandler)
|
mux.HandleFunc("/redirect", redirectHandler)
|
||||||
mux.HandleFunc("/shell", shellHandler)
|
mux.HandleFunc("/shell", shellHandler)
|
||||||
@ -339,6 +352,32 @@ func healthzHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
w.WriteHeader(http.StatusPreconditionFailed)
|
w.WriteHeader(http.StatusPreconditionFailed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// readyzHandler response with a 200 if the UDP server is ready. It serves as a readyz that will return a 503
|
||||||
|
// once a sig-term has been received. This allows for graceful removal from endpoints during a pod delete flow.
|
||||||
|
func readyzHandler(sigTermReceived chan struct{}) func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
log.Printf("GET /readyz")
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-sigTermReceived:
|
||||||
|
w.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
if _, err := w.Write([]byte("shutting down")); err != nil {
|
||||||
|
utilruntime.HandleError(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
default:
|
||||||
|
if serverReady.get() {
|
||||||
|
if _, err := w.Write([]byte("ok")); err != nil {
|
||||||
|
utilruntime.HandleError(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusPreconditionFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func shutdownHandler(w http.ResponseWriter, r *http.Request) {
|
func shutdownHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Printf("GET /shutdown")
|
log.Printf("GET /shutdown")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user