mirror of
https://github.com/clearlinux/docker.git
synced 2026-08-19 12:16:30 +00:00
Compare commits
8 Commits
v1.7.1-rc1
...
v1.7.1
| Author | SHA1 | Date | |
|---|---|---|---|
| 786b29d4db | |||
| 05cc946f62 | |||
| 0e9ef654d2 | |||
| 635ef94a6d | |||
| 937d37fa1a | |||
| 08c55cd94b | |||
| 10965f373c | |||
| c4e6b44df8 |
@@ -1,5 +1,31 @@
|
||||
# Changelog
|
||||
|
||||
## 1.7.1 (2015-07-14)
|
||||
|
||||
#### Runtime
|
||||
|
||||
- Fix default user spawning exec process with `docker exec`
|
||||
- Make `--bridge=none` not to configure the network bridge
|
||||
- Publish networking stats properly
|
||||
- Fix implicit devicemapper selection with static binaries
|
||||
- Fix socket connections that hung intermittently
|
||||
- Fix bridge interface creation on CentOS/RHEL 6.6
|
||||
- Fix local dns lookups added to resolv.conf
|
||||
- Fix copy command mounting volumes
|
||||
- Fix read/write privileges in volumes mounted with --volumes-from
|
||||
|
||||
#### Remote API
|
||||
|
||||
- Fix unmarshalling of Command and Entrypoint
|
||||
- Set limit for minimum client version supported
|
||||
- Validate port specification
|
||||
- Return proper errors when attach/reattach fail
|
||||
|
||||
#### Distribution
|
||||
|
||||
- Fix pulling private images
|
||||
- Fix fallback between registry V2 and V1
|
||||
|
||||
## 1.7.0 (2015-06-16)
|
||||
|
||||
#### Runtime
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
FROM centos:7
|
||||
|
||||
RUN yum groupinstall -y "Development Tools"
|
||||
RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs
|
||||
RUN yum install -y btrfs-progs-devel device-mapper-devel glibc-static libselinux-devel sqlite-devel tar
|
||||
|
||||
ENV GO_VERSION 1.4.2
|
||||
|
||||
@@ -38,6 +38,10 @@ for version in "${versions[@]}"; do
|
||||
centos:*)
|
||||
# get "Development Tools" packages dependencies
|
||||
echo 'RUN yum groupinstall -y "Development Tools"' >> "$version/Dockerfile"
|
||||
|
||||
if [[ "$version" == "centos-7" ]]; then
|
||||
echo 'RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs' >> "$version/Dockerfile"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo 'RUN yum install -y @development-tools fedora-packager' >> "$version/Dockerfile"
|
||||
|
||||
+12
-2
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/docker/docker/nat"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/broadcastwriter"
|
||||
"github.com/docker/docker/pkg/fileutils"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/jsonlog"
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
@@ -599,11 +600,20 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) {
|
||||
return nil, err
|
||||
}
|
||||
for _, m := range mounts {
|
||||
dest, err := container.GetResourcePath(m.Destination)
|
||||
var dest string
|
||||
dest, err = container.GetResourcePath(m.Destination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := mount.Mount(m.Source, dest, "bind", "rbind,ro"); err != nil {
|
||||
var stat os.FileInfo
|
||||
stat, err = os.Stat(m.Source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = fileutils.CreateIfNotExists(dest, stat.IsDir()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err = mount.Mount(m.Source, dest, "bind", "rbind,ro"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ var (
|
||||
DefaultDataLoopbackSize int64 = 100 * 1024 * 1024 * 1024
|
||||
DefaultMetaDataLoopbackSize int64 = 2 * 1024 * 1024 * 1024
|
||||
DefaultBaseFsSize uint64 = 10 * 1024 * 1024 * 1024
|
||||
DefaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
|
||||
DefaultThinpBlockSize uint32 = 128 // 64K = 128 512b sectors
|
||||
DefaultUdevSyncOverride bool = false
|
||||
MaxDeviceId int = 0xffffff // 24 bit, pool limit
|
||||
DeviceIdMapSz int = (MaxDeviceId + 1) / 8
|
||||
// We retry device removal so many a times that even error messages
|
||||
@@ -89,21 +90,22 @@ type DeviceSet struct {
|
||||
deviceIdMap []byte
|
||||
|
||||
// Options
|
||||
dataLoopbackSize int64
|
||||
metaDataLoopbackSize int64
|
||||
baseFsSize uint64
|
||||
filesystem string
|
||||
mountOptions string
|
||||
mkfsArgs []string
|
||||
dataDevice string // block or loop dev
|
||||
dataLoopFile string // loopback file, if used
|
||||
metadataDevice string // block or loop dev
|
||||
metadataLoopFile string // loopback file, if used
|
||||
doBlkDiscard bool
|
||||
thinpBlockSize uint32
|
||||
thinPoolDevice string
|
||||
Transaction `json:"-"`
|
||||
deferredRemove bool // use deferred removal
|
||||
dataLoopbackSize int64
|
||||
metaDataLoopbackSize int64
|
||||
baseFsSize uint64
|
||||
filesystem string
|
||||
mountOptions string
|
||||
mkfsArgs []string
|
||||
dataDevice string // block or loop dev
|
||||
dataLoopFile string // loopback file, if used
|
||||
metadataDevice string // block or loop dev
|
||||
metadataLoopFile string // loopback file, if used
|
||||
doBlkDiscard bool
|
||||
thinpBlockSize uint32
|
||||
thinPoolDevice string
|
||||
Transaction `json:"-"`
|
||||
deferredRemove bool // use deferred removal
|
||||
overrideUdevSyncCheck bool
|
||||
}
|
||||
|
||||
type DiskUsage struct {
|
||||
@@ -1699,15 +1701,16 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
|
||||
devicemapper.SetDevDir("/dev")
|
||||
|
||||
devices := &DeviceSet{
|
||||
root: root,
|
||||
MetaData: MetaData{Devices: make(map[string]*DevInfo)},
|
||||
dataLoopbackSize: DefaultDataLoopbackSize,
|
||||
metaDataLoopbackSize: DefaultMetaDataLoopbackSize,
|
||||
baseFsSize: DefaultBaseFsSize,
|
||||
filesystem: "ext4",
|
||||
doBlkDiscard: true,
|
||||
thinpBlockSize: DefaultThinpBlockSize,
|
||||
deviceIdMap: make([]byte, DeviceIdMapSz),
|
||||
root: root,
|
||||
MetaData: MetaData{Devices: make(map[string]*DevInfo)},
|
||||
dataLoopbackSize: DefaultDataLoopbackSize,
|
||||
metaDataLoopbackSize: DefaultMetaDataLoopbackSize,
|
||||
baseFsSize: DefaultBaseFsSize,
|
||||
overrideUdevSyncCheck: DefaultUdevSyncOverride,
|
||||
filesystem: "ext4",
|
||||
doBlkDiscard: true,
|
||||
thinpBlockSize: DefaultThinpBlockSize,
|
||||
deviceIdMap: make([]byte, DeviceIdMapSz),
|
||||
}
|
||||
|
||||
foundBlkDiscard := false
|
||||
@@ -1764,6 +1767,12 @@ func NewDeviceSet(root string, doInit bool, options []string) (*DeviceSet, error
|
||||
}
|
||||
// convert to 512b sectors
|
||||
devices.thinpBlockSize = uint32(size) >> 9
|
||||
case "dm.override_udev_sync_check":
|
||||
devices.overrideUdevSyncCheck, err = strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case "dm.use_deferred_removal":
|
||||
EnableDeferredRemoval, err = strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
|
||||
@@ -13,6 +13,7 @@ func init() {
|
||||
DefaultDataLoopbackSize = 300 * 1024 * 1024
|
||||
DefaultMetaDataLoopbackSize = 200 * 1024 * 1024
|
||||
DefaultBaseFsSize = 300 * 1024 * 1024
|
||||
DefaultUdevSyncOverride = true
|
||||
if err := graphtest.InitLoopbacks(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/docker/docker/autogen/dockerversion"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
)
|
||||
|
||||
@@ -23,10 +22,9 @@ var (
|
||||
// All registred drivers
|
||||
drivers map[string]InitFunc
|
||||
|
||||
ErrNotSupported = errors.New("driver not supported")
|
||||
ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
|
||||
ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
|
||||
ErrDeviceMapperWithStaticDocker = fmt.Errorf("devicemapper storage driver cannot reliably be used with a statically linked docker binary: please either pick a different storage driver, install a dynamically linked docker binary, or force this unreliable setup anyway by specifying --storage-driver=devicemapper")
|
||||
ErrNotSupported = errors.New("driver not supported")
|
||||
ErrPrerequisites = errors.New("prerequisites for driver not satisfied (wrong filesystem?)")
|
||||
ErrIncompatibleFS = fmt.Errorf("backing file system is unsupported for this graph driver")
|
||||
)
|
||||
|
||||
type InitFunc func(root string, options []string) (Driver, error)
|
||||
@@ -112,35 +110,36 @@ func New(root string, options []string) (driver Driver, err error) {
|
||||
}
|
||||
|
||||
// Guess for prior driver
|
||||
priorDriver, err := scanPriorDrivers(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(priorDriver) != 0 {
|
||||
// Do not allow devicemapper when it's not explicit and the Docker binary was built statically.
|
||||
if staticWithDeviceMapper(priorDriver) {
|
||||
return nil, ErrDeviceMapperWithStaticDocker
|
||||
priorDrivers := scanPriorDrivers(root)
|
||||
for _, name := range priority {
|
||||
if name == "vfs" {
|
||||
// don't use vfs even if there is state present.
|
||||
continue
|
||||
}
|
||||
|
||||
driver, err = GetDriver(priorDriver, root, options)
|
||||
if err != nil {
|
||||
// unlike below, we will return error here, because there is prior
|
||||
// state, and now it is no longer supported/prereq/compatible, so
|
||||
// something changed and needs attention. Otherwise the daemon's
|
||||
// images would just "disappear".
|
||||
logrus.Errorf("[graphdriver] prior storage driver %q failed: %s", priorDriver, err)
|
||||
return nil, err
|
||||
for _, prior := range priorDrivers {
|
||||
// of the state found from prior drivers, check in order of our priority
|
||||
// which we would prefer
|
||||
if prior == name {
|
||||
driver, err = GetDriver(name, root, options)
|
||||
if err != nil {
|
||||
// unlike below, we will return error here, because there is prior
|
||||
// state, and now it is no longer supported/prereq/compatible, so
|
||||
// something changed and needs attention. Otherwise the daemon's
|
||||
// images would just "disappear".
|
||||
logrus.Errorf("[graphdriver] prior storage driver %q failed: %s", name, err)
|
||||
return nil, err
|
||||
}
|
||||
if err := checkPriorDriver(name, root); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logrus.Infof("[graphdriver] using prior storage driver %q", name)
|
||||
return driver, nil
|
||||
}
|
||||
}
|
||||
logrus.Infof("[graphdriver] using prior storage driver %q", priorDriver)
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
// Check for priority drivers first
|
||||
for _, name := range priority {
|
||||
if staticWithDeviceMapper(name) {
|
||||
continue
|
||||
}
|
||||
driver, err = GetDriver(name, root, options)
|
||||
if err != nil {
|
||||
if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
|
||||
@@ -152,10 +151,7 @@ func New(root string, options []string) (driver Driver, err error) {
|
||||
}
|
||||
|
||||
// Check all registered drivers if no priority driver is found
|
||||
for name, initFunc := range drivers {
|
||||
if staticWithDeviceMapper(name) {
|
||||
continue
|
||||
}
|
||||
for _, initFunc := range drivers {
|
||||
if driver, err = initFunc(root, options); err != nil {
|
||||
if err == ErrNotSupported || err == ErrPrerequisites || err == ErrIncompatibleFS {
|
||||
continue
|
||||
@@ -167,31 +163,31 @@ func New(root string, options []string) (driver Driver, err error) {
|
||||
return nil, fmt.Errorf("No supported storage backend found")
|
||||
}
|
||||
|
||||
// scanPriorDrivers returns a previosly used driver.
|
||||
// it returns an error when there are several drivers scanned.
|
||||
func scanPriorDrivers(root string) (string, error) {
|
||||
var priorDrivers []string
|
||||
// scanPriorDrivers returns an un-ordered scan of directories of prior storage drivers
|
||||
func scanPriorDrivers(root string) []string {
|
||||
priorDrivers := []string{}
|
||||
for driver := range drivers {
|
||||
p := filepath.Join(root, driver)
|
||||
if _, err := os.Stat(p); err == nil && driver != "vfs" {
|
||||
priorDrivers = append(priorDrivers, driver)
|
||||
}
|
||||
}
|
||||
return priorDrivers
|
||||
}
|
||||
|
||||
if len(priorDrivers) > 1 {
|
||||
return "", multipleDriversError(root, priorDrivers)
|
||||
func checkPriorDriver(name, root string) error {
|
||||
priorDrivers := []string{}
|
||||
for _, prior := range scanPriorDrivers(root) {
|
||||
if prior != name && prior != "vfs" {
|
||||
if _, err := os.Stat(filepath.Join(root, prior)); err == nil {
|
||||
priorDrivers = append(priorDrivers, prior)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(priorDrivers) == 0 {
|
||||
return "", nil
|
||||
if len(priorDrivers) > 0 {
|
||||
|
||||
return errors.New(fmt.Sprintf("%q contains other graphdrivers: %s; Please cleanup or explicitly choose storage driver (-s <DRIVER>)", root, strings.Join(priorDrivers, ",")))
|
||||
}
|
||||
return priorDrivers[0], nil
|
||||
}
|
||||
|
||||
func multipleDriversError(root string, drivers []string) error {
|
||||
return fmt.Errorf("%q contains several graphdrivers: %s; Please cleanup or explicitly choose storage driver (--storage-driver <DRIVER>)", root, strings.Join(drivers, ", "))
|
||||
}
|
||||
|
||||
func staticWithDeviceMapper(name string) bool {
|
||||
return name == "devicemapper" && dockerversion.IAMSTATIC == "true"
|
||||
return nil
|
||||
}
|
||||
|
||||
+9
-4
@@ -191,11 +191,16 @@ func (daemon *Daemon) registerMountPoints(container *Container, hostConfig *runc
|
||||
}
|
||||
|
||||
for _, m := range c.MountPoints {
|
||||
cp := m
|
||||
cp.RW = m.RW && mode != "ro"
|
||||
cp := &mountPoint{
|
||||
Name: m.Name,
|
||||
Source: m.Source,
|
||||
RW: m.RW && mode != "ro",
|
||||
Driver: m.Driver,
|
||||
Destination: m.Destination,
|
||||
}
|
||||
|
||||
if len(m.Source) == 0 {
|
||||
v, err := createVolume(m.Name, m.Driver)
|
||||
if len(cp.Source) == 0 {
|
||||
v, err := createVolume(cp.Name, cp.Driver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,489 @@
|
||||
<!--[metadata]>
|
||||
+++
|
||||
title = "daemon"
|
||||
description = "The daemon command description and usage"
|
||||
keywords = ["container, daemon, runtime"]
|
||||
[menu.main]
|
||||
parent = "smn_cli"
|
||||
+++
|
||||
<![end-metadata]-->
|
||||
|
||||
# daemon
|
||||
|
||||
Usage: docker [OPTIONS] COMMAND [arg...]
|
||||
|
||||
A self-sufficient runtime for linux containers.
|
||||
|
||||
Options:
|
||||
--api-cors-header="" Set CORS headers in the remote API
|
||||
-b, --bridge="" Attach containers to a network bridge
|
||||
--bip="" Specify network bridge IP
|
||||
-D, --debug=false Enable debug mode
|
||||
-d, --daemon=false Enable daemon mode
|
||||
--default-gateway="" Container default gateway IPv4 address
|
||||
--default-gateway-v6="" Container default gateway IPv6 address
|
||||
--dns=[] DNS server to use
|
||||
--dns-search=[] DNS search domains to use
|
||||
--default-ulimit=[] Set default ulimit settings for containers
|
||||
-e, --exec-driver="native" Exec driver to use
|
||||
--exec-opt=[] Set exec driver options
|
||||
--exec-root="/var/run/docker" Root of the Docker execdriver
|
||||
--fixed-cidr="" IPv4 subnet for fixed IPs
|
||||
--fixed-cidr-v6="" IPv6 subnet for fixed IPs
|
||||
-G, --group="docker" Group for the unix socket
|
||||
-g, --graph="/var/lib/docker" Root of the Docker runtime
|
||||
-H, --host=[] Daemon socket(s) to connect to
|
||||
-h, --help=false Print usage
|
||||
--icc=true Enable inter-container communication
|
||||
--insecure-registry=[] Enable insecure registry communication
|
||||
--ip=0.0.0.0 Default IP when binding container ports
|
||||
--ip-forward=true Enable net.ipv4.ip_forward
|
||||
--ip-masq=true Enable IP masquerading
|
||||
--iptables=true Enable addition of iptables rules
|
||||
--ipv6=false Enable IPv6 networking
|
||||
-l, --log-level="info" Set the logging level
|
||||
--label=[] Set key=value labels to the daemon
|
||||
--log-driver="json-file" Default driver for container logs
|
||||
--log-opt=[] Log driver specific options
|
||||
--mtu=0 Set the containers network MTU
|
||||
-p, --pidfile="/var/run/docker.pid" Path to use for daemon PID file
|
||||
--registry-mirror=[] Preferred Docker registry mirror
|
||||
-s, --storage-driver="" Storage driver to use
|
||||
--selinux-enabled=false Enable selinux support
|
||||
--storage-opt=[] Set storage driver options
|
||||
--tls=false Use TLS; implied by --tlsverify
|
||||
--tlscacert="~/.docker/ca.pem" Trust certs signed only by this CA
|
||||
--tlscert="~/.docker/cert.pem" Path to TLS certificate file
|
||||
--tlskey="~/.docker/key.pem" Path to TLS key file
|
||||
--tlsverify=false Use TLS and verify the remote
|
||||
--userland-proxy=true Use userland proxy for loopback traffic
|
||||
-v, --version=false Print version information and quit
|
||||
|
||||
Options with [] may be specified multiple times.
|
||||
|
||||
The Docker daemon is the persistent process that manages containers. Docker
|
||||
uses the same binary for both the daemon and client. To run the daemon you
|
||||
provide the `-d` flag.
|
||||
|
||||
To run the daemon with debug output, use `docker -d -D`.
|
||||
|
||||
## Daemon socket option
|
||||
|
||||
The Docker daemon can listen for [Docker Remote API](/reference/api/docker_remote_api/)
|
||||
requests via three different types of Socket: `unix`, `tcp`, and `fd`.
|
||||
|
||||
By default, a `unix` domain socket (or IPC socket) is created at
|
||||
`/var/run/docker.sock`, requiring either `root` permission, or `docker` group
|
||||
membership.
|
||||
|
||||
If you need to access the Docker daemon remotely, you need to enable the `tcp`
|
||||
Socket. Beware that the default setup provides un-encrypted and
|
||||
un-authenticated direct access to the Docker daemon - and should be secured
|
||||
either using the [built in HTTPS encrypted socket](/articles/https/), or by
|
||||
putting a secure web proxy in front of it. You can listen on port `2375` on all
|
||||
network interfaces with `-H tcp://0.0.0.0:2375`, or on a particular network
|
||||
interface using its IP address: `-H tcp://192.168.59.103:2375`. It is
|
||||
conventional to use port `2375` for un-encrypted, and port `2376` for encrypted
|
||||
communication with the daemon.
|
||||
|
||||
> **Note:**
|
||||
> If you're using an HTTPS encrypted socket, keep in mind that only
|
||||
> TLS1.0 and greater are supported. Protocols SSLv3 and under are not
|
||||
> supported anymore for security reasons.
|
||||
|
||||
On Systemd based systems, you can communicate with the daemon via
|
||||
[Systemd socket activation](http://0pointer.de/blog/projects/socket-activation.html),
|
||||
use `docker -d -H fd://`. Using `fd://` will work perfectly for most setups but
|
||||
you can also specify individual sockets: `docker -d -H fd://3`. If the
|
||||
specified socket activated files aren't found, then Docker will exit. You can
|
||||
find examples of using Systemd socket activation with Docker and Systemd in the
|
||||
[Docker source tree](https://github.com/docker/docker/tree/master/contrib/init/systemd/).
|
||||
|
||||
You can configure the Docker daemon to listen to multiple sockets at the same
|
||||
time using multiple `-H` options:
|
||||
|
||||
# listen using the default unix socket, and on 2 specific IP addresses on this host.
|
||||
docker -d -H unix:///var/run/docker.sock -H tcp://192.168.59.106 -H tcp://10.10.10.2
|
||||
|
||||
The Docker client will honor the `DOCKER_HOST` environment variable to set the
|
||||
`-H` flag for the client.
|
||||
|
||||
$ docker -H tcp://0.0.0.0:2375 ps
|
||||
# or
|
||||
$ export DOCKER_HOST="tcp://0.0.0.0:2375"
|
||||
$ docker ps
|
||||
# both are equal
|
||||
|
||||
Setting the `DOCKER_TLS_VERIFY` environment variable to any value other than
|
||||
the empty string is equivalent to setting the `--tlsverify` flag. The following
|
||||
are equivalent:
|
||||
|
||||
$ docker --tlsverify ps
|
||||
# or
|
||||
$ export DOCKER_TLS_VERIFY=1
|
||||
$ docker ps
|
||||
|
||||
The Docker client will honor the `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`
|
||||
environment variables (or the lowercase versions thereof). `HTTPS_PROXY` takes
|
||||
precedence over `HTTP_PROXY`.
|
||||
|
||||
### Daemon storage-driver option
|
||||
|
||||
The Docker daemon has support for several different image layer storage
|
||||
drivers: `aufs`, `devicemapper`, `btrfs`, `zfs` and `overlay`.
|
||||
|
||||
The `aufs` driver is the oldest, but is based on a Linux kernel patch-set that
|
||||
is unlikely to be merged into the main kernel. These are also known to cause
|
||||
some serious kernel crashes. However, `aufs` is also the only storage driver
|
||||
that allows containers to share executable and shared library memory, so is a
|
||||
useful choice when running thousands of containers with the same program or
|
||||
libraries.
|
||||
|
||||
The `devicemapper` driver uses thin provisioning and Copy on Write (CoW)
|
||||
snapshots. For each devicemapper graph location – typically
|
||||
`/var/lib/docker/devicemapper` – a thin pool is created based on two block
|
||||
devices, one for data and one for metadata. By default, these block devices
|
||||
are created automatically by using loopback mounts of automatically created
|
||||
sparse files. Refer to [Storage driver options](#storage-driver-options) below
|
||||
for a way how to customize this setup.
|
||||
[~jpetazzo/Resizing Docker containers with the Device Mapper plugin](http://jpetazzo.github.io/2014/01/29/docker-device-mapper-resize/)
|
||||
article explains how to tune your existing setup without the use of options.
|
||||
|
||||
The `btrfs` driver is very fast for `docker build` - but like `devicemapper`
|
||||
does not share executable memory between devices. Use
|
||||
`docker -d -s btrfs -g /mnt/btrfs_partition`.
|
||||
|
||||
The `zfs` driver is probably not fast as `btrfs` but has a longer track record
|
||||
on stability. Thanks to `Single Copy ARC` shared blocks between clones will be
|
||||
cached only once. Use `docker -d -s zfs`. To select a different zfs filesystem
|
||||
set `zfs.fsname` option as described in [Storage driver options](#storage-driver-options).
|
||||
|
||||
The `overlay` is a very fast union filesystem. It is now merged in the main
|
||||
Linux kernel as of [3.18.0](https://lkml.org/lkml/2014/10/26/137). Call
|
||||
`docker -d -s overlay` to use it.
|
||||
|
||||
> **Note:**
|
||||
> As promising as `overlay` is, the feature is still quite young and should not
|
||||
> be used in production. Most notably, using `overlay` can cause excessive
|
||||
> inode consumption (especially as the number of images grows), as well as
|
||||
> being incompatible with the use of RPMs.
|
||||
|
||||
> **Note:**
|
||||
> It is currently unsupported on `btrfs` or any Copy on Write filesystem
|
||||
> and should only be used over `ext4` partitions.
|
||||
|
||||
### Storage driver options
|
||||
|
||||
Particular storage-driver can be configured with options specified with
|
||||
`--storage-opt` flags. Options for `devicemapper` are prefixed with `dm` and
|
||||
options for `zfs` start with `zfs`.
|
||||
|
||||
* `dm.thinpooldev`
|
||||
|
||||
Specifies a custom block storage device to use for the thin pool.
|
||||
|
||||
If using a block device for device mapper storage, it is best to use `lvm`
|
||||
to create and manage the thin-pool volume. This volume is then handed to Docker
|
||||
to exclusively create snapshot volumes needed for images and containers.
|
||||
|
||||
Managing the thin-pool outside of Docker makes for the most feature-rich
|
||||
method of having Docker utilize device mapper thin provisioning as the
|
||||
backing storage for Docker's containers. The highlights of the lvm-based
|
||||
thin-pool management feature include: automatic or interactive thin-pool
|
||||
resize support, dynamically changing thin-pool features, automatic thinp
|
||||
metadata checking when lvm activates the thin-pool, etc.
|
||||
|
||||
Example use:
|
||||
|
||||
docker -d --storage-opt dm.thinpooldev=/dev/mapper/thin-pool
|
||||
|
||||
* `dm.basesize`
|
||||
|
||||
Specifies the size to use when creating the base device, which limits the
|
||||
size of images and containers. The default value is 10G. Note, thin devices
|
||||
are inherently "sparse", so a 10G device which is mostly empty doesn't use
|
||||
10 GB of space on the pool. However, the filesystem will use more space for
|
||||
the empty case the larger the device is.
|
||||
|
||||
This value affects the system-wide "base" empty filesystem
|
||||
that may already be initialized and inherited by pulled images. Typically,
|
||||
a change to this value requires additional steps to take effect:
|
||||
|
||||
$ sudo service docker stop
|
||||
$ sudo rm -rf /var/lib/docker
|
||||
$ sudo service docker start
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.basesize=20G
|
||||
|
||||
* `dm.loopdatasize`
|
||||
|
||||
>**Note**: This option configures devicemapper loopback, which should not be used in production.
|
||||
|
||||
Specifies the size to use when creating the loopback file for the
|
||||
"data" device which is used for the thin pool. The default size is
|
||||
100G. The file is sparse, so it will not initially take up this
|
||||
much space.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.loopdatasize=200G
|
||||
|
||||
* `dm.loopmetadatasize`
|
||||
|
||||
>**Note**: This option configures devicemapper loopback, which should not be used in production.
|
||||
|
||||
Specifies the size to use when creating the loopback file for the
|
||||
"metadadata" device which is used for the thin pool. The default size
|
||||
is 2G. The file is sparse, so it will not initially take up
|
||||
this much space.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.loopmetadatasize=4G
|
||||
|
||||
* `dm.fs`
|
||||
|
||||
Specifies the filesystem type to use for the base device. The supported
|
||||
options are "ext4" and "xfs". The default is "ext4"
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.fs=xfs
|
||||
|
||||
* `dm.mkfsarg`
|
||||
|
||||
Specifies extra mkfs arguments to be used when creating the base device.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt "dm.mkfsarg=-O ^has_journal"
|
||||
|
||||
* `dm.mountopt`
|
||||
|
||||
Specifies extra mount options used when mounting the thin devices.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.mountopt=nodiscard
|
||||
|
||||
* `dm.datadev`
|
||||
|
||||
(Deprecated, use `dm.thinpooldev`)
|
||||
|
||||
Specifies a custom blockdevice to use for data for the thin pool.
|
||||
|
||||
If using a block device for device mapper storage, ideally both datadev and
|
||||
metadatadev should be specified to completely avoid using the loopback
|
||||
device.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1
|
||||
|
||||
* `dm.metadatadev`
|
||||
|
||||
(Deprecated, use `dm.thinpooldev`)
|
||||
|
||||
Specifies a custom blockdevice to use for metadata for the thin pool.
|
||||
|
||||
For best performance the metadata should be on a different spindle than the
|
||||
data, or even better on an SSD.
|
||||
|
||||
If setting up a new metadata pool it is required to be valid. This can be
|
||||
achieved by zeroing the first 4k to indicate empty metadata, like this:
|
||||
|
||||
$ dd if=/dev/zero of=$metadata_dev bs=4096 count=1
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.datadev=/dev/sdb1 --storage-opt dm.metadatadev=/dev/sdc1
|
||||
|
||||
* `dm.blocksize`
|
||||
|
||||
Specifies a custom blocksize to use for the thin pool. The default
|
||||
blocksize is 64K.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.blocksize=512K
|
||||
|
||||
* `dm.blkdiscard`
|
||||
|
||||
Enables or disables the use of blkdiscard when removing devicemapper
|
||||
devices. This is enabled by default (only) if using loopback devices and is
|
||||
required to resparsify the loopback file on image/container removal.
|
||||
|
||||
Disabling this on loopback can lead to *much* faster container removal
|
||||
times, but will make the space used in `/var/lib/docker` directory not be
|
||||
returned to the system for other use when containers are removed.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d --storage-opt dm.blkdiscard=false
|
||||
|
||||
* `dm.override_udev_sync_check`
|
||||
|
||||
Overrides the `udev` synchronization checks between `devicemapper` and `udev`.
|
||||
`udev` is the device manager for the Linux kernel.
|
||||
|
||||
To view the `udev` sync support of a Docker daemon that is using the
|
||||
`devicemapper` driver, run:
|
||||
|
||||
$ docker info
|
||||
[...]
|
||||
Udev Sync Supported: true
|
||||
[...]
|
||||
|
||||
When `udev` sync support is `true`, then `devicemapper` and udev can
|
||||
coordinate the activation and deactivation of devices for containers.
|
||||
|
||||
When `udev` sync support is `false`, a race condition occurs between
|
||||
the`devicemapper` and `udev` during create and cleanup. The race condition
|
||||
results in errors and failures. (For information on these failures, see
|
||||
[docker#4036](https://github.com/docker/docker/issues/4036))
|
||||
|
||||
To allow the `docker` daemon to start, regardless of `udev` sync not being
|
||||
supported, set `dm.override_udev_sync_check` to true:
|
||||
|
||||
$ docker -d --storage-opt dm.override_udev_sync_check=true
|
||||
|
||||
When this value is `true`, the `devicemapper` continues and simply warns
|
||||
you the errors are happening.
|
||||
|
||||
> **Note:**
|
||||
> The ideal is to pursue a `docker` daemon and environment that does
|
||||
> support synchronizing with `udev`. For further discussion on this
|
||||
> topic, see [docker#4036](https://github.com/docker/docker/issues/4036).
|
||||
> Otherwise, set this flag for migrating existing Docker daemons to
|
||||
> a daemon with a supported environment.
|
||||
|
||||
|
||||
## Docker execdriver option
|
||||
|
||||
Currently supported options of `zfs`:
|
||||
|
||||
* `zfs.fsname`
|
||||
|
||||
Set zfs filesystem under which docker will create its own datasets.
|
||||
By default docker will pick up the zfs filesystem where docker graph
|
||||
(`/var/lib/docker`) is located.
|
||||
|
||||
Example use:
|
||||
|
||||
$ docker -d -s zfs --storage-opt zfs.fsname=zroot/docker
|
||||
|
||||
## Docker execdriver option
|
||||
|
||||
The Docker daemon uses a specifically built `libcontainer` execution driver as
|
||||
its interface to the Linux kernel `namespaces`, `cgroups`, and `SELinux`.
|
||||
|
||||
There is still legacy support for the original [LXC userspace tools](
|
||||
https://linuxcontainers.org/) via the `lxc` execution driver, however, this is
|
||||
not where the primary development of new functionality is taking place.
|
||||
Add `-e lxc` to the daemon flags to use the `lxc` execution driver.
|
||||
|
||||
## Options for the native execdriver
|
||||
|
||||
You can configure the `native` (libcontainer) execdriver using options specified
|
||||
with the `--exec-opt` flag. All the flag's options have the `native` prefix. A
|
||||
single `native.cgroupdriver` option is available.
|
||||
|
||||
The `native.cgroupdriver` option specifies the management of the container's
|
||||
cgroups. You can specify `cgroupfs` or `systemd`. If you specify `systemd` and
|
||||
it is not available, the system uses `cgroupfs`. By default, if no option is
|
||||
specified, the execdriver first tries `systemd` and falls back to `cgroupfs`.
|
||||
This example sets the execdriver to `cgroupfs`:
|
||||
|
||||
$ sudo docker -d --exec-opt native.cgroupdriver=cgroupfs
|
||||
|
||||
Setting this option applies to all containers the daemon launches.
|
||||
|
||||
## Daemon DNS options
|
||||
|
||||
To set the DNS server for all Docker containers, use
|
||||
`docker -d --dns 8.8.8.8`.
|
||||
|
||||
To set the DNS search domain for all Docker containers, use
|
||||
`docker -d --dns-search example.com`.
|
||||
|
||||
## Insecure registries
|
||||
|
||||
Docker considers a private registry either secure or insecure. In the rest of
|
||||
this section, *registry* is used for *private registry*, and `myregistry:5000`
|
||||
is a placeholder example for a private registry.
|
||||
|
||||
A secure registry uses TLS and a copy of its CA certificate is placed on the
|
||||
Docker host at `/etc/docker/certs.d/myregistry:5000/ca.crt`. An insecure
|
||||
registry is either not using TLS (i.e., listening on plain text HTTP), or is
|
||||
using TLS with a CA certificate not known by the Docker daemon. The latter can
|
||||
happen when the certificate was not found under
|
||||
`/etc/docker/certs.d/myregistry:5000/`, or if the certificate verification
|
||||
failed (i.e., wrong CA).
|
||||
|
||||
By default, Docker assumes all, but local (see local registries below),
|
||||
registries are secure. Communicating with an insecure registry is not possible
|
||||
if Docker assumes that registry is secure. In order to communicate with an
|
||||
insecure registry, the Docker daemon requires `--insecure-registry` in one of
|
||||
the following two forms:
|
||||
|
||||
* `--insecure-registry myregistry:5000` tells the Docker daemon that
|
||||
myregistry:5000 should be considered insecure.
|
||||
* `--insecure-registry 10.1.0.0/16` tells the Docker daemon that all registries
|
||||
whose domain resolve to an IP address is part of the subnet described by the
|
||||
CIDR syntax, should be considered insecure.
|
||||
|
||||
The flag can be used multiple times to allow multiple registries to be marked
|
||||
as insecure.
|
||||
|
||||
If an insecure registry is not marked as insecure, `docker pull`,
|
||||
`docker push`, and `docker search` will result in an error message prompting
|
||||
the user to either secure or pass the `--insecure-registry` flag to the Docker
|
||||
daemon as described above.
|
||||
|
||||
Local registries, whose IP address falls in the 127.0.0.0/8 range, are
|
||||
automatically marked as insecure as of Docker 1.3.2. It is not recommended to
|
||||
rely on this, as it may change in the future.
|
||||
|
||||
## Running a Docker daemon behind a HTTPS_PROXY
|
||||
|
||||
When running inside a LAN that uses a `HTTPS` proxy, the Docker Hub
|
||||
certificates will be replaced by the proxy's certificates. These certificates
|
||||
need to be added to your Docker host's configuration:
|
||||
|
||||
1. Install the `ca-certificates` package for your distribution
|
||||
2. Ask your network admin for the proxy's CA certificate and append them to
|
||||
`/etc/pki/tls/certs/ca-bundle.crt`
|
||||
3. Then start your Docker daemon with `HTTPS_PROXY=http://username:password@proxy:port/ docker -d`.
|
||||
The `username:` and `password@` are optional - and are only needed if your
|
||||
proxy is set up to require authentication.
|
||||
|
||||
This will only add the proxy and authentication to the Docker daemon's requests -
|
||||
your `docker build`s and running containers will need extra configuration to
|
||||
use the proxy
|
||||
|
||||
## Default Ulimits
|
||||
|
||||
`--default-ulimit` allows you to set the default `ulimit` options to use for
|
||||
all containers. It takes the same options as `--ulimit` for `docker run`. If
|
||||
these defaults are not set, `ulimit` settings will be inherited, if not set on
|
||||
`docker run`, from the Docker daemon. Any `--ulimit` options passed to
|
||||
`docker run` will overwrite these defaults.
|
||||
|
||||
## Miscellaneous options
|
||||
|
||||
IP masquerading uses address translation to allow containers without a public
|
||||
IP to talk to other machines on the Internet. This may interfere with some
|
||||
network topologies and can be disabled with --ip-masq=false.
|
||||
|
||||
Docker supports softlinks for the Docker data directory (`/var/lib/docker`) and
|
||||
for `/var/lib/docker/tmp`. The `DOCKER_TMPDIR` and the data directory can be
|
||||
set like this:
|
||||
|
||||
DOCKER_TMPDIR=/mnt/disk2/tmp /usr/local/bin/docker -d -D -g /var/lib/docker -H unix:// > /var/lib/boot2docker/docker.log 2>&1
|
||||
# or
|
||||
export DOCKER_TMPDIR=/mnt/disk2/tmp
|
||||
/usr/local/bin/docker -d -D -g /var/lib/docker -H unix:// > /var/lib/boot2docker/docker.log 2>&1
|
||||
|
||||
|
||||
@@ -36,10 +36,7 @@ Requires(preun): initscripts
|
||||
# required packages on install
|
||||
Requires: /bin/sh
|
||||
Requires: iptables
|
||||
Requires: libc.so.6
|
||||
Requires: libcgroup
|
||||
Requires: libpthread.so.0
|
||||
Requires: libsqlite3.so.0
|
||||
Requires: tar
|
||||
Requires: xz
|
||||
%if 0%{?fedora} >= 21
|
||||
|
||||
@@ -632,3 +632,20 @@ func (s *DockerSuite) TestCopyAndRestart(c *check.C) {
|
||||
c.Fatalf("expected %q but got %q", expectedMsg, msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DockerSuite) TestCopyCreatedContainer(c *check.C) {
|
||||
out, err := exec.Command(dockerBinary, "create", "--name", "test_cp", "-v", "/test", "busybox").CombinedOutput()
|
||||
if err != nil {
|
||||
c.Fatalf(string(out), err)
|
||||
}
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "test")
|
||||
if err != nil {
|
||||
c.Fatalf("unable to make temporary directory: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
out, err = exec.Command(dockerBinary, "cp", "test_cp:/bin/sh", tmpDir).CombinedOutput()
|
||||
if err != nil {
|
||||
c.Fatalf(string(out), err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3211,3 +3211,21 @@ func (s *DockerSuite) TestDevicePermissions(c *check.C) {
|
||||
c.Fatalf("output should begin with %q, got %q", permissions, out)
|
||||
}
|
||||
}
|
||||
|
||||
// https://github.com/docker/docker/pull/14498
|
||||
func (s *DockerSuite) TestVolumeFromMixedRWOptions(c *check.C) {
|
||||
dockerCmd(c, "run", "--name", "parent", "-v", "/test", "busybox", "true")
|
||||
dockerCmd(c, "run", "--volumes-from", "parent:ro", "--name", "test-volumes-1", "busybox", "true")
|
||||
dockerCmd(c, "run", "--volumes-from", "parent:rw", "--name", "test-volumes-2", "busybox", "true")
|
||||
|
||||
testRO, err := inspectFieldMap("test-volumes-1", ".VolumesRW", "/test")
|
||||
c.Assert(err, check.IsNil)
|
||||
if testRO != "false" {
|
||||
c.Fatalf("Expected RO volume was RW")
|
||||
}
|
||||
testRW, err := inspectFieldMap("test-volumes-2", ".VolumesRW", "/test")
|
||||
c.Assert(err, check.IsNil)
|
||||
if testRW != "true" {
|
||||
c.Fatalf("Expected RW volume was RO")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -369,6 +369,45 @@ for data and metadata:
|
||||
--storage-opt dm.metadatadev=/dev/vdc \
|
||||
--storage-opt dm.basesize=20G
|
||||
|
||||
#### dm.override_udev_sync_check
|
||||
|
||||
By default, the devicemapper backend attempts to synchronize with the
|
||||
`udev` device manager for the Linux kernel. This option allows
|
||||
disabling that synchronization, to continue even though the
|
||||
configuration may be buggy.
|
||||
|
||||
To view the `udev` sync support of a Docker daemon that is using the
|
||||
`devicemapper` driver, run:
|
||||
|
||||
$ docker info
|
||||
[...]
|
||||
Udev Sync Supported: true
|
||||
[...]
|
||||
|
||||
When `udev` sync support is `true`, then `devicemapper` and `udev` can
|
||||
coordinate the activation and deactivation of devices for containers.
|
||||
|
||||
When `udev` sync support is `false`, a race condition occurs between
|
||||
the`devicemapper` and `udev` during create and cleanup. The race
|
||||
condition results in errors and failures. (For information on these
|
||||
failures, see
|
||||
[docker#4036](https://github.com/docker/docker/issues/4036))
|
||||
|
||||
To allow the `docker` daemon to start, regardless of whether `udev` sync is
|
||||
`false`, set `dm.override_udev_sync_check` to true:
|
||||
|
||||
$ docker -d --storage-opt dm.override_udev_sync_check=true
|
||||
|
||||
When this value is `true`, the driver continues and simply warns you
|
||||
the errors are happening.
|
||||
|
||||
**Note**: The ideal is to pursue a `docker` daemon and environment
|
||||
that does support synchronizing with `udev`. For further discussion on
|
||||
this topic, see
|
||||
[docker#4036](https://github.com/docker/docker/issues/4036).
|
||||
Otherwise, set this flag for migrating existing Docker daemons to a
|
||||
daemon with a supported environment.
|
||||
|
||||
# EXEC DRIVER OPTIONS
|
||||
|
||||
Use the **--exec-opt** flags to specify options to the exec-driver. The only
|
||||
|
||||
@@ -168,3 +168,23 @@ func ReadSymlinkedDirectory(path string) (string, error) {
|
||||
}
|
||||
return realPath, nil
|
||||
}
|
||||
|
||||
// CreateIfNotExists creates a file or a directory only if it does not already exist.
|
||||
func CreateIfNotExists(path string, isDir bool) error {
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
if isDir {
|
||||
return os.MkdirAll(path, 0755)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.OpenFile(path, os.O_CREATE, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user