@@ -10,6 +10,7 @@ import (
10
10
goruntime "runtime"
11
11
"strconv"
12
12
"strings"
13
+ "sync"
13
14
"time"
14
15
15
16
systemd "github.com/coreos/go-systemd/v22/daemon"
@@ -32,6 +33,7 @@ import (
32
33
"github.com/k3s-io/k3s/pkg/nodeconfig"
33
34
"github.com/k3s-io/k3s/pkg/profile"
34
35
"github.com/k3s-io/k3s/pkg/rootless"
36
+ "github.com/k3s-io/k3s/pkg/signals"
35
37
"github.com/k3s-io/k3s/pkg/spegel"
36
38
"github.com/k3s-io/k3s/pkg/util"
37
39
"github.com/k3s-io/k3s/pkg/version"
@@ -147,34 +149,29 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error {
147
149
}
148
150
}
149
151
150
- if nodeConfig .Docker {
151
- if err := executor .Docker (ctx , nodeConfig ); err != nil {
152
- return err
153
- }
154
- } else if nodeConfig .ContainerRuntimeEndpoint == "" {
155
- if err := containerd .SetupContainerdConfig (nodeConfig ); err != nil {
156
- return err
157
- }
158
- if err := executor .Containerd (ctx , nodeConfig ); err != nil {
159
- return err
160
- }
161
- } else {
162
- if err := executor .CRI (ctx , nodeConfig ); err != nil {
163
- return err
164
- }
165
- }
152
+ // Create a new context to use for agent components that is cancelled on a
153
+ // delay after the signal context. This allows other things (like etcd) to
154
+ // clean up, before agent components exit when their contexts are cancelled.
155
+ ctx = util .DelayCancel (ctx , util .DefaultContextDelay )
166
156
167
157
notifySocket := os .Getenv ("NOTIFY_SOCKET" )
168
158
os .Unsetenv ("NOTIFY_SOCKET" )
169
159
160
+ go func () {
161
+ if err := startCRI (ctx , nodeConfig ); err != nil {
162
+ signals .RequestShutdown (pkgerrors .WithMessage (err , "failed to start container runtime" ))
163
+ }
164
+ }()
165
+
170
166
if err := setupTunnelAndRunAgent (ctx , nodeConfig , cfg , proxy ); err != nil {
171
167
return err
172
168
}
173
169
174
170
go func () {
175
171
<- executor .APIServerReadyChan ()
176
- if err := startNetwork (ctx , nodeConfig ); err != nil {
177
- logrus .Fatalf ("Failed to start networking: %v" , err )
172
+ if err := startNetwork (ctx , & sync.WaitGroup {}, nodeConfig ); err != nil {
173
+ signals .RequestShutdown (pkgerrors .WithMessage (err , "failed to start networking" ))
174
+ return
178
175
}
179
176
180
177
// By default, the server is responsible for notifying systemd
@@ -189,9 +186,23 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error {
189
186
return nil
190
187
}
191
188
189
+ // startCRI starts the configured CRI, or waits for an external CRI to be ready.
190
+ func startCRI (ctx context.Context , nodeConfig * daemonconfig.Node ) error {
191
+ if nodeConfig .Docker {
192
+ return executor .Docker (ctx , nodeConfig )
193
+ } else if nodeConfig .ContainerRuntimeEndpoint == "" {
194
+ if err := containerd .SetupContainerdConfig (nodeConfig ); err != nil {
195
+ return err
196
+ }
197
+ return executor .Containerd (ctx , nodeConfig )
198
+ } else {
199
+ return executor .CRI (ctx , nodeConfig )
200
+ }
201
+ }
202
+
192
203
// startNetwork updates the network annotations on the node, and starts flannel
193
204
// and the kube-router netpol controller, if enabled.
194
- func startNetwork (ctx context.Context , nodeConfig * daemonconfig.Node ) error {
205
+ func startNetwork (ctx context.Context , wg * sync. WaitGroup , nodeConfig * daemonconfig.Node ) error {
195
206
// Use the kubelet kubeconfig to update annotations on the local node
196
207
kubeletClient , err := util .GetClientSet (nodeConfig .AgentConfig .KubeConfigKubelet )
197
208
if err != nil {
@@ -203,13 +214,13 @@ func startNetwork(ctx context.Context, nodeConfig *daemonconfig.Node) error {
203
214
}
204
215
205
216
if ! nodeConfig .NoFlannel {
206
- if err := flannel .Run (ctx , nodeConfig ); err != nil {
217
+ if err := flannel .Run (ctx , wg , nodeConfig ); err != nil {
207
218
return err
208
219
}
209
220
}
210
221
211
222
if ! nodeConfig .AgentConfig .DisableNPC {
212
- if err := netpol .Run (ctx , nodeConfig ); err != nil {
223
+ if err := netpol .Run (ctx , wg , nodeConfig ); err != nil {
213
224
return err
214
225
}
215
226
}
@@ -264,7 +275,7 @@ func getConntrackConfig(nodeConfig *daemonconfig.Node) (*kubeproxyconfig.KubePro
264
275
// RunStandalone bootstraps the executor, but does not run the kubelet or containerd.
265
276
// This allows other bits of code that expect the executor to be set up properly to function
266
277
// even when the agent is disabled.
267
- func RunStandalone (ctx context.Context , cfg cmds.Agent ) error {
278
+ func RunStandalone (ctx context.Context , wg * sync. WaitGroup , cfg cmds.Agent ) error {
268
279
proxy , err := createProxyAndValidateToken (ctx , & cfg )
269
280
if err != nil {
270
281
return err
@@ -308,7 +319,7 @@ func RunStandalone(ctx context.Context, cfg cmds.Agent) error {
308
319
309
320
// Run sets up cgroups, configures the LB proxy, and triggers startup
310
321
// of containerd and kubelet.
311
- func Run (ctx context.Context , cfg cmds.Agent ) error {
322
+ func Run (ctx context.Context , wg * sync. WaitGroup , cfg cmds.Agent ) error {
312
323
if err := cgroups .Validate (); err != nil {
313
324
return err
314
325
}
0 commit comments