预计阅读时间:66分钟

Docker run reference

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

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

General form

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

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

docker run命令必须指定一个IMAGE来派生容器. 图像开发人员可以定义与以下相关的图像默认值:

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

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

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

Note

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

Operator exclusive options

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

Detached vs foreground

启动 Docker 容器时,您必须首先决定是在后台以"分离"模式还是在默认前台模式下运行容器:

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

Detached (-d)

要以分离模式启动容器,请使用-d=true或仅使用-d选项. 按照设计,当用于运行容器的根进程退出时,以分离模式启动的容器退出,除非您还指定--rm选项. 如果将-d--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命令.

Foreground

在前台模式下(不指定-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 ,正如您将在后面的示例中看到的那样. 当客户端从管道接收其标准输入时,禁止指定-t ,如下所示:

$ echo test | docker run -i busybox cat

Note

Linux 对容器内以 PID 1 运行的进程进行特殊处理:它忽略具有默认操作的任何信号. 因此,进程不会在SIGINTSIGTERM上终止,除非它被编码为这样做.

Container identification

Name (--name)

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

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

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

Note

默认桥接网络上的容器必须链接才能通过名称进行通信.

PID equivalent

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

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

Image[:tag]

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

Image[@digest]

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

以下示例使用sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0摘要从alpine映像运行容器:

$ docker run alpine@sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0 date

PID settings (--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等调试工具构建容器,但希望在容器内调试进程时使用这些工具.

Example: run htop inside a container

创建这个 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

Joining another container’s pid namespace can be used for debugging that container.

Example

启动一个运行 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 settings (--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 settings (--ipc)

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

接受以下值:

Value Description
”” 使用守护进程的默认值.
“none” 自己的私有 IPC 命名空间,未安装 /dev/shm.
“private” 拥有私有 IPC 命名空间.
“shareable” 拥有私有 IPC 命名空间,可以与其他容器共享.
"容器:<_name-or-ID_>" 加入另一个("可共享")容器的 IPC 命名空间.
“host” 使用主机系统的 IPC 命名空间.

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

IPC (POSIX/SysV IPC) 命名空间提供了命名共享内存段、信号量和消息队列的分离.

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

Network settings

--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 地址是否为独特.

支持的网络:

Network Description
none 容器中没有网络.
bridge (default) 通过 veth 接口将容器连接到网桥.
host 在容器内使用主机的网络堆栈.
container:<name|id> 使用另一个容器的网络堆栈,通过其名称id指定.
NETWORK 将容器连接到用户创建的网络(使用docker network create命令)

Network: none

如果 network is none ,容器将无法访问任何外部路由. 容器仍将在容器中启用loopback接口,但它没有任何通往外部流量的路由.

Network: bridge

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

Containers can communicate via their IP addresses by default. To communicate by name, they must be linked.

Network: host

将网络设置为host后,容器将共享主机的网络堆栈,并且主机的所有接口都可用于容器. 容器的主机名将与主机系统上的主机名匹配. 注意--mac-addresshost网络模式下无效. 即使在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 服务器.

Note

--network="host"使容器可以完全访问本地系统服务,例如 D-bus,因此被认为是不安全的.

Network: container

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

示例运行 Redis 容器并将 Redis 绑定到localhost ,然后运行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

User-defined network

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

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

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

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

Managing /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文件将使用链接容器的名称进行更新.

Note

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

Restart policies (--restart)

在 Docker run 上使用--restart标志,您可以指定容器在退出时应该或不应该如何重新启动的重新启动策略.

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

Docker 支持以下重启策略:

Policy Result
no 容器退出时不要自动重启. 这是默认设置.
on-failure[:max-retries] 仅当容器以非零退出状态退出时才重新启动. (可选)限制 Docker 守护程序尝试重新启动的次数.
always 无论退出状态如何,始终重新启动容器. 当您指定 always 时,Docker 守护程序将尝试无限期地重新启动容器. 无论容器的当前状态如何,容器也将始终在守护程序启动时启动.
unless-stopped 无论退出状态如何,始终重启容器,包括在守护进程启动时,除非容器在 Docker 守护进程停止之前进入停止状态.

在每次重新启动之前添加一个增加的延迟(是先前延迟的两倍,从 100 毫秒开始),以防止服务器泛滥. 这意味着守护进程将等待 100 毫秒,然后等待 200 毫秒、400、800、1600 等等,直到达到on-failure限制、达到 1 分钟的最大延迟,或者当您使用docker stopdocker rm -f容器.

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

您可以指定 Docker 在使用on-failure策略时尝试重新启动容器的最大次数. 默认情况下,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 (清理)标志的示例.

Examples

$ docker run --restart=always redis

这将以always的重启策略运行redis容器,这样如果容器退出,Docker 将重启它.

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

这将以on-failure重启策略和最大重启计数 10 运行redis容器.如果redis容器以非零退出状态退出连续超过 10 次,Docker 将中止尝试重启容器. 提供最大重启限制仅对失败策略有效.

Exit Status

The exit code from docker run gives information about why the container failed to run or why it exited. When docker run exits with a non-zero code, the exit codes follow the chroot standard, see below:

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

退出代码 of 包含命令 otherwise

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

Clean up (--rm)

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

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

Note

If you set the --rm flag, Docker also removes the anonymous volumes associated with the container when the container is removed. This is similar to running docker rm -v my-container. Only volumes that are specified without a name are removed. For example, when running:

$ docker run --rm -v /foo -v awesome:/bar busybox top

/foo的音量将被删除,但/bar的音量不会. 通过--volumes-from继承的卷将使用相同的逻辑删除:如果原始卷指定了名称,它将不会被删除.

Security configuration

Option Description
--security-opt="label=user:USER" 为容器设置标签用户
--security-opt="label=role:ROLE" 为容器设置标签角色
--security-opt="label=type:TYPE" 设置容器的标签类型
--security-opt="label=level:LEVEL" 设置容器的标签级别
--security-opt="label=disable" 关闭容器的标签限制
--security-opt="apparmor=PROFILE" 设置要应用于容器的 apparmor 配置文件
--security-opt="no-new-privileges:true" 禁止容器进程获得新权限
--security-opt="seccomp=unconfined" 关闭容器的 seccomp 限制
--security-opt="seccomp=profile.json" 列入白名单的系统调用 seccomp Json 文件用作 seccomp 过滤器

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

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

Note

当前不支持自动翻译 MLS 标签.

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

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

如果您想对容器内的进程采取更严格的安全策略,您可以为容器指定替代类型. 您可以通过执行以下命令来运行只允许侦听 Apache 端口的容器:

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

Note

您必须编写定义svirt_apache_t类型的策略.

如果你想阻止你的容器进程获得额外的权限,你可以执行以下命令:

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

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

Specify an init process

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

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

Specify custom cgroups

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

Runtime constraints on resources

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

Option Description
-m, --memory="" 内存限制(格式: <number>[<unit>] ). 数字是一个正整数. 单位可以是bkmg之一. 最小为 4M.
--memory-swap="" 总内存限制(内存 + 交换,格式: <number>[<unit>] ). 数字是一个正整数. 单位可以是bkmg之一.
--memory-reservation="" Memory soft limit (format: <number>[<unit>]). Number is a positive integer. Unit can be one of b, k, m, or g.
--kernel-memory="" 内核内存限制(格式: <number>[<unit>] ). 数字是一个正整数. 单位可以是bkmg之一. 最小为 4M.
-c, --cpu-shares=0 CPU 份额(相对权重)
--cpus=0.000 CPU 数量. Number 是一个小数. 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="" 限制设备的读取速率(每秒 IO)(格式: <device-path>:<number> ). 数字是一个正整数.
--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 .

User memory constraints

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

Option Result
内存=inf,内存交换=inf (default) 容器没有内存限制. 容器可以根据需要使用尽可能多的内存.
内存=L<inf,内存交换=inf (指定 memory 并将 memory-swap 设置为-1 )不允许容器使用超过 L 字节的内存,但可以根据需要使用尽可能多的交换(如果主机支持交换内存).
内存=L<inf,内存交换=2*L (指定没有内存交换的内存)容器不允许使用超过 L 字节的内存,交换加上内存使用量是它的两倍.
内存=L<inf,内存交换=S<inf,L<=S (同时指定 memory 和 memory-swap)容器不允许使用超过 L 字节的内存,swap加上内存使用受 S 限制.

Examples:

$ 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)将设置为内存的两倍,在这种情况下,内存+ 交换将是 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

The container can use as much memory as it needs. The memory reservation setting ensures the container doesn’t consume too much memory for long time, because every memory reclaim shrinks the container’s consumption to the reservation.

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

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

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

The following example, illustrates a dangerous way to use the flag:

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

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

Kernel memory constraints

内核内存与用户内存根本不同,因为内核内存不能被换出. 无法交换使得容器有可能通过消耗过多的内核内存来阻塞系统服务. 内核内存包括:

  • 堆栈页面
  • 平板页面
  • 套接字内存压力
  • tcp内存压力

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

内核内存永远不会完全独立于用户内存. 相反,您在用户内存限制的上下文中限制内核内存. 假设"U"是用户内存限制,"K"是内核限制. 有三种可能的方法来设置限制:

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

Examples:

$ 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 内核内存.

Swappiness constraint

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

例如,您可以设置:

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

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

CPU share constraint

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

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

该比例仅适用于 CPU 密集型进程正在运行时. 当一个容器中的任务空闲时,其他容器可以使用剩余的 CPU 时间. 实际的 CPU 时间量将根据系统上运行的容器数量而有所不同.

例如,考虑三个容器,一个的 cpu-share 为 1024,另外两个的 cpu-share 设置为 512.当所有三个容器中的进程都尝试使用 100% 的 CPU 时,第一个容器将获得 50% 的总 CPU 时间. 如果添加第四个 cpu-share 为 1024 的容器,第一个容器仅获得 33% 的 CPU. 其余容器分别获得 16.5%、16.5% 和 33% 的 CPU.

在多核系统上,CPU 时间的份额分布在所有 CPU 内核上. 即使容器被限制为少于 100% 的 CPU 时间,它也可以使用 100% 的每个单独的 CPU 内核.

例如,考虑一个具有三个以上内核的系统. 如果使用-c=512启动一个容器{C0}运行一个进程,并启动另一个容器{C1}并使用-c=1024运行两个进程,这可能会导致以下 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 period constraint

默认的 CPU CFS(完全公平调度器)周期为 100 毫秒. 我们可以使用--cpu-period来设置 CPU 的周期来限制容器的 CPU 使用率. 通常--cpu-period应该与--cpu-quota一起使用.

Examples:

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

If there is 1 CPU, this means the container can get 50% CPU worth of run-time every 50ms.

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

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

有关详细信息,请参阅有关带​​宽限制的 CFS 文档.

Cpuset constraint

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

Examples:

$ 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 系统上有效.

Examples:

$ 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 quota constraint

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

Block IO bandwidth (Blkio) constraint

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

Note:

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在 a特定设备. 以下示例使用默认权重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]格式限制. 读取和写入速率都必须是正整数. 您可以以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>格式的限制. 读取和写入速率都必须是正整数.

Additional groups

--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

Runtime privilege and Linux capabilities

Option Description
--cap-add 添加 Linux 功能
--cap-drop 放弃 Linux 功能
--privileged 授予此容器扩展权限
--device=[] 允许您在没有 --privileged 标志的情况下在容器内运行设备.

默认情况下,Docker 容器是"无特权的",例如,不能在 Docker 容器内运行 Docker 守护程序. 这是因为默认情况下不允许容器访问任何设备,但"特权"容器可以访问所有设备(请参阅cgroups 设备上的文档).

--privileged 标志为容器提供所有功能. 当操作员执行docker run --privileged时,Docker 将启用对主机上所有设备的访问,并在 AppArmor 或 SELinux 中设置一些配置,以允许容器几乎与在主机上运行在容器外部的进程一样访问主机. Docker 博客上提供了有关使用--privileged运行的其他信息.

If you want to limit access to a specific device or devices you can use the --device flag. It allows you to specify one or more devices that will be accessible within the container.

$ 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 功能选项.

Capability Key 能力描述
AUDIT_WRITE 将记录写入内核审计日志.
CHOWN 对文件 UID 和 GID 进行任意更改(请参阅 chown(2)).
DAC_OVERRIDE 绕过文件读取、写入和执行权限检查.
FOWNER 绕过通常要求进程的文件系统 UID 与文件的 UID 匹配的操作的权限检查.
FSETID 修改文件时不要清除 set-user-ID 和 set-group-ID 权限位.
KILL 绕过发送信号的权限检查.
MKNOD 使用 mknod(2) 创建特殊文件.
NET_BIND_SERVICE 将套接字绑定到 Internet 域特权端口(端口号小于 1024).
NET_RAW 使用 RAW 和 PACKET 套接字.
SETFCAP 设置文件功能.
SETGID 对进程 GID 和补充 GID 列表进行任意操作.
SETPCAP 修改流程能力.
SETUID 对进程 UID 进行任意操作.
SYS_CHROOT 使用 chroot(2),更改根目录.

下表显示了默认情况下未授予但可以添加的功能.

能力密钥 能力描述
AUDIT_CONTROL 启用和禁用内核审计; 更改审计过滤规则; 检索审核状态和过滤规则.
AUDIT_READ 允许通过多播 netlink 套接字读取审计日志.
BLOCK_SUSPEND 允许防止系统挂起.
BPF 允许创建 BPF 映射、加载 BPF 类型格式 (BTF) 数据、检索 BPF 程序的 JITed 代码等等.
CHECKPOINT_RESTORE 允许检查点/恢复相关操作. 在内核 5.9 中引入.
DAC_READ_SEARCH 绕过文件读取权限检查和目录读取并执行权限检查.
IPC_LOCK 锁定内存(mlock(2)、mlockall(2)、mmap(2)、shmctl(2)).
IPC_OWNER 绕过对 System V IPC 对象的操作的权限检查.
LEASE 在任意文件上建立租约(参见 fcntl(2)).
LINUX_IMMUTABLE 设置 FS_APPEND_FL 和 FS_IMMUTABLE_FL 索引节点标志.
MAC_ADMIN 允许 MAC 配置或状态更改. 为 Smack LSM 实现.
MAC_OVERRIDE 覆盖强制访问控制 (MAC). 为 Smack Linux 安全模块 (LSM) 实施.
NET_ADMIN 执行各种网络相关操作.
NET_BROADCAST 制作套接字广播,并收听多播.
PERFMON 使用 perf_events、i915_perf 和其他内核子系统允许系统性能和可观察性特权操作
SYS_ADMIN 执行一系列系统管理操作.
SYS_BOOT 使用 reboot(2) 和 kexec_load(2),重新启动并加载新内核以供以后执行.
SYS_MODULE 加载和卸载内核模块.
SYS_NICE 提高进程 nice 值(nice(2)、setpriority(2))并更改任意进程的 nice 值.
SYS_PACCT 使用 acct(2),打开或关闭进程记帐.
SYS_PTRACE 使用 ptrace(2) 跟踪任意进程.
SYS_RAWIO 执行 I/O 端口操作(iopl(2) 和 ioperm(2)).
SYS_RESOURCE 覆盖资源限制.
SYS_TIME 设置系统时钟(settimeofday(2)、stime(2)、adjtimex(2)); 设置实时(硬件)时钟.
SYS_TTY_CONFIG 使用 vhangup(2); 在虚拟终端上使用各种特权 ioctl(2) 操作.
SYSLOG Perform privileged syslog(2) operations.
WAKE_ALARM 触发可以唤醒系统的东西.

更多参考信息可在功能 (7) - Linux 手册页Linux 内核源代码中找到.

这两个标志都支持值ALL ,因此允许容器使用除MKNOD之外的所有功能:

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

--cap-add--cap-drop标志接受使用CAP_前缀指定的功能. 因此,以下示例是等效的:

$ docker run --cap-add=SYS_ADMIN ...
$ docker run --cap-add=CAP_SYS_ADMIN ...

为了与网络堆栈交互,而不是使用--privileged他们应该使用--cap-add=NET_ADMIN来修改网络接口.

$ 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 配置文件将根据所选功能进行调整,以允许使用功能允许的设施,因此您不必对此进行调整.

Logging drivers (--log-driver)

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

Driver Description
none 禁用容器的任何日志记录. 此驱动程序不提供docker logs .
local 日志以设计用于最小开销的自定义格式存储.
json-file Docker 的默认日志记录驱动程序. 将 JSON 消息写入文件. 此驱动程序不支持任何日志记录选项.
syslog 用于 Docker 的 Syslog 日志记录驱动程序. 将日志消息写入 syslog.
journald 用于 Docker 的 Journald 日志记录驱动程序. 将日志消息写入journald .
gelf 用于 Docker 的 Graylog 扩展日志格式 (GELF) 日志记录驱动程序. 将日志消息写入 GELF 端点,如 Graylog 或 Logstash.
fluentd 用于 Docker 的 Fluentd 日志记录驱动程序. 将日志消息写入fluentd (转发输入).
awslogs 用于 Docker 的 Amazon CloudWatch Logs 日志记录驱动程序. 将日志消息写入 Amazon CloudWatch Logs.
splunk 用于 Docker 的 Splunk 日志记录驱动程序. 使用事件 Http 收集器将日志消息写入splunk .
etwlogs Windows 事件跟踪 (ETW) 事件. 将日志消息写入 Windows 事件跟踪 (ETW) 事件. 仅限 Windows 平台.
gcplogs 谷歌云平台 (GCP) 日志记录. 将日志消息写入 Google Cloud Platform (GCP) 日志记录.
logentries Rapid7 日志记录. 将日志消息写入 Rapid7 Logentries.

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

Overriding Dockerfile image defaults

当开发者从Dockerfile构建镜像或提交镜像时,开发者可以设置一些默认参数,这些参数在镜像作为容器启动时生效.

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

CMD (default command or options)

回忆一下 Docker 命令行中的可选COMMAND

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

此命令是可选的,因为创建IMAGE的人可能已经使用 Dockerfile CMD指令提供了默认COMMAND . 作为操作员(从映像运行容器的人),您可以通过指定新的COMMAND来覆盖该CMD指令.

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

ENTRYPOINT (default command to execute at runtime)

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

映像的ENTRYPOINT类似于COMMAND ,因为它指定容器启动时要运行的可执行文件,但(故意)更难以覆盖. 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

Note

传递--entrypoint将清除镜像上的任何默认命令集(即用于构建它的 Dockerfile 中的任何CMD指令).

EXPOSE (incoming ports)

以下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 (environment variables)

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

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

Variable Value
HOME 根据USER的值设置
HOSTNAME 与容器关联的主机名
PATH 包括流行的目录,例如/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TERM 如果为容器分配了伪 TTY,则为xterm

此外,操作员可以使用一个或多个-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).

HEALTHCHECK

  --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

Example:


$ 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 (mount tmpfs filesystems)

--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 (shared filesystems)

-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)

Note

当使用 systemd 管理 Docker 守护进程的启动和停止时,在 systemd 单元文件中有一个选项来控制 Docker 守护进程本身的挂载传播,称为MountFlags . 此设置的值可能会导致 Docker 看不到在挂载点上所做的挂载传播更改. 例如,如果此值为slave ,您可能无法在卷上使用sharedrshared传播.

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

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

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

例如,您可以为host-src值指定/foofoo . 如果您提供/foo值,Docker 会创建一个绑定挂载. 如果您提供foo规范,Docker 会创建一个命名卷.

USER

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 的范围内.

WORKDIR

在容器中运行二进制文件的默认工作目录是根目录 ( / ). 可以使用 Dockerfile WORKDIR命令设置不同的工作目录. 操作员可以通过以下方式覆盖它:

-w="", --workdir="": Working directory inside the container
docker, run, configure, runtime

by  icopy.site