Skip to content

Commit

Permalink
fix: allow graceful node shutdown to be overridden
Browse files Browse the repository at this point in the history
The problem is that these values needs to be set to zero if the kubelet
feature gate is disabled, so we can't assume that we can override zero
value with the proper config, so we have to do an extra check on the
supplied configuration.

Also creates KB article on disabling this feature gate.

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
  • Loading branch information
smira committed Apr 28, 2022
1 parent 867d38f commit 6e7486f
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 54 deletions.
4 changes: 2 additions & 2 deletions internal/app/machined/pkg/controllers/k8s/kubelet_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ func NewKubeletConfiguration(clusterDNS []string, dnsDomain string, extraConfig
config.Logging.Format = "json"
}

if config.ShutdownGracePeriod.Duration == 0 {
if _, overridden := extraConfig["shutdownGracePeriod"]; !overridden && config.ShutdownGracePeriod.Duration == 0 {
config.ShutdownGracePeriod = metav1.Duration{Duration: constants.KubeletShutdownGracePeriod}
}

if config.ShutdownGracePeriodCriticalPods.Duration == 0 {
if _, overridden := extraConfig["shutdownGracePeriodCriticalPods"]; !overridden && config.ShutdownGracePeriodCriticalPods.Duration == 0 {
config.ShutdownGracePeriodCriticalPods = metav1.Duration{Duration: constants.KubeletShutdownGracePeriodCriticalPods}
}

Expand Down
134 changes: 82 additions & 52 deletions internal/app/machined/pkg/controllers/k8s/kubelet_spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,63 +322,93 @@ func TestNewKubeletConfigurationFail(t *testing.T) {
}
}

func TestNewKubeletConfigurationSuccess(t *testing.T) {
config, err := k8sctrl.NewKubeletConfiguration(
[]string{"10.0.0.5"}, "cluster.local", map[string]interface{}{
"oomScoreAdj": -300,
"enableDebuggingHandlers": true,
func TestNewKubeletConfigurationMerge(t *testing.T) {
defaultKubeletConfig := kubeletconfig.KubeletConfiguration{
TypeMeta: metav1.TypeMeta{
APIVersion: kubeletconfig.SchemeGroupVersion.String(),
Kind: "KubeletConfiguration",
},
)
require.NoError(t, err)

assert.Equal(
t, &kubeletconfig.KubeletConfiguration{
TypeMeta: metav1.TypeMeta{
APIVersion: kubeletconfig.SchemeGroupVersion.String(),
Kind: "KubeletConfiguration",
StaticPodPath: constants.ManifestsDirectory,
Port: constants.KubeletPort,
Authentication: kubeletconfig.KubeletAuthentication{
X509: kubeletconfig.KubeletX509Authentication{
ClientCAFile: constants.KubernetesCACert,
},
StaticPodPath: constants.ManifestsDirectory,
Port: constants.KubeletPort,
Authentication: kubeletconfig.KubeletAuthentication{
X509: kubeletconfig.KubeletX509Authentication{
ClientCAFile: constants.KubernetesCACert,
},
Webhook: kubeletconfig.KubeletWebhookAuthentication{
Enabled: pointer.ToBool(true),
},
Anonymous: kubeletconfig.KubeletAnonymousAuthentication{
Enabled: pointer.ToBool(false),
},
Webhook: kubeletconfig.KubeletWebhookAuthentication{
Enabled: pointer.ToBool(true),
},
Authorization: kubeletconfig.KubeletAuthorization{
Mode: kubeletconfig.KubeletAuthorizationModeWebhook,
Anonymous: kubeletconfig.KubeletAnonymousAuthentication{
Enabled: pointer.ToBool(false),
},
CgroupRoot: "/",
SystemCgroups: constants.CgroupSystem,
KubeletCgroups: constants.CgroupKubelet,
RotateCertificates: true,
ProtectKernelDefaults: true,
Address: "0.0.0.0",
OOMScoreAdj: pointer.ToInt32(-300),
ClusterDomain: "cluster.local",
ClusterDNS: []string{"10.0.0.5"},
SerializeImagePulls: pointer.ToBool(false),
FailSwapOn: pointer.ToBool(false),
SystemReserved: map[string]string{
"cpu": constants.KubeletSystemReservedCPU,
"memory": constants.KubeletSystemReservedMemory,
"pid": constants.KubeletSystemReservedPid,
"ephemeral-storage": constants.KubeletSystemReservedEphemeralStorage,
},
Authorization: kubeletconfig.KubeletAuthorization{
Mode: kubeletconfig.KubeletAuthorizationModeWebhook,
},
CgroupRoot: "/",
SystemCgroups: constants.CgroupSystem,
KubeletCgroups: constants.CgroupKubelet,
RotateCertificates: true,
ProtectKernelDefaults: true,
Address: "0.0.0.0",
OOMScoreAdj: pointer.ToInt32(constants.KubeletOOMScoreAdj),
ClusterDomain: "cluster.local",
ClusterDNS: []string{"10.0.0.5"},
SerializeImagePulls: pointer.ToBool(false),
FailSwapOn: pointer.ToBool(false),
SystemReserved: map[string]string{
"cpu": constants.KubeletSystemReservedCPU,
"memory": constants.KubeletSystemReservedMemory,
"pid": constants.KubeletSystemReservedPid,
"ephemeral-storage": constants.KubeletSystemReservedEphemeralStorage,
},
Logging: v1alpha1.LoggingConfiguration{
Format: "json",
},
ShutdownGracePeriod: metav1.Duration{Duration: constants.KubeletShutdownGracePeriod},
ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: constants.KubeletShutdownGracePeriodCriticalPods},
StreamingConnectionIdleTimeout: metav1.Duration{Duration: 5 * time.Minute},
TLSMinVersion: "VersionTLS13",
}

for _, tt := range []struct {
name string
extraConfig map[string]interface{}
expectedOverrides func(*kubeletconfig.KubeletConfiguration)
}{
{
name: "override some",
extraConfig: map[string]interface{}{
"oomScoreAdj": -300,
"enableDebuggingHandlers": true,
},
Logging: v1alpha1.LoggingConfiguration{
Format: "json",
expectedOverrides: func(kc *kubeletconfig.KubeletConfiguration) {
kc.OOMScoreAdj = pointer.ToInt32(-300)
kc.EnableDebuggingHandlers = pointer.ToBool(true)
},
ShutdownGracePeriod: metav1.Duration{Duration: constants.KubeletShutdownGracePeriod},
ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: constants.KubeletShutdownGracePeriodCriticalPods},
StreamingConnectionIdleTimeout: metav1.Duration{Duration: 5 * time.Minute},
TLSMinVersion: "VersionTLS13",
EnableDebuggingHandlers: pointer.ToBool(true),
},
config,
)
{
name: "disable graceful shutdown",
extraConfig: map[string]interface{}{
"shutdownGracePeriod": "0s",
"shutdownGracePeriodCriticalPods": "0s",
},
expectedOverrides: func(kc *kubeletconfig.KubeletConfiguration) {
kc.ShutdownGracePeriod = metav1.Duration{}
kc.ShutdownGracePeriodCriticalPods = metav1.Duration{}
},
},
} {
tt := tt

t.Run(tt.name, func(t *testing.T) {
expected := defaultKubeletConfig
tt.expectedOverrides(&expected)

config, err := k8sctrl.NewKubeletConfiguration([]string{"10.0.0.5"}, "cluster.local", tt.extraConfig)

require.NoError(t, err)

assert.Equal(t, &expected, config)
})
}
}
21 changes: 21 additions & 0 deletions website/content/v1.1/learn-more/knowledge-base.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: "Knowledge Base"
weight: 1999
description: "Recipes for common configuration tasks with Talos Linux."
---

## Disabling `GracefulNodeShutdown` on a node

Talos Linux enables [Graceful Node Shutdown](https://kubernetes.io/docs/concepts/architecture/nodes/#graceful-node-shutdown) Kubernetes feature by default.

If this feature should be disabled, modify the `kubelet` part of the machine configuration with:

```yaml
machine:
kubelet:
extraArgs:
feature-gates: GracefulNodeShutdown=false
extraConfig:
shutdownGracePeriod: 0s
shutdownGracePeriodCriticalPods: 0s
```

0 comments on commit 6e7486f

Please sign in to comment.