预计阅读时间: 62分钟

Docker运行参考

Docker在隔离的容器中运行进程。容器是在主机上运行的进程。主机可以是本地主机,也可以是远程主机。当操作员执行docker rundocker run的容器进程是独立的,因为它具有自己的文件系统,自己的网络以及独立于主机的独立的进程树。

该页面详细介绍了如何在运行时使用docker run命令定义容器的资源。

一般形式

基本的docker run命令采用以下形式:

$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

docker run命令必须指定要从中派生容器的IMAGE 。图像开发人员可以定义与以下内容有关的图像默认值:

  • 独立运行或前台运行
  • 容器识别
  • 网络设置
  • CPU和内存的运行时限制

使用docker run [OPTIONS] ,操作员可以添加或覆盖开发人员设置的图像默认设置。此外,操作员可以覆盖Docker运行时本身设置的几乎所有默认设置。操作员具有覆盖映像和Docker运行时默认设置的能力,这就是为什么run具有比其他任何docker命令更多的选项的原因。

要了解如何解释[OPTIONS]的类型,请参阅“ 选项类型”

注意 :根据您的Docker系统配置,可能需要您在docker run命令前添加sudo 。为避免必须在docker命令中使用sudo ,系统管理员可以创建一个名为docker的Unix组并将用户添加到其中。有关此配置的更多信息,请参阅您操作系统的Docker安装文档。

运营商专有选项

只有操作员(执行docker run的人员)可以设置以下选项。

独立式vs前景式

启动Docker容器时,必须首先确定要在后台以“分离”模式还是默认的前台模式运行该容器:

-d=false: Detached mode: Run container in the background, print new container id

分离(-d)

要以分离模式启动容器,请使用-d=true或仅使用-d选项。按照设计,除非用于运行容器的根进程退出,否则以分离模式启动的容器将退出,除非您还指定了--rm选项。如果将-d--rm一起--rm ,则在容器退出守护程序退出时(以先发生者为准)将其删除。

不要将service x start命令传递给分离的容器。例如,此命令尝试启动nginx服务。

$ docker run -d -p 80:80 my_image service nginx start

这成功启动了容器内的nginx服务。但是,它失败了分离容器范例,因为根进程( service nginx start )返回,并且分离容器按设计停止。结果, nginx服务已启动,但无法使用。相反,要启动诸如nginx Web服务器之类的进程,请执行以下操作:

$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'

要使用分离的容器进行输入/输出,请使用网络连接或共享卷。这些是必需的,因为容器不再侦听docker run的命令行。

要重新附加到分离的容器,请使用docker attach命令。

前景

在前台模式(未指定-d时的默认设置)下, docker run可以在容器中启动进程并将控制台附加到进程的标准输入,输出和标准错误。它甚至可以假装为TTY(这是大多数命令行可执行文件所期望的)并传递信号。所有这些都是可配置的:

-a=[]           : Attach to `STDIN`, `STDOUT` and/or `STDERR`
-t              : Allocate a pseudo-tty
--sig-proxy=true: Proxy all received signals to the process (non-TTY mode only)
-i              : Keep STDIN open even if not attached

如果您不指定-a则Docker将同时附加到stdout和stderr 。您可以指定要连接到三个标准流( STDINSTDOUTSTDERR )中的哪个,如下所示:

$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash

对于交互式进程(例如shell),必须一起使用-i -t以便为容器进程分配tty。 -i -t通常写为-it ,您将在后面的示例中看到-it 。当客户端从管道接收其标准输入时,禁止指定-t ,如下所示:

$ echo test | docker run -i busybox cat

注意 :Linux会特别处理在容器内以PID 1运行的进程:它会忽略具有默认操作的任何信号。因此,除非经过编码,否则该过程不会在SIGINTSIGTERM上终止。

容器识别

名称(--name)

操作员可以通过三种方式识别容器:

标识符类型 示例值
UUID长标识符 “ f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778”
UUID短标识符 “ f78375b1c487”
名称 “ evil_ptolemy”

UUID标识符来自Docker守护程序。如果未使用--name选项分配容器名称,则守护程序将为您生成一个随机字符串名称。定义name是向容器添加含义的便捷方法。如果指定name ,则可以在Docker网络中引用容器时使用它。这适用于后台和前台Docker容器。

注意 :必须链接默认网桥网络上的容器以按名称进行通信。

PID当量

最后,为了帮助自动化,您可以让Docker将容器ID写入您选择的文件中。这类似于某些程序将其进程ID写到文件中的方式(您已经将它们视为PID文件):

--cidfile="": Write the container ID to the file

图片[:tag]

虽然不是严格地标识容器的一种方法,但是您可以通过在命令中添加image[:tag]来指定要运行该容器的映像的版本。例如, docker run ubuntu:14.04

图片[@digest]

使用v2或更高版本图像格式的图像具有称为摘要的内容可寻址标识符。只要用于生成图像的输入不变,摘要值就可以预测和参考。

下面的示例使用sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0摘要运行来自alpine图像的容器:

$ docker run alpine@sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 date

PID设置(--pid)

--pid=""  : Set the PID (Process) Namespace mode for the container,
             'container:<name|id>': joins another container's PID namespace
             'host': use the host's PID namespace inside the container

默认情况下,所有容器都启用了PID名称空间。

PID名称空间提供了流程分离。PID命名空间可删除系统进程的视图,并允许重用进程ID,包括pid 1。

在某些情况下,您希望容器共享主机的进程名称空间,基本上允许容器内的进程查看系统上的所有进程。例如,您可以使用调试工具(例如stracegdb来构建容器,但希望在调试容器中的进程时使用这些工具。

示例:在容器内运行htop

创建此Dockerfile:

FROM alpine:latest
RUN apk add --update htop && rm -rf /var/cache/apk/*
CMD ["htop"]

构建Dockerfile并将映像标记为myhtop

$ docker build -t myhtop .

使用以下命令在容器内运行htop

$ docker run -it --rm --pid=host myhtop

加入另一个容器的pid名称空间可用于调试该容器。

启动运行Redis服务器的容器:

$ docker run --name my-redis -d redis

通过运行另一个包含strace的容器来调试redis容器:

$ docker run -it --pid=container:my-redis my_strace_docker_image bash
$ strace -p 1

UTS设置(--uts)

--uts=""  : Set the UTS namespace mode for the container,
       'host': use the host's UTS namespace inside the container

UTS名称空间用于设置主机名和对该名称空间中正在运行的进程可见的域。默认情况下,所有容器(包括带有--network=host容器)都具有自己的UTS命名空间。host设置将导致容器使用与主机相同的UTS命名空间。请注意, --hostname--domainnamehost UTS模式下无效。

如果希望容器的主机名随着主机的主机名更改而更改,则可能希望与主机共享UTS名称空间。一个更高级的用例是从容器更改主机的主机名。

IPC设置(--ipc)

--ipc="MODE"  : Set the IPC mode for the container

接受以下值:

描述
”” 使用守护程序的默认值。
“没有” 自己的私有IPC名称空间,未安装/ dev / shm。
“私人的” 自己的专用IPC名称空间。
“可共享” 自己的私有IPC名称空间,可以与其他容器共享。
“容器:<_名称或ID_>” 加入另一个(“可共享”)容器的IPC名称空间。
“主办” 使用主机系统的IPC名称空间。

如果未指定,则使用守护程序默认值,它可以是"private""shareable" ,具体取决于守护程序的版本和配置。

IPC(POSIX / SysV IPC)名称空间提供命名共享内存段,信号量和消息队列的分隔。

共享内存段用于以内存速度加速进程间通信,而不是通过管道或网络堆栈。数据库和科学计算和金融服务行业的定制应用程序(通常是C / OpenMPI,C ++ /使用boost库)通常使用共享内存。如果将这些类型的应用程序分为多个容器,则可能需要共享容器的IPC机制,对主容器(即“捐赠者”)使用"shareable"模式,并使用"container:<donor-name-or-ID>"用于其他容器)。

网络设置

--dns=[]           : Set custom dns servers for the container
--network="bridge" : Connect a container to a network
                      'bridge': create a network stack on the default Docker bridge
                      'none': no networking
                      'container:<name|id>': reuse another container's network stack
                      'host': use the Docker host network stack
                      '<network-name>|<network-id>': connect to a user-defined network
--network-alias=[] : Add network-scoped alias for the container
--add-host=""      : Add a line to /etc/hosts (host:IP)
--mac-address=""   : Sets the container's Ethernet device's MAC address
--ip=""            : Sets the container's Ethernet device's IPv4 address
--ip6=""           : Sets the container's Ethernet device's IPv6 address
--link-local-ip=[] : Sets one or more container's Ethernet device's link local IPv4/IPv6 addresses

默认情况下,所有容器都启用了联网功能,并且可以建立任何传出连接。操作员可以使用docker run --network none完全禁用网络,从而禁用所有传入和传出网络。在这种情况下,您将仅通过文件或STDINSTDOUT执行I / O。

发布端口和链接到其他容器仅适用于默认端口(桥)。链接功能是旧版功能。与链接相比,您应该始终偏爱使用Docker网络驱动程序。

默认情况下,您的容器将使用与主机相同的DNS服务器,但是您可以使用--dns覆盖它。

默认情况下,MAC地址是使用分配给容器的IP地址生成的。您可以通过--mac-address参数(格式: 12:34:56:78:9a:bc )提供MAC地址,从而显式设置容器的MAC地址。请注意,Docker不会检查手动指定的MAC地址是否唯一。

支持的网络:

网络 描述
没有 容器中没有网络。
网桥 (默认) 通过veth接口将容器连接到桥。
主办 在容器内使用主机的网络堆栈。
容器 :<名称| id> 使用通过其名称id指定的另一个容器的网络堆栈。
网络 将容器连接到用户创建的网络(使用docker network create命令)

网络:无

none网络的情况下,容器将无法访问任何外部路由。容器仍将在容器中启用loopback接口,但它没有任何通往外部流量的路由。

网桥

将网络设置为bridge ,容器将使用docker的默认网络设置。在主机上设置了一个网桥,通常称为docker0 ,并将为该容器创建一对veth接口。veth对的一侧将保留在连接到桥的主机上,而另一对将除了loopback接口之外,还将放置在容器的命名空间内。将为网桥的网络上的容器分配一个IP地址,流量将通过该网桥路由到容器。

默认情况下,容器可以通过其IP地址进行通信。要通过名称进行通信,必须将它们链接起来。

网络:主机

将网络设置为host ,容器将共享主机的网络堆栈,并且来自主机的所有接口将对容器可用。容器的主机名将与主机系统上的主机名匹配。请注意,-- --mac-addresshost --mac-address中无效。即使在host网络模式下,默认情况下,容器也有其自己的UTS名称空间。因此,-- --hostname--domainnamehost网络模式下被允许,并且只会更改容器内的主机名和域名。与--hostname相似,-- --add-host ,-- --dns ,-- --dns-search--dns-option选项可以在host网络模式下使用。这些选项更新容器内的/etc/hosts/etc/resolv.conf 。在主机上未对/etc/hosts/etc/resolv.conf进行任何更改。

与默认bridge模式相比, host模式提供了显着更好的网络性能,因为它使用了主机的本机网络堆栈,而桥接则必须通过docker守护程序进行一级虚拟化。当容器的网络性能至关重要时,建议以这种模式运行容器,例如,生产负载平衡器或高性能Web服务器。

注意 :-- --network="host"赋予容器对本地系统服务(例如D-bus)的完全访问权限,因此被认为是不安全的。

网络:容器

将网络设置为container一个容器将共享另一个容器的网络堆栈。另一个容器的名称必须以--network container:<name|id>的格式提供。请注意--add-host --hostname --dns --dns-search --dns-option--mac-addresscontainer --mac-address中无效,-- --publish --publish-all --expose也无效在container netmode中。

示例运行带有Redis绑定到localhost的Redis容器,然后运行redis-cli命令并通过localhost接口连接到Redis服务器的示例。

$ docker run -d --name redis example/redis --bind 127.0.0.1
$ # use the redis container's network stack to access localhost
$ docker run --rm -it --network container:redis example/redis-cli -h 127.0.0.1

用户定义的网络

您可以使用Docker网络驱动程序或外部网络驱动程序插件创建网络。您可以将多个容器连接到同一网络。一旦连接到用户定义的网络,这些容器就可以仅使用另一个容器的IP地址或名称轻松进行通信。

对于支持多主机连接的overlay网络或自定义插件,连接到同一多主机网络但从不同引擎启动的容器也可以这种方式进行通信。

以下示例使用内置bridge网络驱动程序并在创建的网络中运行容器来创建网络

$ docker network create -d bridge my-net
$ docker run --network=my-net -itd --name=container3 busybox

管理/ etc / hosts

您的容器将在/etc/hosts中包含几行,这些行定义了容器本身的主机名以及localhost和其他一些常见的东西。--add-host标志可用于向/etc/hosts添加其他行。

$ docker run -it --add-host db-static:86.75.30.9 ubuntu cat /etc/hosts
172.17.0.22     09d03f76bf2c
fe00::0         ip6-localnet
ff00::0         ip6-mcastprefix
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
127.0.0.1       localhost
::1	            localhost ip6-localhost ip6-loopback
86.75.30.9      db-static

如果某个容器已连接到默认的桥接网络并与其他容器linked ,则该容器的/etc/hosts文件将使用链接的容器的名称进行更新。

注意由于Docker可以实时更新容器的/etc/hosts文件,因此在某些情况下,容器内的进程最终可能会读取空的或不完整的/etc/hosts文件。在大多数情况下,重试读取应该可以解决该问题。

重新启动策略(-重新启动)

在Docker运行时使用--restart标志,您可以指定重启策略,以指定容器在退出时应如何重启。

当容器上的重启策略处于活动状态时,它将在docker ps显示为UpRestarting 。使用docker events查看生效的重启策略也可能很有用。

Docker支持以下重启策略:

政策 结果
没有 退出时不要自动重启容器。这是默认值。
失败 [:max-retries] 仅当容器以非零退出状态退出时才重新启动。(可选)限制Docker守护进程尝试重新启动的重试次数。
总是 无论退出状态如何,请始终重新启动容器。当您始终指定时,Docker守护程序将尝试无限期重启容器。无论容器的当前状态如何,该容器还将始终在守护程序启动时启动。
除非停止 无论退出状态如何(包括守护程序启动时),无论退出状态如何,都应始终重新启动容器,除非容器在停止Docker守护程序之前处于停止状态。

在每次重新启动之前,添加一个不断增加的延迟(从100毫秒开始,是以前的延迟的两倍),以防止服务器泛滥。这意味着守护程序将等待100 ms,然后等待200 ms,400、800、1600,依此类推,直到达到on-failure限制,或者当docker stopdocker rm -f容器时。

如果成功重启容器(容器已启动并运行至少10秒钟),则延迟将重置为其默认值100毫秒。

您可以指定使用失败模式时Docker尝试重新启动容器的最大次数。默认是Docker将永远尝试重新启动容器。可以通过docker inspect获得容器的(尝试的)重启次数。例如,获取容器“ my-container”的重新启动次数;

$ docker inspect -f "{{ .RestartCount }}" my-container
# 2

或者,获取上一次启动(重新)容器的时间;

$ docker inspect -f "{{ .State.StartedAt }}" my-container
# 2015-03-04T23:47:07.691840179Z

--restart (重新启动策略)与--rm (清除)标志结合使用会导致错误。容器重新启动时,连接的客户端将断开连接。请参阅--rm有关使用--rm (清除)标志的示例。

例子

$ docker run --restart=always redis

这将以始终为重启策略的方式运行redis容器,以便如果容器退出,则Docker将重新启动它。

$ docker run --restart=on-failure:10 redis

这将以重新启动策略( 失败时重新启动)和最大重新启动计数为10来运行redis容器。如果redis容器连续以非零退出状态退出10次以上,则Docker将中止尝试重新启动容器的操作。提供最大重启限制仅对失败策略有效。

退出状态

docker run的退出代码提供有关为何容器无法运行或为何退出的信息。当docker run使用非零代码退出时,退出代码遵循chroot标准,请参见下文:

125(如果错误是由Docker守护程序本身造成的)

$ docker run --foo busybox; echo $?
# flag provided but not defined: --foo
  See 'docker run --help'.
  125

126如果无法调用所包含的命令

$ docker run busybox /etc; echo $?
# docker: Error response from daemon: Container command '/etc' could not be invoked.
  126

127如果找不到所包含的命令

$ docker run busybox foo; echo $?
# docker: Error response from daemon: Container command 'foo' not found or does not exist.
  127

否则退出包含命令的 代码

$ docker run busybox /bin/sh -c 'exit 3'; echo $?
# 3

清理(--rm)

默认情况下,即使容器退出后,容器的文件系统也会保留。这使调试容易得多(因为您可以检查最终状态),并且默认情况下保留所有数据。但是,如果您正在运行短期前台进程,那么这些容器文件系统确实会堆积起来。相反,如果您希望Docker 自动清理容器并在容器退出时删除文件系统,则可以添加--rm标志:

--rm=false: Automatically remove the container when it exits

注意 :设置--rm标志时,当删除容器时,Docker还将删除与该容器关联的匿名卷。这类似于运行docker rm -v my-container 。仅删除没有名称的指定卷。例如,使用docker run --rm -v /foo -v awesome:/bar busybox top ,将删除/foo的卷,但不会删除/bar的卷。通过--volumes-from继承的卷将以相同的逻辑删除-如果原始卷是用名称指定的,则不会删除。

安全配置

--security-opt="label=user:USER"     : Set the label user for the container
--security-opt="label=role:ROLE"     : Set the label role for the container
--security-opt="label=type:TYPE"     : Set the label type for the container
--security-opt="label=level:LEVEL"   : Set the label level for the container
--security-opt="label=disable"       : Turn off label confinement for the container
--security-opt="apparmor=PROFILE"    : Set the apparmor profile to be applied to the container
--security-opt="no-new-privileges:true|false"   : Disable/enable container processes from gaining new privileges
--security-opt="seccomp=unconfined"  : Turn off seccomp confinement for the container
--security-opt="seccomp=profile.json": White listed syscalls seccomp Json file to be used as a seccomp filter

您可以通过指定--security-opt标志来覆盖每个容器的默认标签方案。在以下命令中指定级别可以使您在容器之间共享相同的内容。

$ docker run --security-opt label=level:s0:c100,c200 -it fedora bash

注意 :当前不支持MLS标签的自动翻译。

要禁用此容器的安全标签,而不是使用--privileged标志运行,请使用以下命令:

$ docker run --security-opt label=disable -it fedora bash

如果要对容器内的进程采用更严格的安全策略,则可以为容器指定其他类型。您可以通过执行以下命令来运行仅允许在Apache端口上侦听的容器:

$ docker run --security-opt label=type:svirt_apache_t -it centos bash

注意 :您必须编写定义svirt_apache_t类型的策略。

如果要阻止容器进程获取其他特权,可以执行以下命令:

$ docker run --security-opt no-new-privileges -it centos bash

这意味着提高权限的命令(例如susudo将不再起作用。它还会导致在删除特权后,稍后再应用任何seccomp过滤器,这可能意味着您可以使用一组更具限制性的过滤器。有关更多详细信息,请参见内核文档

指定一个初始化过程

您可以使用--init标志来指示应将初始化进程用作容器中的PID 1。指定初始化过程可确保在创建的容器内执行初始化系统的通常职责,例如获取僵尸进程。

使用的默认初始化进程是在Docker守护进程的系统路径中找到的第一个docker-init可执行文件。默认安装中包含的此docker-init二进制文件由tini支持。

指定自定义cgroup

使用--cgroup-parent标志,您可以传递特定的cgroup来运行容器。这使您可以自行创建和管理cgroup。您可以为这些cgroup定义自定义资源,并将容器放在公共父组下。

资源的运行时限制

操作员还可以调整容器的性能参数:

选项 描述
-m ,-- --memory="" 内存限制(格式: <number>[<unit>] )。Number是一个正整数。单位可以是bkmg 。最小为4M。
--memory-swap =“” 总内存限制(内存+交换,格式: <number>[<unit>] )。数字是一个正整数。单位可以是bkmg
--memory-reservation =“” 内存软限制(格式: <number>[<unit>] )。数字是一个正整数。单位可以是bkmg
--kernel-memory =“” 内核内存限制(格式: <number>[<unit>] )。Number是一个正整数。单位可以是bkmg 。最小为4M。
-c ,-- --cpu-shares=0 CPU份额(相对重量)
--cpus = 0.000 CPU数量。数字是小数。0.000表示没有限制。
--cpu-period = 0 限制CPU CFS(完全公平调度程序)期限
--cpuset-cpus =“” 允许执行的CPU(0-3,0,1)
--cpuset-mems =“” 允许执行的内存节点(MEM)(0-3,0,1)。仅在NUMA系统上有效。
--cpu-quota = 0 限制CPU CFS(完全公平的调度程序)配额
--cpu-rt-period = 0 限制CPU的实时时间。以微秒为单位。需要设置父级cgroup,并且不能高于父级cgroup。还要检查rtprio ulimits。
--cpu-rt-runtime = 0 限制CPU实时运行时间。以微秒为单位。需要设置父级cgroup,并且不能高于父级cgroup。还要检查rtprio ulimits。
--blkio-weight = 0 块IO权重(相对权重)接受10到1000之间的权重值。
--blkio-weight-device =“” 块IO权重(相对设备权重,格式: DEVICE_NAME:WEIGHT
--device-read-bps =“” 限制从设备读取的速率(格式: <device-path>:<number>[<unit>] )。数字是一个正整数。单位可以是kbmbgb
--device-write-bps =“” 将写入速率限制为设备(格式: <device-path>:<number>[<unit>] )。数字是一个正整数。单位可以是kbmbgb
--device-read-iops =“” 限制从设备(格式: <device-path>:<number> )的读取速率(每秒IO)。数字是一个正整数。
--device-write-iops =“” 将写入速率(每秒的IO)限制为设备(格式: <device-path>:<number> )。数字是一个正整数。
--oom-kill-disable = false 是否为容器禁用OOM Killer。
--oom-score-adj = 0 调整容器的OOM首选项(-1000到1000)
--memory-swappiness =“” 调整容器的内存交换行为。接受0到100之间的整数。
--shm-size =“” /dev/shm大小。格式为<number><unit>number必须大于0 。单位是可选的,可以是b (字节), k (千字节), m (兆字节)或g (千兆字节)。如果省略单位,则系统使用字节。如果完全省略大小,则系统使用64m

用户内存限制

我们有四种设置用户内存使用量的方法:

选项 结果
memory = inf,memory-swap = inf (默认) 容器没有内存限制。容器可以使用所需的内存。
内存= L <inf,内存交换= inf (指定内存,并将memory-swap设置为-1 )容器不允许使用超过L个字节的内存,但可以根据需要使用尽可能多的交换(如果主机支持交换内存)。
内存= L <inf,内存交换= 2 * L (请指定无内存交换的内存)不允许该容器使用超过L个字节的内存,而交换内存使用量则是该字节的两倍。
内存= L <inf,内存交换= S <inf,L <= S (同时指定内存和内存交换)容器不允许使用超过L个字节的内存,交换内存使用量受S限制。

例子:

$ docker run -it ubuntu:14.04 /bin/bash

我们没有对内存进行任何设置,这意味着容器中的进程可以使用所需的内存并交换所需的内存。

$ docker run -it -m 300M --memory-swap -1 ubuntu:14.04 /bin/bash

我们设置了内存限制和禁用了交换内存限制,这意味着容器中的进程可以使用300M内存,并根据需要使用尽可能多的交换内存(如果主机支持交换内存)。

$ docker run -it -m 300M ubuntu:14.04 /bin/bash

我们仅设置内存限制,这意味着容器中的进程可以使用300M内存和300M交换内存,默认情况下,总虚拟内存大小(--memory-swap)将设置为内存的两倍,在这种情况下,内存+ swap将为2 * 300M,因此进程也可以使用300M交换内存。

$ docker run -it -m 300M --memory-swap 1G ubuntu:14.04 /bin/bash

我们同时设置了内存和交换内存,因此容器中的进程可以使用300M内存和700M交换内存。

内存保留是一种内存软限制,它可以实现更大的内存共享。在正常情况下,容器可以使用所需数量的内存,并且仅受-m / --memory选项设置的硬限制的约束。设置内存预留后,Docker会检测到内存争用或内存不足,并强制容器将其使用限制为预留限制。

始终将内存保留值设置为硬限制以下,否则硬限制优先。保留为0等于不设置保留。默认情况下(未设置保留),内存保留与硬盘限制相同。

内存保留是一项软限制功能,不能保证不会超出限制。取而代之的是,此功能试图确保在内存竞争激烈时,根据预留提示/设置分配内存。

以下示例将内存( -m )限制为500M,并将内存预留设置为200M。

$ docker run -it -m 500M --memory-reservation 200M ubuntu:14.04 /bin/bash

在这种配置下,当容器消耗的内存大于200M且小于500M时,下一个系统内存回收将尝试将容器内存缩小到200M以下。

下面的示例将内存保留设置为1G,没有硬盘限制。

$ docker run -it --memory-reservation 1G ubuntu:14.04 /bin/bash

容器可以使用所需的内存。内存预留设置可确保容器长时间不占用过多内存,因为每次回收内存都会将容器的消耗减少到预留空间。

默认情况下,如果发生内存不足(OOM)错误,内核将终止容器中的进程。要更改此行为,请使用--oom-kill-disable选项。仅在还设置了-m/--memory选项的容器上禁用OOM杀手。如果未设置-m标志,则可能导致主机内存不足,并要求终止主机的系统进程以释放内存。

以下示例将内存限制为100M,并为此容器禁用OOM杀手:

$ docker run -it -m 100M --oom-kill-disable ubuntu:14.04 /bin/bash

以下示例说明了使用标志的危险方式:

$ docker run -it --oom-kill-disable ubuntu:14.04 /bin/bash

容器具有无限的内存,这可能导致主机内存用完,并需要终止系统进程来释放内存。可以更改--oom-score-adj参数,以选择在系统内存不足时将杀死哪些容器的优先级,负分数会使它们被杀死的可能性较小,而正分数则更有可能被杀死。

内核内存限制

内核内存从根本上不同于用户内存,因为不能交换内核内存。无法交换使得容器可以通过消耗过多的内核内存来阻止系统服务。内核内存包括:

  • 堆叠页面
  • 平板页面
  • 插槽内存压力
  • tcp内存压力

您可以设置内核内存限制来限制这些类型的内存。例如,每个进程都消耗一些堆栈页面。通过限制内核内存,可以防止内核内存使用率过高时创建新进程。

内核内存永远不会完全独立于用户内存。而是在用户内存限制的范围内限制内核内存。假设“ U”是用户内存限制,“ K”是内核限制。有三种可能的方式来设置限制:

选项 结果
!!= 0,K = inf (默认) 这是使用内核内存之前已经存在的标准内存限制机制。内核内存被完全忽略。
!!= 0,K <U 内核内存是用户内存的子集。此设置在每个cgroup的内存总量被过量使用的部署中很有用。绝对不建议过度使用内核内存限制,因为此框仍然会耗尽不可回收的内存。在这种情况下,您可以配置K,以便所有组的总和永远不大于总内存。然后,以系统的服务质量为代价自由设置U。
!!= 0,K> U 由于内核内存费用也被馈送到用户计数器,并且针对两种内存的容器触发回收。此配置为管理员提供了内存的统一视图。对于只想跟踪内核内存使用情况的人来说,它也很有用。

例子:

$ docker run -it -m 500M --kernel-memory 50M ubuntu:14.04 /bin/bash

我们设置了内存和内核内存,因此容器中的进程总共可以使用500M内存,在这500M内存中,它可以是50M内核内存的顶部。

$ docker run -it --kernel-memory 50M ubuntu:14.04 /bin/bash

我们将内核内存设置为不带-m ,因此容器中的进程可以使用所需数量的内存,但它们只能使用50M内核内存。

湿度约束

默认情况下,容器的内核可以换出一定比例的匿名页面。要为容器设置此百分比,请在0到100之间指定--memory-swappiness值。值为0将关闭匿名页面交换。值100会将所有匿名页面设置为可交换。默认情况下,如果您不使用--memory-swappiness ,则内存交换值将从父级继承。

例如,您可以设置:

$ docker run -it --memory-swappiness=0 ubuntu:14.04 /bin/bash

当您要保留容器的工作集并避免交换性能损失时,设置--memory-swappiness选项将很有帮助。

CPU份额限制

默认情况下,所有容器获得相同比例的CPU周期。可以通过更改容器的CPU份额权重(相对于所有其他正在运行的容器的权重)来修改此比例。

要从默认值1024修改比例,请使用-c--cpu-shares标志将权重设置为2或更高。如果设置为0,则系统将忽略该值,并使用默认值1024。

该比例仅在运行CPU密集型进程时适用。当一个容器中的任务空闲时,其他容器可以使用剩余的CPU时间。实际的CPU时间量取决于系统上运行的容器数。

例如,考虑三个容器,一个容器的cpu份额为1024,另外两个容器的cpu份额设置为512。当所有三个容器中的进程尝试使用100%的CPU时,第一个容器将获得总CPU时间的50%。如果添加第四个容器的cpu份额为1024,则第一个容器仅获得33%的CPU。剩余的容器接收CPU的16.5%,16.5%和33%。

在多核系统上,CPU时间的份额分配在所有CPU核上。即使容器限制为少于100%的CPU时间,它也可以使用每个CPU核心的100%。

例如,考虑具有三个以上内核的系统。如果您使用-c=512运行一个进程来启动一个容器{C0} ,而使用-c=1024运行两个进程来启动另一个容器{C1} ,则可能导致以下CPU份额划分:

PID    container	CPU	CPU share
100    {C0}		0	100% of CPU0
101    {C1}		1	100% of CPU1
102    {C1}		2	100% of CPU2

CPU周期限制

默认的CPU CFS(完全公平调度程序)周期为100ms。我们可以使用--cpu-period设置CPU的时间以限制容器的CPU使用率。通常--cpu-period应该与--cpu-quota

例子:

$ docker run -it --cpu-period=50000 --cpu-quota=25000 ubuntu:14.04 /bin/bash

如果有1个CPU,则意味着该容器每50毫秒可获取50%的CPU运行时间。

除了使用--cpu-period--cpu-quota来设置CPU周期约束外,还可以使用浮点数指定--cpus以实现相同的目的。例如,如果有1个CPU,则--cpus=0.5将获得与设置--cpu-period=50000--cpu-quota=25000 (50%CPU)相同的结果。

--cpus的默认值为0.000 ,这意味着没有限制。

有关更多信息,请参阅有关带宽限制CFS文档

Cpuset约束

我们可以设置cpus以允许容器执行。

例子:

$ docker run -it --cpuset-cpus="1,3" ubuntu:14.04 /bin/bash

这意味着容器中的进程可以在cpu 1和cpu 3上执行。

$ docker run -it --cpuset-cpus="0-2" ubuntu:14.04 /bin/bash

这意味着容器中的进程可以在cpu 0,cpu 1和cpu 2上执行。

我们可以设置允许在其中执行容器的内存。仅在NUMA系统上有效。

例子:

$ docker run -it --cpuset-mems="1,3" ubuntu:14.04 /bin/bash

本示例将容器中的进程限制为仅使用来自内存节点1和3的内存。

$ docker run -it --cpuset-mems="0-2" ubuntu:14.04 /bin/bash

本示例将容器中的进程限制为仅使用来自内存节点0、1和2的内存。

CPU配额限制

--cpu-quota标志限制了容器的CPU使用率。默认0值允许容器占用100%的CPU资源(1个CPU)。CFS(完全公平调度程序)处理用于执行进程的资源分配,并且是内核使用的默认Linux调度程序。将此值设置为50000可将容器限制为CPU资源的50%。对于多个CPU,根据需要调整--cpu-quota 。有关更多信息,请参阅有关带宽限制CFS文档

块IO带宽(Blkio)约束

默认情况下,所有容器都获得相同比例的块IO带宽(blkio)。这个比例是500。要修改此比例,请使用--blkio-weight标志,相对于所有其他运行中的容器权重更改容器的blkio权--blkio-weight

注意: blkio权重设置仅适用于直接IO。当前不支持缓冲的IO。

--blkio-weight标志可以将权重设置为10到1000之间的值。例如,以下命令创建两个具有不同blkio权重的容器:

$ docker run -it --name c1 --blkio-weight 300 ubuntu:14.04 /bin/bash
$ docker run -it --name c2 --blkio-weight 600 ubuntu:14.04 /bin/bash

如果您同时在两个容器中阻止IO,例如:

$ time dd if=/mnt/zerofile of=test.out bs=1M count=1024 oflag=direct

您会发现时间比例与两个容器的blkio重量比例相同。

--blkio-weight-device="DEVICE_NAME:WEIGHT"标志用于设置特定的设备权重。DEVICE_NAME:WEIGHT是一个包含冒号分隔的设备名称和重量的字符串。例如,将/dev/sda设备权重设置为200

$ docker run -it \
    --blkio-weight-device "/dev/sda:200" \
    ubuntu

如果您同时指定--blkio-weight--blkio-weight-device ,则Docker将使用--blkio-weight作为默认权重,并使用--blkio-weight-device覆盖此默认值,并使用特定设备。以下示例使用默认权重300并在/dev/sda上将此默认值覆盖,将该权重设置为200

$ docker run -it \
    --blkio-weight 300 \
    --blkio-weight-device "/dev/sda:200" \
    ubuntu

--device-read-bps标志限制了从设备读取的速率(每秒字节数)。例如,此命令创建一个容器,并将/dev/sda的读取速率限制为每秒1mb

$ docker run -it --device-read-bps /dev/sda:1mb ubuntu

--device-write-bps标志限制了设备的写入速率(每秒字节数)。例如,此命令创建一个容器并将/dev/sda的写入速率限制为每秒1mb

$ docker run -it --device-write-bps /dev/sda:1mb ubuntu

这两个标志均采用<device-path>:<limit>[unit]格式的<device-path>:<limit>[unit] 。读写速率都必须为正整数。您可以以kb (千字节), mb (兆字节)或gb (千兆字节)为单位指定速率。

--device-read-iops标志限制了从设备的读取速率(每秒IO)。例如,此命令创建一个容器并将每秒从/dev/sda的读取速率限制为1000 IO:

$ docker run -ti --device-read-iops /dev/sda:1000 ubuntu

--device-write-iops标志可限制对设备的写入速率(每秒IO)。例如,此命令创建一个容器并将对/dev/sda的写入速率限制为每秒1000 IO:

$ docker run -ti --device-write-iops /dev/sda:1000 ubuntu

这两个标志均采用<device-path>:<limit>格式的<device-path>:<limit> 。读写速率都必须为正整数。

其他组

--group-add: Add additional groups to run as

默认情况下,docker容器进程运行时会查找指定用户的补充组。如果要向该组列表添加更多内容,则可以使用以下标志:

$ docker run --rm --group-add audio --group-add nogroup --group-add 777 busybox id
uid=0(root) gid=0(root) groups=10(wheel),29(audio),99(nogroup),777

运行时特权和Linux功能

--cap-add: Add Linux capabilities
--cap-drop: Drop Linux capabilities
--privileged=false: Give extended privileges to this container
--device=[]: Allows you to run devices inside the container without the --privileged flag.

默认情况下,Docker容器是“无特权的”,并且不能(例如)在Docker容器内运行Docker守护程序。这是因为默认情况下,不允许容器访问任何设备,但是授予“特权”容器访问所有设备的权限(请参阅cgroups devices文档)。

当操作员执行docker run --privileged ,Docker将启用对主机上所有设备的访问,并在AppArmor或SELinux中进行一些配置,以允许容器对主机的访问几乎与在主机上容器外部运行的进程相同。可以在Docker Blog上获得有关使用--privileged运行的更多信息。

如果要限制对特定设备的访问,可以使用--device标志。它允许您指定一个或多个在容器内可访问的设备。

$ docker run --device=/dev/snd:/dev/snd ...

默认情况下,容器将能够readwritemknod这些设备。可以使用每个--device标志的第三组:rwm选项来覆盖此设置:

$ docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk  /dev/xvdc

Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:r --rm -it ubuntu fdisk  /dev/xvdc
You will not be able to write the partition table.

Command (m for help): q

$ docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk  /dev/xvdc
    crash....

$ docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk  /dev/xvdc
fdisk: unable to open /dev/xvdc: Operation not permitted

除了--privileged ,操作员还可以使用--cap-add--cap-drop对功能进行精细控制。默认情况下,Docker具有保留的默认功能列表。下表列出了默认情况下允许并可以删除的Linux功能选项。

能力钥匙 能力描述
SETPCAP 修改流程功能。
麦克诺德 使用mknod(2)创建特殊文件。
AUDIT_WRITE 将记录写入内核审核日志。
周恩 对文件UID和GID进行任意更改(请参阅chown(2))。
NET_RAW 使用RAW和PACKET插槽。
DAC_OVERRIDE 绕过文件读取,写入和执行权限检查。
福纳 绕过权限检查通常需要进程的文件系统UID与文件的UID匹配的操作。
FSETID 修改文件时,请勿清除set-user-ID和set-group-ID权限位。
绕过许可检查以发送信号。
SETGID 对进程GID和补充GID列表进行任意处理。
SETUID 对进程UID进行任意操作。
NET_BIND_SERVICE 将套接字绑定到Internet域特权端口(端口号小于1024)。
SYS_CHROOT 使用chroot(2),更改根目录。
集资基金 设置文件功能。

下表显示了默认情况下不授予的功能,可以添加这些功能。

能力钥匙 能力描述
SYS_MODULE 加载和卸载内核模块。
SYS_RAWIO 执行I / O端口操作(iopl(2)和ioperm(2))。
SYS_PACCT 使用acct(2),打开或关闭进程记帐。
SYS_ADMIN 执行一系列系统管理操作。
SYS_NICE 提高进程的nice值(nice(2),setpriority(2))并更改任意进程的nice值。
SYS_RESOURCE 覆盖资源限制。
SYS_TIME 设置系统时钟(settimeofday(2),stime(2),adjtimex(2));设置实时(硬件)时钟。
SYS_TTY_CONFIG 使用vhangup(2);在虚拟终端上使用各种特权的ioctl(2)操作。
AUDIT_CONTROL 启用和禁用内核审核;更改审核过滤器规则;检索审核状态和过滤规则。
MAC_ADMIN 允许MAC配置或状态更改。为Smack LSM实施。
MAC_OVERRIDE 覆盖强制访问控制(MAC)。为Smack Linux安全模块(LSM)实现。
NET_ADMIN 执行各种与网络相关的操作。
系统日志 执行特权的syslog(2)操作。
DAC_READ_SEARCH 绕过文件读取权限检查以及目录读取和执行权限检查。
LINUX_IMMUTABLE 设置FS_APPEND_FL和FS_IMMUTABLE_FL i节点标志。
NET_BROADCAST 进行套接字广播,并收听多播。
IPC_LOCK 锁定内存(mlock(2),mlockall(2),mmap(2),shmctl(2))。
IPC_OWNER 绕过权限检查对System V IPC对象的操作。
SYS_PTRACE 使用ptrace(2)跟踪任意进程。
SYS_BOOT 使用reboot(2)和kexec_load(2),重新引导并加载新内核以供以后执行。
在任意文件上建立租约(请参阅fcntl(2))。
WAKE_ALARM 触发将唤醒系统的操作。
BLOCK_SUSPEND 使用可以阻止系统挂起的功能。

功能(7)-Linux手册页上提供了更多参考信息。

这两个标志都支持值ALL ,因此,如果操作员希望拥有除MKNOD所有功能,则可以使用:

$ docker run --cap-add=ALL --cap-drop=MKNOD ...

为了与网络堆栈进行--privileged ,应该使用--cap-add=NET_ADMIN来修改网络接口,而不是使用--privileged

$ docker run -it --rm  ubuntu:14.04 ip link add dummy0 type dummy
RTNETLINK answers: Operation not permitted
$ docker run -it --rm --cap-add=NET_ADMIN ubuntu:14.04 ip link add dummy0 type dummy

要挂载基于FUSE的文件系统,您需要结合使用--cap-add--device

$ docker run --rm -it --cap-add SYS_ADMIN sshfs sshfs sven@10.10.10.20:/home/sven /mnt
fuse: failed to open /dev/fuse: Operation not permitted
$ docker run --rm -it --device /dev/fuse sshfs sshfs sven@10.10.10.20:/home/sven /mnt
fusermount: mount failed: Operation not permitted
$ docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
# sshfs sven@10.10.10.20:/home/sven /mnt
The authenticity of host '10.10.10.20 (10.10.10.20)' can't be established.
ECDSA key fingerprint is 25:34:85:75:25:b0:17:46:05:19:04:93:b5:dd:5f:c6.
Are you sure you want to continue connecting (yes/no)? yes
sven@10.10.10.20's password:
root@30aa0cfaf1b5:/# ls -la /mnt/src/docker
total 1516
drwxrwxr-x 1 1000 1000   4096 Dec  4 06:08 .
drwxrwxr-x 1 1000 1000   4096 Dec  4 11:46 ..
-rw-rw-r-- 1 1000 1000     16 Oct  8 00:09 .dockerignore
-rwxrwxr-x 1 1000 1000    464 Oct  8 00:09 .drone.yml
drwxrwxr-x 1 1000 1000   4096 Dec  4 06:11 .git
-rw-rw-r-- 1 1000 1000    461 Dec  4 06:08 .gitignore
....

默认的seccomp配置文件将根据所选功能进行调整,以允许使用该功能允许的功能,因此自Docker 1.12起,您不必对此进行调整。在Docker 1.10和1.11中没有发生这种情况,添加功能时可能有必要使用自定义seccomp配置文件或使用--security-opt seccomp=unconfined

日志驱动程序(--log-driver)

容器可以具有与Docker守护程序不同的日志记录驱动程序。将--log-driver=VALUEdocker run命令一起使用以配置容器的日志记录驱动程序。支持以下选项:

司机 描述
没有 禁用容器的任何日志记录。此驱动程序将不提供docker logs
json文件 Docker的默认日志记录驱动程序。将JSON消息写入文件。此驱动程序不支持任何日志记录选项。
系统日志 Docker的Syslog日志记录驱动程序。将日志消息写入syslog。
日记 Docker的日志记录驱动程序。将日志消息写入journald
凝胶 用于Docker的Graylog扩展日志格式(GELF)日志记录驱动程序。将日志消息写入GELF端点(如Graylog或Logstash)。
流利的 Docker的流利日志记录驱动程序。将日志消息fluentd (转发输入)。
博客 Docker的Amazon CloudWatch Logs日志记录驱动程序。将日志消息写入Amazon CloudWatch Logs
散弹 用于Docker的Splunk日志记录驱动程序。使用事件Http收集器将日志消息写入splunk

journald docker logs命令仅适用于json-file和日志记录日志驱动程序。有关使用日志记录驱动程序的详细信息,请参阅配置日志记录驱动程序

覆盖Dockerfile映像默认值

当开发人员从Dockerfile生成映像或提交映像时,开发人员可以设置许多默认参数,这些默认参数在映像作为容器启动时生效。

在运行时无法覆盖以下四个Dockerfile命令: FROMMAINTAINERRUNADD 。其他所有内容在docker run都有相应的覆盖。我们将介绍开发人员在每个Dockerfile指令中可能设置的内容,以及操作员如何覆盖该设置。

CMD(默认命令或选项)

在Docker命令行中调用可选的COMMAND

$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

该命令是可选的,因为创建IMAGE可能已经使用Dockerfile CMD指令提供了默认COMMAND 。作为操作员(从图像运行容器的人员),您只需指定新的COMMAND即可覆盖该CMD指令。

如果图像还指定了ENTRYPOINT则将CMDCOMMAND作为参数附加到ENTRYPOINT

ENTRYPOINT(在运行时执行的默认命令)

--entrypoint="": Overwrite the default entrypoint set by the image

映像的ENTRYPOINTCOMMAND类似,因为它指定了在容器启动时要运行的可执行文件,但是(故意)更难以覆盖。ENTRYPOINT为容器提供了其默认性质或行为,因此,当您设置ENTRYPOINT您可以像运行该二进制文件一样运行该容器,并带有默认选项,并且可以通过COMMAND传递更多选项。但是,有时运营商可能需要运行在容器内别的东西,这样你就可以覆盖默认ENTRYPOINT使用字符串来指定新的在运行时ENTRYPOINT 。这是一个如何在已设置为自动运行其他内容(例如/usr/bin/redis-server )的容器中运行Shell的示例:

$ docker run -it --entrypoint /bin/bash example/redis

或两个如何将更多参数传递给该ENTRYPOINT的示例:

$ docker run -it --entrypoint /bin/bash example/redis -c ls -l
$ docker run -it --entrypoint /usr/bin/redis-cli example/redis --help

您可以通过传递空字符串来重置容器入口点,例如:

$ docker run -it --entrypoint="" mysql bash

注意 :传递--entrypoint将清除映像上设置的任何默认命令(即,用于构建映像的Dockerfile中的任何CMD指令)。

暴露(入港)

以下run命令选项可用于容器网络:

--expose=[]: Expose a port or a range of ports inside the container.
             These are additional to those exposed by the `EXPOSE` instruction
-P         : Publish all exposed ports to the host interfaces
-p=[]      : Publish a container's port or a range of ports to the host
               format: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPort
               Both hostPort and containerPort can be specified as a
               range of ports. When specifying ranges for both, the
               number of container ports in the range must match the
               number of host ports in the range, for example:
                   -p 1234-1236:1234-1236/tcp

               When specifying a range for hostPort only, the
               containerPort must not be a range.  In this case the
               container port is published somewhere within the
               specified hostPort range. (e.g., `-p 1234-1236:1234/tcp`)

               (use 'docker port' to see the actual mapping)

--link=""  : Add link to another container (<name or id>:alias or <name or id>)

除了EXPOSE指令外,图像开发人员对网络的控制并不多。EXPOSE指令定义了提供服务的初始传入端口。这些端口可用于容器内部的进程。操作员可以使用--expose选项添加到暴露的端口。

要公开容器的内部端口,操作员可以使用-P-p标志启动容器。主机上可以访问裸露的端口,并且所有可访问主机的客户端都可以使用这些端口。

-P选项将所有端口发布到主机接口。Docker将每个公开端口绑定到主机上的随机端口。端口范围/proc/sys/net/ipv4/ip_local_port_range定义的临时端口范围内 。使用-p标志可以显式映射单个端口或端口范围。

容器内部(服务在其中进行侦听的端口)的端口号不需要与容器外部(客户端进行连接的地方)暴露的端口号相匹配。例如,在容器内,HTTP服务正在端口80上侦听(因此映像开发人员在Dockerfile中指定EXPOSE 80 )。在运行时,端口可能绑定到主机上的42800。要查找主机端口和公开端口之间的映射,请使用docker port

如果操作员在默认桥接网络中启动新的客户端容器时使用--link ,则该客户端容器可以通过专用网络接口访问公开的端口。如网络概述中所述,在用户定义的网络中启动容器时使用--link时,它将为要链接的容器提供命名别名。

ENV(环境变量)

创建Linux容器时,Docker会自动设置一些环境变量。创建Windows容器时,Docker不会设置任何环境变量。

为Linux容器设置了以下环境变量:

变量
根据USER的值进行设置
主机名 与容器关联的主机名
路径 包括流行的目录,例如/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
术语 xterm是否为容器分配了伪TTY

此外,操作员可以使用一个或多个-e标志设置容器中的任何环境变量 ,甚至覆盖上面提到的标志,或者由开发人员使用Dockerfile ENV定义。如果操作员在没有指定值的情况下命名环境变量,则命名变量的当前值将传播到容器的环境中:

$ export today=Wednesday
$ docker run -e "deep=purple" -e today --rm alpine env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=d2219b854598
deep=purple
today=Wednesday
HOME=/root
PS C:\> docker run --rm -e "foo=bar" microsoft/nanoserver cmd /s /c set
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\ContainerAdministrator\AppData\Roaming
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=C2FAEFCC8253
ComSpec=C:\Windows\system32\cmd.exe
foo=bar
LOCALAPPDATA=C:\Users\ContainerAdministrator\AppData\Local
NUMBER_OF_PROCESSORS=8
OS=Windows_NT
Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Users\ContainerAdministrator\AppData\Local\Microsoft\WindowsApps
PATHEXT=.COM;.EXE;.BAT;.CMD
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 62 Stepping 4, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=3e04
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PUBLIC=C:\Users\Public
SystemDrive=C:
SystemRoot=C:\Windows
TEMP=C:\Users\ContainerAdministrator\AppData\Local\Temp
TMP=C:\Users\ContainerAdministrator\AppData\Local\Temp
USERDOMAIN=User Manager
USERNAME=ContainerAdministrator
USERPROFILE=C:\Users\ContainerAdministrator
windir=C:\Windows

同样,操作员可以使用-h设置HOSTNAME (Linux)或COMPUTERNAME (Windows)。

健康检查

  --health-cmd            Command to run to check health
  --health-interval       Time between running the check
  --health-retries        Consecutive failures needed to report unhealthy
  --health-timeout        Maximum time to allow one check to run
  --health-start-period   Start period for the container to initialize before starting health-retries countdown
  --no-healthcheck        Disable any container-specified HEALTHCHECK

例:

$ docker run --name=test -d \
    --health-cmd='stat /etc/passwd || exit 1' \
    --health-interval=2s \
    busybox sleep 1d
$ sleep 2; docker inspect --format='{{.State.Health.Status}}' test
healthy
$ docker exec test rm /etc/passwd
$ sleep 2; docker inspect --format='{{json .State.Health}}' test
{
  "Status": "unhealthy",
  "FailingStreak": 3,
  "Log": [
    {
      "Start": "2016-05-25T17:22:04.635478668Z",
      "End": "2016-05-25T17:22:04.7272552Z",
      "ExitCode": 0,
      "Output": "  File: /etc/passwd\n  Size: 334       \tBlocks: 8          IO Block: 4096   regular file\nDevice: 32h/50d\tInode: 12          Links: 1\nAccess: (0664/-rw-rw-r--)  Uid: (    0/    root)   Gid: (    0/    root)\nAccess: 2015-12-05 22:05:32.000000000\nModify: 2015..."
    },
    {
      "Start": "2016-05-25T17:22:06.732900633Z",
      "End": "2016-05-25T17:22:06.822168935Z",
      "ExitCode": 0,
      "Output": "  File: /etc/passwd\n  Size: 334       \tBlocks: 8          IO Block: 4096   regular file\nDevice: 32h/50d\tInode: 12          Links: 1\nAccess: (0664/-rw-rw-r--)  Uid: (    0/    root)   Gid: (    0/    root)\nAccess: 2015-12-05 22:05:32.000000000\nModify: 2015..."
    },
    {
      "Start": "2016-05-25T17:22:08.823956535Z",
      "End": "2016-05-25T17:22:08.897359124Z",
      "ExitCode": 1,
      "Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
    },
    {
      "Start": "2016-05-25T17:22:10.898802931Z",
      "End": "2016-05-25T17:22:10.969631866Z",
      "ExitCode": 1,
      "Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
    },
    {
      "Start": "2016-05-25T17:22:12.971033523Z",
      "End": "2016-05-25T17:22:13.082015516Z",
      "ExitCode": 1,
      "Output": "stat: can't stat '/etc/passwd': No such file or directory\n"
    }
  ]
}

健康状态也会显示在docker ps输出中。

TMPFS(挂载tmpfs文件系统)

--tmpfs=[]: Create a tmpfs mount with: container-dir[:<options>],
            where the options are identical to the Linux
            'mount -t tmpfs -o' command.

下面的示例使用rwnoexecnosuidsize=65536k选项将空的tmpfs装入容器。

$ docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image

VOLUME(共享文件系统)

-v, --volume=[host-src:]container-dest[:<options>]: Bind mount a volume.
The comma-delimited `options` are [rw|ro], [z|Z],
[[r]shared|[r]slave|[r]private], and [nocopy].
The 'host-src' is an absolute path or a name value.

If neither 'rw' or 'ro' is specified then the volume is mounted in
read-write mode.

The `nocopy` mode is used to disable automatically copying the requested volume
path in the container to the volume storage location.
For named volumes, `copy` is the default mode. Copy modes are not supported
for bind-mounted volumes.

--volumes-from="": Mount all volumes from the given container(s)

注意 :当使用systemd管理Docker守护程序的启动和停止时,在systemd单元文件中有一个选项来控制Docker守护程序本身的安装传播,称为MountFlags 。此设置的值可能会导致Docker无法看到在安装点上进行的安装传播更改。例如,如果此值为slave ,则可能无法在卷上使用sharedrshared传播。

卷命令足够复杂,可以在“ 使用卷”部分中拥有自己的文档。开发人员可以定义与映像关联的一个或多个VOLUME ,但是只有操作员才能从一个容器访问另一个容器(或从容器访问安装在主机上的卷)。

container-dest必须始终是绝对路径,例如/src/docshost-src可以是绝对路径或name值。如果您提供host-dir的绝对路径,则Docker将绑定绑定到您指定的路径。如果提供name ,则Docker将使用该name创建一个命名卷。

name值必须以字母数字字符开始,接着a-z0-9_ (下划线), . (句号)或- (连字符)。绝对路径以/ (正斜杠)开头。

例如,您可以为host-src值指定/foofoo 。如果提供/foo值,则Docker将创建绑定安装。如果提供foo规范,则Docker将创建一个命名卷。

用户

root (id = 0)是容器中的默认用户。图像开发人员可以创建其他用户。这些用户可以通过名称访问。传递数字ID时,用户不必在容器中。

开发人员可以使用Dockerfile USER指令设置默认用户以运行第一个进程。启动容器时,操作员可以通过传递-u选项来覆盖USER指令。

-u="", --user="": Sets the username or UID used and optionally the groupname or GID for the specified command.

The followings examples are all valid:
--user=[ user | user:group | uid | uid:gid | user:gid | uid:group ]

注意:如果您传递数字uid,则它必须在0-2147483647的范围内。

工作目录

在容器中运行二进制文件的默认工作目录是根目录( / ),但是开发人员可以使用Dockerfile WORKDIR命令设置其他默认目录。操作员可以使用以下方法覆盖它:

-w="": Working directory inside the container
码头工人运行配置运行时