Skip to content

Commit 7520950

Browse files
authored
fix: configure kernel modules and settings per k0s (#1872)
* fix: configure kernel modules and settings per k0s * f * f * f * f
1 parent 8cde4d2 commit 7520950

File tree

8 files changed

+123
-25
lines changed

8 files changed

+123
-25
lines changed

cmd/installer/cli/install.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,11 @@ func runInstall(ctx context.Context, name string, flags InstallCmdFlags, metrics
255255
logrus.Debugf("unable to configure sysctl: %v", err)
256256
}
257257

258+
logrus.Debugf("configuring kernel modules")
259+
if err := configutils.ConfigureKernelModules(); err != nil {
260+
logrus.Debugf("unable to configure kernel modules: %v", err)
261+
}
262+
258263
logrus.Debugf("configuring network manager")
259264
if err := configureNetworkManager(ctx); err != nil {
260265
return fmt.Errorf("unable to configure network manager: %w", err)

cmd/installer/cli/install_runpreflights.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ func runInstallRunPreflights(ctx context.Context, name string, flags InstallCmdF
6262
logrus.Debugf("unable to configure sysctl: %v", err)
6363
}
6464

65+
logrus.Debugf("configuring kernel modules")
66+
if err := configutils.ConfigureKernelModules(); err != nil {
67+
logrus.Debugf("unable to configure kernel modules: %v", err)
68+
}
69+
6570
logrus.Debugf("running install preflights")
6671
if err := runInstallPreflights(ctx, flags, nil); err != nil {
6772
if errors.Is(err, preflights.ErrPreflightsHaveFail) {

cmd/installer/cli/join.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ func runJoin(ctx context.Context, name string, flags JoinCmdFlags, jcmd *kotsadm
138138
logrus.Debugf("unable to configure sysctl: %v", err)
139139
}
140140

141+
logrus.Debugf("configuring kernel modules")
142+
if err := configutils.ConfigureKernelModules(); err != nil {
143+
logrus.Debugf("unable to configure kernel modules: %v", err)
144+
}
145+
141146
logrus.Debugf("configuring network manager")
142147
if err := configureNetworkManager(ctx); err != nil {
143148
return fmt.Errorf("unable to configure network manager: %w", err)

cmd/installer/cli/join_runpreflights.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ func runJoinRunPreflights(ctx context.Context, name string, flags JoinCmdFlags,
6666
logrus.Debugf("unable to configure sysctl: %v", err)
6767
}
6868

69+
logrus.Debugf("configuring kernel modules")
70+
if err := configutils.ConfigureKernelModules(); err != nil {
71+
logrus.Debugf("unable to configure kernel modules: %v", err)
72+
}
73+
6974
cidrCfg, err := getJoinCIDRConfig(jcmd)
7075
if err != nil {
7176
return fmt.Errorf("unable to get join CIDR config: %w", err)

cmd/installer/cli/restore.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,6 @@ func runRestore(ctx context.Context, name string, flags InstallCmdFlags, s3Store
135135
}
136136
}
137137

138-
logrus.Debugf("configuring sysctl")
139-
if err := configutils.ConfigureSysctl(); err != nil {
140-
logrus.Debugf("unable to configure sysctl: %v", err)
141-
}
142-
143138
logrus.Debugf("getting restore state")
144139
state := getECRestoreState(ctx)
145140
logrus.Debugf("restore state is: %q", state)
@@ -364,6 +359,16 @@ func runRestoreStepNew(ctx context.Context, name string, flags InstallCmdFlags,
364359
}
365360
}
366361

362+
logrus.Debugf("configuring sysctl")
363+
if err := configutils.ConfigureSysctl(); err != nil {
364+
logrus.Debugf("unable to configure sysctl: %v", err)
365+
}
366+
367+
logrus.Debugf("configuring kernel modules")
368+
if err := configutils.ConfigureKernelModules(); err != nil {
369+
logrus.Debugf("unable to configure kernel modules: %v", err)
370+
}
371+
367372
logrus.Debugf("configuring network manager")
368373
if err := configureNetworkManager(ctx); err != nil {
369374
return fmt.Errorf("unable to configure network manager: %w", err)

pkg/configutils/runtime.go

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,109 @@
11
package configutils
22

33
import (
4+
"bufio"
5+
"bytes"
46
_ "embed"
57
"fmt"
68
"os"
79
"os/exec"
810
"path/filepath"
11+
"strings"
912

1013
"github.com/replicatedhq/embedded-cluster/pkg/helpers"
14+
"go.uber.org/multierr"
1115
)
1216

13-
// sysctlConfigPath is the path to the sysctl config file that is used to configure
14-
// the embedded cluster. This could have been a constant but we want to be able to
15-
// override it for testing purposes.
17+
// sysctlConfigPath is the path to the sysctl config file that is used to configure the embedded
18+
// cluster. This could have been a constant but we want to be able to override it for testing
19+
// purposes.
1620
var sysctlConfigPath = "/etc/sysctl.d/99-embedded-cluster.conf"
1721

18-
//go:embed static/99-embedded-cluster.conf
19-
var embeddedClusterConf []byte
22+
var modulesLoadConfigPath = "/etc/modules-load.d/99-embedded-cluster.conf"
2023

21-
// ConfigureSysctl writes the sysctl config file for the embedded cluster and
22-
// reloads the sysctl configuration. This function has a distinct behavior: if
23-
// the sysctl binary does not exist it returns an error but if it fails to lay
24-
// down the sysctl config on disk it simply returns nil.
24+
//go:embed static/sysctl.d/99-embedded-cluster.conf
25+
var embeddedClusterSysctlConf []byte
26+
27+
//go:embed static/modules-load.d/99-embedded-cluster.conf
28+
var embeddedClusterModulesConf []byte
29+
30+
// ConfigureSysctl writes the sysctl config file for the embedded cluster and reloads the sysctl
31+
// configuration. This function has a distinct behavior: if the sysctl binary does not exist it
32+
// returns an error but if it fails to lay down the sysctl config on disk it simply returns nil.
33+
// NOTE: do not run this after the cluster has already been installed as it may revert sysctl
34+
// settings set by k0s and its extensions.
2535
func ConfigureSysctl() error {
2636
if _, err := exec.LookPath("sysctl"); err != nil {
27-
return fmt.Errorf("unable to find sysctl binary: %w", err)
37+
return fmt.Errorf("find sysctl binary: %w", err)
2838
}
2939

30-
if err := sysctlConfig(sysctlConfigPath); err != nil {
31-
return fmt.Errorf("unable to materialize sysctl config: %w", err)
40+
if err := sysctlConfig(); err != nil {
41+
return fmt.Errorf("materialize sysctl config: %w", err)
3242
}
3343

3444
if _, err := helpers.RunCommand("sysctl", "--system"); err != nil {
35-
return fmt.Errorf("unable to configure sysctl: %w", err)
45+
return fmt.Errorf("configure sysctl: %w", err)
46+
}
47+
return nil
48+
}
49+
50+
// sysctlConfig writes the embedded sysctl config to the /etc/sysctl.d directory.
51+
func sysctlConfig() error {
52+
if err := os.MkdirAll(filepath.Dir(sysctlConfigPath), 0755); err != nil {
53+
return fmt.Errorf("create directory: %w", err)
54+
}
55+
if err := os.WriteFile(sysctlConfigPath, embeddedClusterSysctlConf, 0644); err != nil {
56+
return fmt.Errorf("write file: %w", err)
57+
}
58+
return nil
59+
}
60+
61+
// ConfigureKernelModules writes the kernel modules config file and ensures the kernel modules are
62+
// loaded that are listed in the file.
63+
func ConfigureKernelModules() error {
64+
if _, err := exec.LookPath("modprobe"); err != nil {
65+
return fmt.Errorf("find modprobe binary: %w", err)
66+
}
67+
68+
if err := kernelModulesConfig(); err != nil {
69+
return fmt.Errorf("materialize kernel modules config: %w", err)
70+
}
71+
72+
if err := ensureKernelModulesLoaded(); err != nil {
73+
return fmt.Errorf("ensure kernel modules are loaded: %w", err)
3674
}
3775
return nil
3876
}
3977

40-
// SysctlConfig writes the embedded sysctl config to the /etc/sysctl.d directory.
41-
func sysctlConfig(dstpath string) error {
42-
if err := os.MkdirAll(filepath.Dir(dstpath), 0755); err != nil {
43-
return fmt.Errorf("unable to create directory: %w", err)
78+
// kernelModulesConfig writes the embedded kernel modules config to the /etc/modules-load.d
79+
// directory.
80+
func kernelModulesConfig() error {
81+
if err := os.MkdirAll(filepath.Dir(modulesLoadConfigPath), 0755); err != nil {
82+
return fmt.Errorf("create directory: %w", err)
4483
}
45-
if err := os.WriteFile(dstpath, embeddedClusterConf, 0644); err != nil {
46-
return fmt.Errorf("unable to write file: %w", err)
84+
if err := os.WriteFile(modulesLoadConfigPath, embeddedClusterModulesConf, 0644); err != nil {
85+
return fmt.Errorf("write file: %w", err)
4786
}
4887
return nil
4988
}
89+
90+
// ensureKernelModulesLoaded ensures the kernel modules are loaded by iterating over the modules in
91+
// the config file and calling modprobe for each one.
92+
func ensureKernelModulesLoaded() (finalErr error) {
93+
scanner := bufio.NewScanner(bytes.NewReader(embeddedClusterModulesConf))
94+
for scanner.Scan() {
95+
module := strings.TrimSpace(scanner.Text())
96+
if module != "" && !strings.HasPrefix(module, "#") {
97+
if err := modprobe(module); err != nil {
98+
err = fmt.Errorf("modprobe %s: %w", module, err)
99+
finalErr = multierr.Append(finalErr, err)
100+
}
101+
}
102+
}
103+
return
104+
}
105+
106+
func modprobe(module string) error {
107+
_, err := helpers.RunCommand("modprobe", module)
108+
return err
109+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# from https://github.com/k0sproject/k0s/blob/fb9fb09cdbea20afa64fbb0218c7eca0ac0a61c7/pkg/component/worker/kernelsetup_linux.go#L63-L75
2+
overlay
3+
ip_tables
4+
#ip6_tables
5+
br_netfilter
6+
nf_conntrack

pkg/configutils/static/99-embedded-cluster.conf renamed to pkg/configutils/static/sysctl.d/99-embedded-cluster.conf

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
# this entry enables ip forwarding. this feature is necessary as embedded
22
# cluster creates virtual network interfaces and need the traffic among them to
3-
# be forwarded.
3+
# be forwarded and routed via iptables.
4+
# from https://github.com/k0sproject/k0s/blob/fb9fb09cdbea20afa64fbb0218c7eca0ac0a61c7/pkg/component/worker/kernelsetup_linux.go#L76-L81
45
net.ipv4.ip_forward = 1
6+
net.ipv4.conf.all.forwarding = 1
7+
net.ipv4.conf.default.forwarding = 1
8+
net.ipv6.conf.all.forwarding = 1
9+
net.ipv6.conf.default.forwarding = 1
10+
net.bridge.bridge-nf-call-iptables = 1
11+
net.bridge.bridge-nf-call-ip6tables = 1
512

613
# arp filter and ignore need to be disabled otherwise we can't have arp
714
# resolving across the calico network interfaces.

0 commit comments

Comments
 (0)