Skip to content

Commit

Permalink
Make runsc aware of host kernel settings and offer to tweak them.
Browse files Browse the repository at this point in the history
This adds a `hostsettings` package which can be used to check and
optionally automatically adjust host kernel settings.

This currently covers six kernel settings:

  - `/proc/sys/kernel/yama/ptrace_scope`: must set to 0 or 1 when using
    `ptrace`.
  - `/proc/sys/user/max_user_namespaces`: must be >= 2, but also
    suggest increasing it further if low.
  - `/proc/sys/kernel/unprivileged_userns_clone`: Must be enabled in
    rootless mode.
  - `/proc/sys/kernel/unprivileged_userns_apparmor_policy`: Same.
  - `/proc/sys/vm/max_map_count`: suggest increasing max host VMAs.
  - `/sys/kernel/mm/transparent_hugepage/shmem_enabled`: suggest turning
    on transparent hugepages.

This is flag-gated; by default `runsc` only checks that these settings
are optimal, but only warns if they are not optimal (unless marked as
mandatory). Other flag settings can be used to either bypass this process
entirely (to avoid the small startup overhead this adds), or to make it
auto-adjust any suboptiomal kernel settings, either on a best-effort or
mandatory basis.

Updates issue #5964
Updates issue #9006

PiperOrigin-RevId: 683375555
  • Loading branch information
EtiennePerot authored and gvisor-bot committed Oct 7, 2024
1 parent cbbd0b4 commit 8e60158
Show file tree
Hide file tree
Showing 7 changed files with 419 additions and 0 deletions.
83 changes: 83 additions & 0 deletions runsc/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ type Config struct {
// HostFifo controls permission to access host FIFO (or named pipes).
HostFifo HostFifo `flag:"host-fifo"`

// HostSettings controls how host settings are handled.
HostSettings HostSettingsPolicy `flag:"host-settings"`

// Network indicates what type of network to use.
Network NetworkType `flag:"network"`

Expand Down Expand Up @@ -971,6 +974,86 @@ func (o *Overlay2) SubMountOverlayMedium() OverlayMedium {
return o.medium
}

// HostSettingsPolicy dictates how host settings should be handled.
type HostSettingsPolicy int

// HostSettingsPolicy values.
const (
// HostSettingsCheck checks the host settings. If any are not optimal, it
// will fail if any of them are mandatory, but will otherwise only log
// warnings. It never attempts to modify host settings.
HostSettingsCheck HostSettingsPolicy = iota

// HostSettingsCheck checks the host settings. If any are not optimal, it
// will fail if any of them are mandatory, but will otherwise not log
// anything about non-mandatory settings.
// It never attempts to modify host settings.
HostSettingsCheckMandatory

// HostSettingsIgnore does not check nor adjust any host settings.
// This is useful in case the host settings are already known to be
// optimal, or to avoid errors if `runsc` is running within a seccomp
// or AppArmor policy that prevents it from checking host settings.
HostSettingsIgnore

// HostSettingsAdjust automatically adjusts host settings if they are not
// optimal. It will fail if any setting is mandatory but cannot be adjusted.
// For non-mandatory settings, it logs a warning if adjustment fails.
HostSettingsAdjust

// HostSettingsEnforce automatically adjusts host settings if they are not
// optimal, and fails if adjustment of any setting fails.
HostSettingsEnforce
)

// Set implements flag.Value. Set(String()) should be idempotent.
func (p *HostSettingsPolicy) Set(v string) error {
switch v {
case "check":
*p = HostSettingsCheck
case "check_mandatory":
*p = HostSettingsCheckMandatory
case "ignore":
*p = HostSettingsIgnore
case "adjust":
*p = HostSettingsAdjust
case "enforce":
*p = HostSettingsEnforce
default:
return fmt.Errorf("invalid host settings policy %q", v)
}
return nil
}

// Ptr returns a pointer to `p`.
// Useful in flag declaration line.
func (p HostSettingsPolicy) Ptr() *HostSettingsPolicy {
return &p
}

// Get implements flag.Get.
func (p *HostSettingsPolicy) Get() any {
return *p
}

// String implements flag.String.
func (p HostSettingsPolicy) String() string {
switch p {
case HostSettingsCheck:
return "check"
case HostSettingsCheckMandatory:
return "check_mandatory"
case HostSettingsAdjust:
return "adjust"
case HostSettingsIgnore:
return "ignore"
case HostSettingsEnforce:
return "enforce"
default:
panic(fmt.Sprintf("Invalid host settings policy %d", p))
}
}

// XDP holds configuration for whether and how to use XDP.
type XDP struct {
Mode XDPMode
Expand Down
1 change: 1 addition & 0 deletions runsc/config/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func RegisterFlags(flagSet *flag.FlagSet) {
flagSet.Bool("oci-seccomp", false, "Enables loading OCI seccomp filters inside the sandbox.")
flagSet.Bool("enable-core-tags", false, "enables core tagging. Requires host linux kernel >= 5.14.")
flagSet.String("pod-init-config", "", "path to configuration file with additional steps to take during pod creation.")
flagSet.Var(HostSettingsCheck.Ptr(), "host-settings", "how to handle non-optimal host kernel settings: check (default, advisory-only), ignore (do not check), adjust (best-effort auto-adjustment), or enforce (auto-adjustment must succeed).")

// Flags that control sandbox runtime behavior: MM related.
flagSet.Bool("app-huge-pages", true, "enable use of huge pages for application memory; requires /sys/kernel/mm/transparent_hugepage/shmem_enabled = advise")
Expand Down
18 changes: 18 additions & 0 deletions runsc/hostsettings/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
load("//tools:defs.bzl", "go_library")

package(
default_applicable_licenses = ["//:license"],
licenses = ["notice"],
)

go_library(
name = "hostsettings",
srcs = [
"hostsettings.go",
],
visibility = ["//:sandbox"],
deps = [
"//pkg/log",
"//runsc/config",
],
)
Loading

0 comments on commit 8e60158

Please sign in to comment.