config_linux.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package config // import "github.com/docker/docker/daemon/config"
  2. import (
  3. "fmt"
  4. "net"
  5. "os/exec"
  6. "path/filepath"
  7. "github.com/containerd/cgroups/v3"
  8. "github.com/docker/docker/api/types/container"
  9. "github.com/docker/docker/api/types/system"
  10. "github.com/docker/docker/opts"
  11. "github.com/docker/docker/pkg/homedir"
  12. "github.com/docker/docker/pkg/rootless"
  13. units "github.com/docker/go-units"
  14. "github.com/pkg/errors"
  15. )
  16. const (
  17. // DefaultIpcMode is default for container's IpcMode, if not set otherwise
  18. DefaultIpcMode = container.IPCModePrivate
  19. // DefaultCgroupNamespaceMode is the default mode for containers cgroup namespace when using cgroups v2.
  20. DefaultCgroupNamespaceMode = container.CgroupnsModePrivate
  21. // DefaultCgroupV1NamespaceMode is the default mode for containers cgroup namespace when using cgroups v1.
  22. DefaultCgroupV1NamespaceMode = container.CgroupnsModeHost
  23. // StockRuntimeName is the reserved name/alias used to represent the
  24. // OCI runtime being shipped with the docker daemon package.
  25. StockRuntimeName = "runc"
  26. // minAPIVersion represents Minimum REST API version supported
  27. minAPIVersion = "1.12"
  28. )
  29. // BridgeConfig stores all the parameters for both the bridge driver and the default bridge network.
  30. type BridgeConfig struct {
  31. DefaultBridgeConfig
  32. EnableIPTables bool `json:"iptables,omitempty"`
  33. EnableIP6Tables bool `json:"ip6tables,omitempty"`
  34. EnableIPForward bool `json:"ip-forward,omitempty"`
  35. EnableIPMasq bool `json:"ip-masq,omitempty"`
  36. EnableUserlandProxy bool `json:"userland-proxy,omitempty"`
  37. UserlandProxyPath string `json:"userland-proxy-path,omitempty"`
  38. }
  39. // DefaultBridgeConfig stores all the parameters for the default bridge network.
  40. type DefaultBridgeConfig struct {
  41. commonBridgeConfig
  42. // Fields below here are platform specific.
  43. EnableIPv6 bool `json:"ipv6,omitempty"`
  44. FixedCIDRv6 string `json:"fixed-cidr-v6,omitempty"`
  45. MTU int `json:"mtu,omitempty"`
  46. DefaultIP net.IP `json:"ip,omitempty"`
  47. IP string `json:"bip,omitempty"`
  48. DefaultGatewayIPv4 net.IP `json:"default-gateway,omitempty"`
  49. DefaultGatewayIPv6 net.IP `json:"default-gateway-v6,omitempty"`
  50. InterContainerCommunication bool `json:"icc,omitempty"`
  51. }
  52. // Config defines the configuration of a docker daemon.
  53. // It includes json tags to deserialize configuration from a file
  54. // using the same names that the flags in the command line uses.
  55. type Config struct {
  56. CommonConfig
  57. // Fields below here are platform specific.
  58. Runtimes map[string]system.Runtime `json:"runtimes,omitempty"`
  59. DefaultInitBinary string `json:"default-init,omitempty"`
  60. CgroupParent string `json:"cgroup-parent,omitempty"`
  61. EnableSelinuxSupport bool `json:"selinux-enabled,omitempty"`
  62. RemappedRoot string `json:"userns-remap,omitempty"`
  63. Ulimits map[string]*units.Ulimit `json:"default-ulimits,omitempty"`
  64. CPURealtimePeriod int64 `json:"cpu-rt-period,omitempty"`
  65. CPURealtimeRuntime int64 `json:"cpu-rt-runtime,omitempty"`
  66. OOMScoreAdjust int `json:"oom-score-adjust,omitempty"` // Deprecated: configure the daemon's oom-score-adjust using a process manager instead.
  67. Init bool `json:"init,omitempty"`
  68. InitPath string `json:"init-path,omitempty"`
  69. SeccompProfile string `json:"seccomp-profile,omitempty"`
  70. ShmSize opts.MemBytes `json:"default-shm-size,omitempty"`
  71. NoNewPrivileges bool `json:"no-new-privileges,omitempty"`
  72. IpcMode string `json:"default-ipc-mode,omitempty"`
  73. CgroupNamespaceMode string `json:"default-cgroupns-mode,omitempty"`
  74. // ResolvConf is the path to the configuration of the host resolver
  75. ResolvConf string `json:"resolv-conf,omitempty"`
  76. Rootless bool `json:"rootless,omitempty"`
  77. }
  78. // GetExecRoot returns the user configured Exec-root
  79. func (conf *Config) GetExecRoot() string {
  80. return conf.ExecRoot
  81. }
  82. // GetInitPath returns the configured docker-init path
  83. func (conf *Config) GetInitPath() string {
  84. if conf.InitPath != "" {
  85. return conf.InitPath
  86. }
  87. if conf.DefaultInitBinary != "" {
  88. return conf.DefaultInitBinary
  89. }
  90. return DefaultInitBinary
  91. }
  92. // LookupInitPath returns an absolute path to the "docker-init" binary by searching relevant "libexec" directories (per FHS 3.0 & 2.3) followed by PATH
  93. func (conf *Config) LookupInitPath() (string, error) {
  94. binary := conf.GetInitPath()
  95. if filepath.IsAbs(binary) {
  96. return binary, nil
  97. }
  98. for _, dir := range []string{
  99. // 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."
  100. // https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch04s07.html
  101. "/usr/local/libexec/docker",
  102. "/usr/libexec/docker",
  103. // 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."
  104. // https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#USRLIBLIBRARIESFORPROGRAMMINGANDPA
  105. "/usr/local/lib/docker",
  106. "/usr/lib/docker",
  107. } {
  108. // 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)
  109. if file, err := exec.LookPath(filepath.Join(dir, binary)); err == nil {
  110. return file, nil
  111. }
  112. }
  113. // if we checked all the "libexec" directories and found no matches, fall back to PATH
  114. return exec.LookPath(binary)
  115. }
  116. // GetResolvConf returns the appropriate resolv.conf
  117. // Check setupResolvConf on how this is selected
  118. func (conf *Config) GetResolvConf() string {
  119. return conf.ResolvConf
  120. }
  121. // IsSwarmCompatible defines if swarm mode can be enabled in this config
  122. func (conf *Config) IsSwarmCompatible() error {
  123. if conf.LiveRestoreEnabled {
  124. return fmt.Errorf("--live-restore daemon configuration is incompatible with swarm mode")
  125. }
  126. return nil
  127. }
  128. func verifyDefaultIpcMode(mode string) error {
  129. const hint = `use "shareable" or "private"`
  130. dm := container.IpcMode(mode)
  131. if !dm.Valid() {
  132. return fmt.Errorf("default IPC mode setting (%v) is invalid; "+hint, dm)
  133. }
  134. if dm != "" && !dm.IsPrivate() && !dm.IsShareable() {
  135. return fmt.Errorf(`IPC mode "%v" is not supported as default value; `+hint, dm)
  136. }
  137. return nil
  138. }
  139. func verifyDefaultCgroupNsMode(mode string) error {
  140. cm := container.CgroupnsMode(mode)
  141. if !cm.Valid() {
  142. return fmt.Errorf(`default cgroup namespace mode (%v) is invalid; use "host" or "private"`, cm)
  143. }
  144. return nil
  145. }
  146. // ValidatePlatformConfig checks if any platform-specific configuration settings are invalid.
  147. func (conf *Config) ValidatePlatformConfig() error {
  148. if conf.OOMScoreAdjust != 0 {
  149. return errors.New(`DEPRECATED: The "oom-score-adjust" config parameter and the dockerd "--oom-score-adjust" options have been removed.`)
  150. }
  151. if err := verifyDefaultIpcMode(conf.IpcMode); err != nil {
  152. return err
  153. }
  154. return verifyDefaultCgroupNsMode(conf.CgroupNamespaceMode)
  155. }
  156. // IsRootless returns conf.Rootless on Linux but false on Windows
  157. func (conf *Config) IsRootless() bool {
  158. return conf.Rootless
  159. }
  160. func setPlatformDefaults(cfg *Config) error {
  161. cfg.Ulimits = make(map[string]*units.Ulimit)
  162. cfg.ShmSize = opts.MemBytes(DefaultShmSize)
  163. cfg.SeccompProfile = SeccompProfileDefault
  164. cfg.IpcMode = string(DefaultIpcMode)
  165. cfg.Runtimes = make(map[string]system.Runtime)
  166. if cgroups.Mode() != cgroups.Unified {
  167. cfg.CgroupNamespaceMode = string(DefaultCgroupV1NamespaceMode)
  168. } else {
  169. cfg.CgroupNamespaceMode = string(DefaultCgroupNamespaceMode)
  170. }
  171. if rootless.RunningWithRootlessKit() {
  172. cfg.Rootless = true
  173. var err error
  174. // use rootlesskit-docker-proxy for exposing the ports in RootlessKit netns to the initial namespace.
  175. cfg.BridgeConfig.UserlandProxyPath, err = exec.LookPath(rootless.RootlessKitDockerProxyBinary)
  176. if err != nil {
  177. return errors.Wrapf(err, "running with RootlessKit, but %s not installed", rootless.RootlessKitDockerProxyBinary)
  178. }
  179. dataHome, err := homedir.GetDataHome()
  180. if err != nil {
  181. return err
  182. }
  183. runtimeDir, err := homedir.GetRuntimeDir()
  184. if err != nil {
  185. return err
  186. }
  187. cfg.Root = filepath.Join(dataHome, "docker")
  188. cfg.ExecRoot = filepath.Join(runtimeDir, "docker")
  189. cfg.Pidfile = filepath.Join(runtimeDir, "docker.pid")
  190. } else {
  191. cfg.Root = "/var/lib/docker"
  192. cfg.ExecRoot = "/var/run/docker"
  193. cfg.Pidfile = "/var/run/docker.pid"
  194. }
  195. return nil
  196. }