From f4a2be5108978b34fcef96258d77b7617ec53188 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Tue, 15 Nov 2022 03:56:49 +0000 Subject: [PATCH] Make rootless settings configurable Add enivironment variables for port-driver, cidr, mtu, and disable-host-loopback settings. Since rootless is still experimental, I don't think they deserve full CLI flag status. Signed-off-by: Brad Davidson (cherry picked from commit c02dceb7adf3d341e22b2bcda7110814a9a919a5) Signed-off-by: Brad Davidson --- pkg/rootless/mounts.go | 1 + pkg/rootless/portdriver.go | 87 ++++++++++++++++++++++++++++++++++++++ pkg/rootless/rootless.go | 55 ++++++++++++++++++------ 3 files changed, 130 insertions(+), 13 deletions(-) create mode 100644 pkg/rootless/portdriver.go diff --git a/pkg/rootless/mounts.go b/pkg/rootless/mounts.go index dc048675c0..2c19f2343c 100644 --- a/pkg/rootless/mounts.go +++ b/pkg/rootless/mounts.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows package rootless diff --git a/pkg/rootless/portdriver.go b/pkg/rootless/portdriver.go new file mode 100644 index 0000000000..e79fce0320 --- /dev/null +++ b/pkg/rootless/portdriver.go @@ -0,0 +1,87 @@ +//go:build !windows +// +build !windows + +package rootless + +import ( + "io" + "path" + + "github.com/rootless-containers/rootlesskit/pkg/port" + portbuiltin "github.com/rootless-containers/rootlesskit/pkg/port/builtin" + portslirp4netns "github.com/rootless-containers/rootlesskit/pkg/port/slirp4netns" + "github.com/sirupsen/logrus" +) + +type portDriver interface { + NewParentDriver() (port.ParentDriver, error) + NewChildDriver() port.ChildDriver + LogWriter() io.Writer + SetStateDir(string) + APISocketPath() string +} + +type builtinDriver struct { + logWriter io.Writer + stateDir string +} + +func (b *builtinDriver) NewParentDriver() (port.ParentDriver, error) { + return portbuiltin.NewParentDriver(b.logWriter, b.stateDir) +} + +func (b *builtinDriver) NewChildDriver() port.ChildDriver { + return portbuiltin.NewChildDriver(b.logWriter) +} + +func (b *builtinDriver) LogWriter() io.Writer { + return b.logWriter +} + +func (b *builtinDriver) SetStateDir(stateDir string) { + b.stateDir = stateDir +} + +func (b *builtinDriver) APISocketPath() string { + return "" +} + +type slirp4netnsDriver struct { + logWriter io.Writer + stateDir string +} + +func (s *slirp4netnsDriver) NewParentDriver() (port.ParentDriver, error) { + return portslirp4netns.NewParentDriver(s.logWriter, s.APISocketPath()) +} + +func (s *slirp4netnsDriver) NewChildDriver() port.ChildDriver { + return portslirp4netns.NewChildDriver() +} + +func (s *slirp4netnsDriver) LogWriter() io.Writer { + return s.logWriter +} + +func (s *slirp4netnsDriver) SetStateDir(stateDir string) { + s.stateDir = stateDir +} + +func (s *slirp4netnsDriver) APISocketPath() string { + if s.stateDir != "" { + return path.Join(s.stateDir, ".s4nn.sock") + } + return "" +} + +func getDriver(driverName string, logWriter io.Writer) portDriver { + if driverName == "slirp4netns" { + return &slirp4netnsDriver{logWriter: logWriter} + } + + if driverName != "" && driverName != "builtin" { + logrus.Warnf("Unsupported port driver %s, using default builtin", driverName) + } + + return &builtinDriver{logWriter: logWriter} +} diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go index d64de2572d..4cc51d3bbe 100644 --- a/pkg/rootless/rootless.go +++ b/pkg/rootless/rootless.go @@ -17,7 +17,6 @@ import ( "github.com/rootless-containers/rootlesskit/pkg/copyup/tmpfssymlink" "github.com/rootless-containers/rootlesskit/pkg/network/slirp4netns" "github.com/rootless-containers/rootlesskit/pkg/parent" - portbuiltin "github.com/rootless-containers/rootlesskit/pkg/port/builtin" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" ) @@ -27,6 +26,11 @@ var ( childEnv = "_K3S_ROOTLESS_SOCK" evacuateCgroup2Env = "_K3S_ROOTLESS_EVACUATE_CGROUP2" // boolean Sock = "" + + mtuEnv = "K3S_ROOTLESS_MTU" + cidrEnv = "K3S_ROOTLESS_CIDR" + portDriverEnv = "K3S_ROOTLESS_PORT_DRIVER" + disableLoopbackEnv = "K3S_ROOTLESS_DISABLE_HOST_LOOPBACK" ) func Rootless(stateDir string) error { @@ -37,10 +41,13 @@ func Rootless(stateDir string) error { hasFD := os.Getenv(pipeFD) != "" hasChildEnv := os.Getenv(childEnv) != "" + driverName := strings.ToLower(os.Getenv(portDriverEnv)) + rootlessDir := filepath.Join(stateDir, "rootless") + driver := getDriver(driverName, &logrusDebugWriter{}) if hasFD { logrus.Debug("Running rootless child") - childOpt, err := createChildOpt() + childOpt, err := createChildOpt(driver) if err != nil { logrus.Fatal(err) } @@ -59,7 +66,7 @@ func Rootless(stateDir string) error { if err := validateSysctl(); err != nil { logrus.Fatal(err) } - parentOpt, err := createParentOpt(filepath.Join(stateDir, "rootless")) + parentOpt, err := createParentOpt(driver, rootlessDir) if err != nil { logrus.Fatal(err) } @@ -120,7 +127,7 @@ func parseCIDR(s string) (*net.IPNet, error) { return ipnet, nil } -func createParentOpt(stateDir string) (*parent.Opt, error) { +func createParentOpt(driver portDriver, stateDir string) (*parent.Opt, error) { if err := os.MkdirAll(stateDir, 0755); err != nil { return nil, errors.Wrapf(err, "failed to mkdir %s", stateDir) } @@ -130,6 +137,8 @@ func createParentOpt(stateDir string) (*parent.Opt, error) { return nil, err } + driver.SetStateDir(stateDir) + opt := &parent.Opt{ StateDir: stateDir, CreatePIDNS: true, @@ -143,33 +152,53 @@ func createParentOpt(stateDir string) (*parent.Opt, error) { return nil, err } if selfCgroup2 := selfCgroupMap[""]; selfCgroup2 == "" { - logrus.Warnf("enabling cgroup2 is highly recommended, see https://rootlesscontaine.rs/getting-started/common/cgroup2/") + logrus.Warnf("Enabling cgroup2 is highly recommended, see https://rootlesscontaine.rs/getting-started/common/cgroup2/") } else { selfCgroup2Dir := filepath.Join("/sys/fs/cgroup", selfCgroup2) if unix.Access(selfCgroup2Dir, unix.W_OK) == nil { opt.EvacuateCgroup2 = "k3s_evac" } else { - logrus.Warn("cannot set cgroup2 evacuation, make sure to run k3s as a systemd unit") + logrus.Warn("Cannot set cgroup2 evacuation, make sure to run k3s as a systemd unit") } } mtu := 0 - ipnet, err := parseCIDR("10.41.0.0/16") + if val := os.Getenv(mtuEnv); val != "" { + if v, err := strconv.ParseInt(val, 10, 0); err != nil { + logrus.Warn("Failed to parse rootless mtu; using default") + } else { + mtu = int(v) + } + } + + disableHostLoopback := true + if val := os.Getenv(disableLoopbackEnv); val != "" { + if v, err := strconv.ParseBool(val); err != nil { + logrus.Warn("Failed to parse rootless disable-host-loopback value; using default") + } else { + disableHostLoopback = v + } + } + + cidr := "10.41.0.0/16" + if val := os.Getenv(cidrEnv); val != "" { + cidr = val + } + + ipnet, err := parseCIDR(cidr) if err != nil { return nil, err } - disableHostLoopback := true binary := "slirp4netns" if _, err := exec.LookPath(binary); err != nil { return nil, err } - debugWriter := &logrusDebugWriter{} - opt.NetworkDriver, err = slirp4netns.NewParentDriver(debugWriter, binary, mtu, ipnet, "tap0", disableHostLoopback, "", false, false, false) + opt.NetworkDriver, err = slirp4netns.NewParentDriver(driver.LogWriter(), binary, mtu, ipnet, "tap0", disableHostLoopback, driver.APISocketPath(), false, false, false) if err != nil { return nil, err } - opt.PortDriver, err = portbuiltin.NewParentDriver(debugWriter, stateDir) + opt.PortDriver, err = driver.NewParentDriver() if err != nil { return nil, err } @@ -188,12 +217,12 @@ func (w *logrusDebugWriter) Write(p []byte) (int, error) { return len(p), nil } -func createChildOpt() (*child.Opt, error) { +func createChildOpt(driver portDriver) (*child.Opt, error) { opt := &child.Opt{} opt.TargetCmd = os.Args opt.PipeFDEnvKey = pipeFD opt.NetworkDriver = slirp4netns.NewChildDriver() - opt.PortDriver = portbuiltin.NewChildDriver(&logrusDebugWriter{}) + opt.PortDriver = driver.NewChildDriver() opt.CopyUpDirs = []string{"/etc", "/var/run", "/run", "/var/lib"} opt.CopyUpDriver = tmpfssymlink.NewChildDriver() opt.MountProcfs = true