github.com/moby/docker@v26.1.3+incompatible/daemon/config/config_linux.go (about)

     1  package config // import "github.com/docker/docker/daemon/config"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"os/exec"
     8  	"path/filepath"
     9  
    10  	"github.com/containerd/cgroups/v3"
    11  	"github.com/containerd/log"
    12  	"github.com/docker/docker/api/types/container"
    13  	"github.com/docker/docker/api/types/system"
    14  	"github.com/docker/docker/libnetwork/drivers/bridge"
    15  	"github.com/docker/docker/opts"
    16  	"github.com/docker/docker/pkg/homedir"
    17  	"github.com/docker/docker/pkg/rootless"
    18  	units "github.com/docker/go-units"
    19  	"github.com/pkg/errors"
    20  )
    21  
    22  const (
    23  	// DefaultIpcMode is default for container's IpcMode, if not set otherwise
    24  	DefaultIpcMode = container.IPCModePrivate
    25  
    26  	// DefaultCgroupNamespaceMode is the default mode for containers cgroup namespace when using cgroups v2.
    27  	DefaultCgroupNamespaceMode = container.CgroupnsModePrivate
    28  
    29  	// DefaultCgroupV1NamespaceMode is the default mode for containers cgroup namespace when using cgroups v1.
    30  	DefaultCgroupV1NamespaceMode = container.CgroupnsModeHost
    31  
    32  	// StockRuntimeName is the reserved name/alias used to represent the
    33  	// OCI runtime being shipped with the docker daemon package.
    34  	StockRuntimeName = "runc"
    35  
    36  	// userlandProxyBinary is the name of the userland-proxy binary.
    37  	// In rootless-mode, [rootless.RootlessKitDockerProxyBinary] is used instead.
    38  	userlandProxyBinary = "docker-proxy"
    39  )
    40  
    41  // BridgeConfig stores all the parameters for both the bridge driver and the default bridge network.
    42  type BridgeConfig struct {
    43  	DefaultBridgeConfig
    44  
    45  	EnableIPTables      bool   `json:"iptables,omitempty"`
    46  	EnableIP6Tables     bool   `json:"ip6tables,omitempty"`
    47  	EnableIPForward     bool   `json:"ip-forward,omitempty"`
    48  	EnableIPMasq        bool   `json:"ip-masq,omitempty"`
    49  	EnableUserlandProxy bool   `json:"userland-proxy,omitempty"`
    50  	UserlandProxyPath   string `json:"userland-proxy-path,omitempty"`
    51  }
    52  
    53  // DefaultBridgeConfig stores all the parameters for the default bridge network.
    54  type DefaultBridgeConfig struct {
    55  	commonBridgeConfig
    56  
    57  	// Fields below here are platform specific.
    58  	EnableIPv6                  bool   `json:"ipv6,omitempty"`
    59  	FixedCIDRv6                 string `json:"fixed-cidr-v6,omitempty"`
    60  	MTU                         int    `json:"mtu,omitempty"`
    61  	DefaultIP                   net.IP `json:"ip,omitempty"`
    62  	IP                          string `json:"bip,omitempty"`
    63  	DefaultGatewayIPv4          net.IP `json:"default-gateway,omitempty"`
    64  	DefaultGatewayIPv6          net.IP `json:"default-gateway-v6,omitempty"`
    65  	InterContainerCommunication bool   `json:"icc,omitempty"`
    66  }
    67  
    68  // Config defines the configuration of a docker daemon.
    69  // It includes json tags to deserialize configuration from a file
    70  // using the same names that the flags in the command line uses.
    71  type Config struct {
    72  	CommonConfig
    73  
    74  	// Fields below here are platform specific.
    75  	Runtimes             map[string]system.Runtime `json:"runtimes,omitempty"`
    76  	DefaultInitBinary    string                    `json:"default-init,omitempty"`
    77  	CgroupParent         string                    `json:"cgroup-parent,omitempty"`
    78  	EnableSelinuxSupport bool                      `json:"selinux-enabled,omitempty"`
    79  	RemappedRoot         string                    `json:"userns-remap,omitempty"`
    80  	Ulimits              map[string]*units.Ulimit  `json:"default-ulimits,omitempty"`
    81  	CPURealtimePeriod    int64                     `json:"cpu-rt-period,omitempty"`
    82  	CPURealtimeRuntime   int64                     `json:"cpu-rt-runtime,omitempty"`
    83  	Init                 bool                      `json:"init,omitempty"`
    84  	InitPath             string                    `json:"init-path,omitempty"`
    85  	SeccompProfile       string                    `json:"seccomp-profile,omitempty"`
    86  	ShmSize              opts.MemBytes             `json:"default-shm-size,omitempty"`
    87  	NoNewPrivileges      bool                      `json:"no-new-privileges,omitempty"`
    88  	IpcMode              string                    `json:"default-ipc-mode,omitempty"`
    89  	CgroupNamespaceMode  string                    `json:"default-cgroupns-mode,omitempty"`
    90  	// ResolvConf is the path to the configuration of the host resolver
    91  	ResolvConf string `json:"resolv-conf,omitempty"`
    92  	Rootless   bool   `json:"rootless,omitempty"`
    93  }
    94  
    95  // GetExecRoot returns the user configured Exec-root
    96  func (conf *Config) GetExecRoot() string {
    97  	return conf.ExecRoot
    98  }
    99  
   100  // GetInitPath returns the configured docker-init path
   101  func (conf *Config) GetInitPath() string {
   102  	if conf.InitPath != "" {
   103  		return conf.InitPath
   104  	}
   105  	if conf.DefaultInitBinary != "" {
   106  		return conf.DefaultInitBinary
   107  	}
   108  	return DefaultInitBinary
   109  }
   110  
   111  // LookupInitPath returns an absolute path to the "docker-init" binary by searching relevant "libexec" directories (per FHS 3.0 & 2.3) followed by PATH
   112  func (conf *Config) LookupInitPath() (string, error) {
   113  	binary := conf.GetInitPath()
   114  	if filepath.IsAbs(binary) {
   115  		return binary, nil
   116  	}
   117  
   118  	for _, dir := range []string{
   119  		// FHS 3.0: "/usr/libexec includes internal binaries that are not intended to be executed directly by users or shell scripts. Applications may use a single subdirectory under /usr/libexec."
   120  		// https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html
   121  		"/usr/local/libexec/docker",
   122  		"/usr/libexec/docker",
   123  
   124  		// FHS 2.3: "/usr/lib includes object files, libraries, and internal binaries that are not intended to be executed directly by users or shell scripts."
   125  		// https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA
   126  		"/usr/local/lib/docker",
   127  		"/usr/lib/docker",
   128  	} {
   129  		// exec.LookPath has a fast-path short-circuit for paths that contain "/" (skipping the PATH lookup) that then verifies whether the given path is likely to be an actual executable binary (so we invoke that instead of reimplementing the same checks)
   130  		if file, err := exec.LookPath(filepath.Join(dir, binary)); err == nil {
   131  			return file, nil
   132  		}
   133  	}
   134  
   135  	// if we checked all the "libexec" directories and found no matches, fall back to PATH
   136  	return exec.LookPath(binary)
   137  }
   138  
   139  // GetResolvConf returns the appropriate resolv.conf
   140  // Check setupResolvConf on how this is selected
   141  func (conf *Config) GetResolvConf() string {
   142  	return conf.ResolvConf
   143  }
   144  
   145  // IsSwarmCompatible defines if swarm mode can be enabled in this config
   146  func (conf *Config) IsSwarmCompatible() error {
   147  	if conf.LiveRestoreEnabled {
   148  		return fmt.Errorf("--live-restore daemon configuration is incompatible with swarm mode")
   149  	}
   150  	return nil
   151  }
   152  
   153  func verifyDefaultIpcMode(mode string) error {
   154  	const hint = `use "shareable" or "private"`
   155  
   156  	dm := container.IpcMode(mode)
   157  	if !dm.Valid() {
   158  		return fmt.Errorf("default IPC mode setting (%v) is invalid; "+hint, dm)
   159  	}
   160  	if dm != "" && !dm.IsPrivate() && !dm.IsShareable() {
   161  		return fmt.Errorf(`IPC mode "%v" is not supported as default value; `+hint, dm)
   162  	}
   163  	return nil
   164  }
   165  
   166  func verifyDefaultCgroupNsMode(mode string) error {
   167  	cm := container.CgroupnsMode(mode)
   168  	if !cm.Valid() {
   169  		return fmt.Errorf(`default cgroup namespace mode (%v) is invalid; use "host" or "private"`, cm)
   170  	}
   171  
   172  	return nil
   173  }
   174  
   175  // ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
   176  func (conf *Config) ValidatePlatformConfig() error {
   177  	if conf.EnableUserlandProxy {
   178  		if conf.UserlandProxyPath == "" {
   179  			return errors.New("invalid userland-proxy-path: userland-proxy is enabled, but userland-proxy-path is not set")
   180  		}
   181  		if !filepath.IsAbs(conf.UserlandProxyPath) {
   182  			return errors.New("invalid userland-proxy-path: must be an absolute path: " + conf.UserlandProxyPath)
   183  		}
   184  		// Using exec.LookPath here, because it also produces an error if the
   185  		// given path is not a valid executable or a directory.
   186  		if _, err := exec.LookPath(conf.UserlandProxyPath); err != nil {
   187  			return errors.Wrap(err, "invalid userland-proxy-path")
   188  		}
   189  	}
   190  
   191  	if err := verifyDefaultIpcMode(conf.IpcMode); err != nil {
   192  		return err
   193  	}
   194  
   195  	if err := bridge.ValidateFixedCIDRV6(conf.FixedCIDRv6); err != nil {
   196  		return errors.Wrap(err, "invalid fixed-cidr-v6")
   197  	}
   198  
   199  	if _, ok := conf.Features["windows-dns-proxy"]; ok {
   200  		return errors.New("feature option 'windows-dns-proxy' is only available on Windows")
   201  	}
   202  
   203  	return verifyDefaultCgroupNsMode(conf.CgroupNamespaceMode)
   204  }
   205  
   206  // IsRootless returns conf.Rootless on Linux but false on Windows
   207  func (conf *Config) IsRootless() bool {
   208  	return conf.Rootless
   209  }
   210  
   211  func setPlatformDefaults(cfg *Config) error {
   212  	cfg.Ulimits = make(map[string]*units.Ulimit)
   213  	cfg.ShmSize = opts.MemBytes(DefaultShmSize)
   214  	cfg.SeccompProfile = SeccompProfileDefault
   215  	cfg.IpcMode = string(DefaultIpcMode)
   216  	cfg.Runtimes = make(map[string]system.Runtime)
   217  
   218  	if cgroups.Mode() != cgroups.Unified {
   219  		cfg.CgroupNamespaceMode = string(DefaultCgroupV1NamespaceMode)
   220  	} else {
   221  		cfg.CgroupNamespaceMode = string(DefaultCgroupNamespaceMode)
   222  	}
   223  
   224  	if rootless.RunningWithRootlessKit() {
   225  		cfg.Rootless = true
   226  
   227  		var err error
   228  		// use rootlesskit-docker-proxy for exposing the ports in RootlessKit netns to the initial namespace.
   229  		cfg.BridgeConfig.UserlandProxyPath, err = exec.LookPath(rootless.RootlessKitDockerProxyBinary)
   230  		if err != nil {
   231  			return errors.Wrapf(err, "running with RootlessKit, but %s not installed", rootless.RootlessKitDockerProxyBinary)
   232  		}
   233  
   234  		dataHome, err := homedir.GetDataHome()
   235  		if err != nil {
   236  			return err
   237  		}
   238  		runtimeDir, err := homedir.GetRuntimeDir()
   239  		if err != nil {
   240  			return err
   241  		}
   242  
   243  		cfg.Root = filepath.Join(dataHome, "docker")
   244  		cfg.ExecRoot = filepath.Join(runtimeDir, "docker")
   245  		cfg.Pidfile = filepath.Join(runtimeDir, "docker.pid")
   246  	} else {
   247  		var err error
   248  		cfg.BridgeConfig.UserlandProxyPath, err = exec.LookPath(userlandProxyBinary)
   249  		if err != nil {
   250  			// Log, but don't error here. This allows running a daemon with
   251  			// userland-proxy disabled (which does not require the binary
   252  			// to be present).
   253  			//
   254  			// An error is still produced by [Config.ValidatePlatformConfig] if
   255  			// userland-proxy is enabled in the configuration.
   256  			//
   257  			// We log this at "debug" level, as this code is also executed
   258  			// when running "--version", and we don't want to print logs in
   259  			// that case..
   260  			log.G(context.TODO()).WithError(err).Debug("failed to lookup default userland-proxy binary")
   261  		}
   262  		cfg.Root = "/var/lib/docker"
   263  		cfg.ExecRoot = "/var/run/docker"
   264  		cfg.Pidfile = "/var/run/docker.pid"
   265  	}
   266  
   267  	return nil
   268  }