Unverified Commit 1e0507c6 authored by Derek Nola's avatar Derek Nola Committed by GitHub

[Release-1.21] Delay service readiness until after startuphooks have finished (#5725)

* Move startup hooks wg into a runtime pointer, check before notifying systemd * Switch default systemd notification to server * Add 1 sec delay to allow etcd to write to disk Signed-off-by: 's avatarDerek Nola <derek.nola@suse.com>
parent ecddd267
...@@ -31,6 +31,7 @@ import ( ...@@ -31,6 +31,7 @@ import (
"github.com/rancher/k3s/pkg/nodeconfig" "github.com/rancher/k3s/pkg/nodeconfig"
"github.com/rancher/k3s/pkg/rootless" "github.com/rancher/k3s/pkg/rootless"
"github.com/rancher/k3s/pkg/util" "github.com/rancher/k3s/pkg/util"
"github.com/rancher/k3s/pkg/version"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/equality"
...@@ -159,8 +160,13 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { ...@@ -159,8 +160,13 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error {
} }
} }
// By default, the server is responsible for notifying systemd
// On agent-only nodes, the agent will notify systemd
if notifySocket != "" {
logrus.Info(version.Program + " agent is up and running")
os.Setenv("NOTIFY_SOCKET", notifySocket) os.Setenv("NOTIFY_SOCKET", notifySocket)
systemd.SdNotify(true, "READY=1\n") systemd.SdNotify(true, "READY=1\n")
}
<-ctx.Done() <-ctx.Done()
return ctx.Err() return ctx.Err()
......
...@@ -419,6 +419,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont ...@@ -419,6 +419,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
logrus.Info("Starting " + version.Program + " " + app.App.Version) logrus.Info("Starting " + version.Program + " " + app.App.Version)
notifySocket := os.Getenv("NOTIFY_SOCKET") notifySocket := os.Getenv("NOTIFY_SOCKET")
os.Unsetenv("NOTIFY_SOCKET")
ctx := signals.SetupSignalHandler(context.Background()) ctx := signals.SetupSignalHandler(context.Background())
...@@ -430,16 +431,16 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont ...@@ -430,16 +431,16 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont
if !serverConfig.ControlConfig.DisableAPIServer { if !serverConfig.ControlConfig.DisableAPIServer {
<-serverConfig.ControlConfig.Runtime.APIServerReady <-serverConfig.ControlConfig.Runtime.APIServerReady
logrus.Info("Kube API server is now running") logrus.Info("Kube API server is now running")
} else { serverConfig.ControlConfig.Runtime.StartupHooksWg.Wait()
}
if !serverConfig.ControlConfig.DisableETCD {
<-serverConfig.ControlConfig.Runtime.ETCDReady <-serverConfig.ControlConfig.Runtime.ETCDReady
logrus.Info("ETCD server is now running") logrus.Info("ETCD server is now running")
} }
logrus.Info(version.Program + " is up and running") logrus.Info(version.Program + " is up and running")
if (cfg.DisableAgent || cfg.DisableAPIServer) && notifySocket != "" {
os.Setenv("NOTIFY_SOCKET", notifySocket) os.Setenv("NOTIFY_SOCKET", notifySocket)
systemd.SdNotify(true, "READY=1\n") systemd.SdNotify(true, "READY=1\n")
}
}() }()
ip := serverConfig.ControlConfig.BindAddress ip := serverConfig.ControlConfig.BindAddress
......
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"net/http" "net/http"
"sort" "sort"
"strings" "strings"
"sync"
"time" "time"
"github.com/k3s-io/kine/pkg/endpoint" "github.com/k3s-io/kine/pkg/endpoint"
...@@ -217,6 +218,7 @@ type ControlRuntime struct { ...@@ -217,6 +218,7 @@ type ControlRuntime struct {
APIServerReady <-chan struct{} APIServerReady <-chan struct{}
AgentReady <-chan struct{} AgentReady <-chan struct{}
ETCDReady <-chan struct{} ETCDReady <-chan struct{}
StartupHooksWg *sync.WaitGroup
ClusterControllerStart func(ctx context.Context) error ClusterControllerStart func(ctx context.Context) error
LeaderElectedClusterControllerStart func(ctx context.Context) error LeaderElectedClusterControllerStart func(ctx context.Context) error
......
...@@ -187,6 +187,10 @@ func encryptionConfigHandler(ctx context.Context, server *config.Control) http.H ...@@ -187,6 +187,10 @@ func encryptionConfigHandler(ctx context.Context, server *config.Control) http.H
genErrorMessage(resp, http.StatusBadRequest, err) genErrorMessage(resp, http.StatusBadRequest, err)
return return
} }
// If a user kills the k3s server immediately after this call, we run into issues where the files
// have not yet been written. This sleep ensures that things have time to sync to disk before
// the request completes.
time.Sleep(1 * time.Second)
resp.WriteHeader(http.StatusOK) resp.WriteHeader(http.StatusOK)
}) })
} }
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
...@@ -70,6 +71,8 @@ func StartServer(ctx context.Context, config *Config, cfg *cmds.Server) error { ...@@ -70,6 +71,8 @@ func StartServer(ctx context.Context, config *Config, cfg *cmds.Server) error {
go startOnAPIServerReady(ctx, config) go startOnAPIServerReady(ctx, config)
} }
config.ControlConfig.Runtime.StartupHooksWg = &sync.WaitGroup{}
config.ControlConfig.Runtime.StartupHooksWg.Add(len(config.StartupHooks))
for _, hook := range config.StartupHooks { for _, hook := range config.StartupHooks {
if err := hook(ctx, config.ControlConfig.Runtime.APIServerReady, config.ControlConfig.Runtime.KubeConfigAdmin); err != nil { if err := hook(ctx, config.ControlConfig.Runtime.APIServerReady, config.ControlConfig.Runtime.KubeConfigAdmin); err != nil {
return errors.Wrap(err, "startup hook") return errors.Wrap(err, "startup hook")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment