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 }