文档】"/>
【翻译docker run的官方参考文档】
docker大部分的重要功能都在run命令中通过不同参数实现,后面要学习dockerfile,docker-compose中很多的选项其实也是这些参数一一对应,用翻译软件先自动翻译了官方docker run文档后重新修正自动翻译的错误之处,很多地方的修改属于个人理解。在这里记录下来,供不愿意直接看英文文档的小伙伴们参考。
如想对照原文参考 请访问 docker run reference
docker run 参考
Docker 在隔离的容器中运行进程。容器是在主机上运行的进程。主机可以是本地的或远程的。当操作符执行时docker 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
. 为避免使用sudo
该docker
命令,您的系统管理员可以创建一个名为的 Unix 组docker
并向其中添加用户。有关此配置的更多信息,请参阅适用于您的操作系统的 Docker 安装文档。
run专属选项
只有操作员(执行者docker run
)可以设置以下选项。
- 独立与前景
- 分离模式 (-d)
- 前台模式
- 容器标识
- 名称 (–name)
- PID当量
- IPC 设置 (–ipc)
- 网络设置
- 重启策略 (–restart)
- 清理 (–rm)
- 资源的运行时限制
- 运行时特权和 Linux 功能
分离模式与前台模式
启动 Docker 容器时,首先要决定是要在后台以“分离”模式还是默认前台模式运行容器:
-d=false: Detached mode: Run container in the background, print new container id
分离模式 (-d)
要以分离模式启动容器,您可以使用-d=true
或只是-d
选项。按照设计,容器在用于运行容器的根进程退出时以分离模式启动,除非您还指定了该--rm
选项。如果使用 -d
with --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 。您可以指定要连接到三个标准流 ( STDIN
, STDOUT
, STDERR
) 中的哪一个,如下所示:
$ 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
笔记
Linux 会特别对待在容器内作为 PID 1 运行的进程:它会忽略任何具有默认操作的信号。因此,进程将不会终止,SIGINT
或者SIGTERM
除非它被编码为这样做。
容器识别
姓名 (–name)
操作员可以通过三种方式识别容器:
标识符类型 | 示例值 |
---|---|
UUID 长标识符 | “f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778” |
UUID 短标识符 | “f78375b1c487” |
name | “邪恶的托勒密” |
UUID 标识符来自 Docker 守护进程。如果您没有使用该--name
选项分配容器名称,则守护程序会为您生成一个随机字符串名称。定义一个name
可以很方便地为容器添加含义。如果指定一个 name
,则可以在引用 Docker 网络中的容器时使用它。这适用于后台和前台 Docker 容器。
笔记
>
默认网桥网络上的容器必须链接以通过名称进行通信。
PID 等价物
最后,为了帮助实现自动化,您可以让 Docker 将容器 ID 写入您选择的文件中。这类似于某些程序可能会将其进程 ID 写入文件的方式(您已经将它们视为 PID 文件):
--cidfile="": Write the container ID to the file
镜像[:标签]
虽然严格来说这不是一种识别容器的方法,但您可以通过添加image[:tag]
到命令来指定要用于运行容器的镜像版本。例如,docker run ubuntu:14.04
。
镜像[@digest]
使用 v2 或更高版本图像格式的镜像具有称为摘要的内容可寻址标识符。只要用于生成镜像的输入不变,摘要值就是可预测和可参考的。
以下示例从alpine
具有sha256:9cacb71397b640eca97488cf08582ae4e4068513101088e9f96c9814bfda95e0
摘要的图像 运行容器:
$ 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。
在某些情况下,您希望容器共享主机的进程命名空间,基本上允许容器内的进程查看系统上的所有进程。例如,您可以使用strace
或 之类的调试工具构建容器gdb
,但希望在调试容器内的进程时使用这些工具。
示例:在容器内运行 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 (UNIX Time-sharing System )命名空间设置 (–uts)
--uts="" : Set the UTS namespace mode for the container,'host': use the host's UTS namespace inside the container
看英文字面意思应该是unix时间共享系统,但是却是一个命名空间的选项设置,UTS 命名空间用于设置主机名和对该命名空间中运行的进程可见的域。默认情况下,所有容器,包括带有–network=host 的容器都有自己的 UTS 命名空间。该
host设置将导致容器使用与主机相同的 UTS 命名空间。注意
–hostname和
–domainname在
host`UTS 模式下无效。
如果您希望容器的主机名随着主机的主机名更改而更改,您可能希望与主机共享 UTS 命名空间。更高级的用例是从容器更改主机的主机名。
IPC 内存设置 (–ipc)
--ipc="MODE" : Set the IPC mode for the container
接受以下值:
价值 | 描述 |
---|---|
”” | 使用守护进程的默认值。 |
“none” | 自己的私有 IPC 命名空间,没有挂载 /dev/shm。 |
“private” | 拥有私有 IPC 命名空间。 |
“shareable” | 拥有私有 IPC 命名空间,可以与其他容器共享。 |
“container:” | 加入另一个(“可共享”)容器的 IPC 命名空间。 |
“host” | 使用主机系统的 IPC 命名空间。 |
如果未指定,则使用守护程序默认值,可以是"private"
或"shareable"
,具体取决于守护程序版本和配置。
IPC (POSIX/SysV IPC) 命名空间提供了命名共享内存段、信号量和消息队列的分离。
共享内存段用于以内存速度加速进程间通信,而不是通过管道或网络堆栈。共享内存通常被用于科学计算和金融服务行业的数据库和定制(通常是 C/OpenMPI、C++/使用 boost 库)高性能应用程序使用。如果这些类型的应用程序被分成多个容器,您可能需要共享容器的 IPC 机制,使用"shareable"
主(即“捐赠者”)容器和"container:"
其他容器的模式。
–network 网络设置
--dns=[] : Set custom dns servers for the container #为容器设置自定义dns服务器
--network="bridge" : Connect a container to a network #将容器连接到网络'bridge': create a network stack on the default Docker bridge #在默认Docker网桥上创建网络堆栈'none': no networking #无网络'container:<name|id>': reuse another container's network stack #重用另一个容器的网络堆栈'host': use the Docker host network stack #使用Docker主机网络堆栈'<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) #向/etc/hosts(主机:IP)添加一行
--mac-address="" : Sets the container's Ethernet device's MAC address # 设置容器的以太网设备的mac地址
--ip="" : Sets the container's Ethernet device's IPv4 address #设置容器的以太网设备的IPv4地址
--ip6="" : Sets the container's Ethernet device's IPv6 address #设置容器的以太网设备的IPv6地址
--link-local-ip=[] : Sets one or more container's Ethernet device's link local IPv4/IPv6 addresses #设置一个或多个容器的以太网设备的链路本地IPv4/IPv6地址
默认情况下,所有容器都启用了网络,并且它们可以进行任何传出连接。操作员可以完全禁用网络,docker run --network none
从而禁用所有传入和传出的网络。在这样的情况下,您将通过文件或执行I / O STDIN
和STDOUT
唯一的。
发布端口和链接到其他容器仅适用于默认值(网桥)。链接功能是遗留功能。与链接相比,您应该始终更喜欢使用 Docker 网络驱动程序。
默认情况下,您的容器将使用与主机相同的 DNS 服务器,但您可以使用--dns
.
默认情况下,MAC 地址是使用分配给容器的 IP 地址生成的。您可以通过--mac-address
参数(格式12:34:56:78:9a:bc
:)提供 MAC 地址来显式设置容器的 MAC 地址。请注意,Docker 不会检查手动指定的 MAC 地址是否唯一。
支持的网络:
网络 | 描述 |
---|---|
none | 容器中没有网络。 |
bridge(默认) | 通过 veth 接口将容器连接到网桥。 |
host | 在容器内使用主机的网络堆栈。 |
container: | 使用另一个容器的网络堆栈,通过其名称或id指定。 |
NETWORK | 将容器连接到用户创建的网络(使用docker network create 命令) |
–network="none"模式
具有网络none
的容器将无法访问任何外部路由。容器仍将loopback
在容器中启用一个 接口,但它没有任何通往外部流量的路由。
–network="bridge"模式
将网络设置为bridge
容器将使用 docker 的默认网络设置。在主机上设置了一个网桥,通常命名为 docker0
,并且veth
将为容器创建一对接口。该veth
对的一侧将保留在连接到网桥的主机上,而该对的另一侧将放置在除了loopback
接口之外的容器的命名空间内。将为网桥网络上的容器分配 IP 地址,流量将通过此网桥路由到容器。
默认情况下,容器可以通过其 IP 地址进行通信。要按名称进行通信,必须将它们链接起来。
–network="host"模式
将网络设置为host
容器将共享主机的网络堆栈,并且来自主机的所有接口都可用于容器。容器的主机名将与主机系统上的主机名匹配。注意--mac-address
在host
网络模式下无效。即使在host
网络模式下,容器默认也有自己的 UTS 命名空间。作为这种 --hostname
和--domainname
在被允许host
的网络模式,因此仅改变容器内的主机名和域名。类似--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,因此被认为是不安全的。
–network=container模式
将网络设置为container
一个容器将共享另一个容器的网络堆栈。另一个容器的名称必须以--network container:
. 注意--add-host
--hostname
--dns
--dns-search
--dns-option
和--mac-address
在container
网络模式下--publish
--publish-all
--expose
无效,在container
网络模式下也无效。
示例运行具有 Redis 绑定的 Redis 容器,localhost
然后运行redis-cli
命令并通过localhost
接口连接到 Redis 服务器 。
$ docker run -d --name redis6379 example/redis --bind 127.0.0.1
$ # use the redis container's network stack to access localhost
$ docker run --rm -it --network container:redis6379 example/redis 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
管理 /etc/hosts
您的容器将包含/etc/hosts
定义容器本身的主机名以及localhost
其他一些常见内容的行。该 --add-host
标志可用于向/etc/hosts
.
$ docker run -it --add-host db-static:86.75.30.9 ubuntu cat /etc/hosts172.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
文件或不完整文件的情况。在大多数情况下,再次重试读取应该可以解决问题。
重启策略 (–restart)
使用--restart
Docker 运行上的标志,您可以指定一个重启策略,用于在退出时应该或不应该重新启动容器。
当重新启动策略是活性的容器上,它将被显示为任一Up
或Restarting
在docker ps
。用于docker events
查看生效的重启策略也很有用。
Docker 支持以下重启策略:
政策 | 结果 |
---|---|
不 | 容器退出时不要自动重启容器。这是默认设置。 |
失败时[:max-retries] | 仅当容器以非零退出状态退出时才重新启动。(可选)限制 Docker 守护程序尝试重新启动的次数。 |
总是 | 无论退出状态如何,始终重新启动容器。当您指定 always 时,Docker 守护进程将尝试无限期地重新启动容器。无论容器的当前状态如何,容器也将始终在守护程序启动时启动。 |
除非停止 | 无论退出状态如何,始终重启容器,包括守护进程启动时,除非容器在 Docker 守护进程停止之前进入停止状态。 |
每次重新启动之前都会增加一个增加的延迟(前一个延迟的两倍,从 100 毫秒开始),以防止服务器泛滥。这意味着守护程序将等待 100 毫秒,然后是 200 毫秒、400、800、1600 毫秒,依此类推,直到达到on-failure
限制、1 分钟的最大延迟或您docker stop
或docker 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
(清理)标志的示例。
例子
$ docker run --restart=always redis
这将redis
使用始终重启策略运行容器, 以便如果容器退出,Docker 将重启它。
$ docker run --restart=on-failure:10 redis
这将redis
使用on-failure重启策略 和最大重启次数 10 运行redis
容器。如果容器以非零退出状态退出超过 10 次,Docker 将中止尝试重启容器。提供最大重启限制仅对on-failure策略有效 。
exit code(退出状态)
退出代码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(安全配置)
选项 | 描述 |
---|---|
--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
笔记
>
目前不支持 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
这意味着提高诸如su
或等特权的命令sudo
将不再起作用。它还会导致稍后应用任何 seccomp 过滤器,在删除权限后,这可能意味着您可以拥有一组更严格的过滤器。有关更多详细信息,请参阅内核文档。
指定一个init进程
您可以使用该--init
标志来指示应将 init 进程用作容器中的 PID 1。指定 init 进程可确保 init 系统的通常职责(例如收割僵尸进程)在创建的容器内执行。
使用的默认 init 进程是docker-init
在 Docker 守护进程的系统路径中找到的第一个可执行文件。这个docker-init
二进制文件包含在默认安装中,由tini支持。
指定自定义 cgroup
使用该--cgroup-parent
标志,您可以传递特定的 cgroup 以在其中运行容器。这允许您自行创建和管理 cgroup。您可以为这些 cgroup 定义自定义资源,并将容器放在一个公共父组下。
资源的运行时限制
操作人员还可以调整容器的性能参数:
选项 | 描述 |
---|---|
-m , --memory="" | 内存限制(格式:)[] 。数字是一个正整数。单位可以是一个b ,k ,m ,或g 。最小为 4M。 |
--memory-swap="" | 总内存限制(内存 + 交换,格式:)[] 。数字是一个正整数。单位可以是一个b ,k ,m ,或g 。 |
--memory-reservation="" | 内存软限制(格式:)[] 。数字是一个正整数。单位可以是一个b ,k ,m ,或g 。 |
--kernel-memory="" | 内核内存限制(格式:)[] 。数字是一个正整数。单位可以是一个b ,k ,m ,或g 。最小为 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="" | 限制设备的读取速率(格式:):[] 。数字是一个正整数。单位可以是一个kb ,mb 或gb 。 |
--device-write-bps="" | 限制写入设备的速率(格式:):[] 。数字是一个正整数。单位可以是一个kb ,mb 或gb 。 |
--device-read-iops="" | 限制设备的读取速率(每秒 IO)(格式:): 。数字是一个正整数。 |
--device-write-iops="" | 限制设备的写入速率(每秒 IO)(格式:): 。数字是一个正整数。 |
--oom-kill-disable=false | 是否为容器禁用 OOM Killer。 |
--oom-score-adj=0 | 调整容器的 OOM 首选项(-1000 到 1000) |
--memory-swappiness="" | 调整容器的内存交换行为。接受 0 到 100 之间的整数。 |
--shm-size="" | 的大小/dev/shm 。格式为``. number 必须大于0 。单位是可选的,可以是b (字节)、k (千字节)、m (兆字节)或g (千兆字节)。如果省略单位,系统将使用字节。如果完全省略大小,系统将使用64m . |
用户内存限制
我们有四种设置用户内存使用的方法:
选项 | 结果 |
---|---|
内存=inf,内存交换=inf(默认) | 容器没有内存限制。容器可以根据需要使用尽可能多的内存。 |
内存=L<inf,内存交换=inf | (指定内存并将内存交换设置为-1 )容器不允许使用超过 L 字节的内存,但可以根据需要使用尽可能多的交换(如果主机支持交换内存)。 |
内存=L<inf,内存交换=2*L | (指定内存不带memory-swap)容器不允许使用超过L字节的内存,swap加内存使用量是它的两倍。 |
内存=L<inf,内存交换=S<inf,L<=S | (同时指定memory和memory-swap)容器不允许使用超过L字节的内存,swap加内存使用受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)将设置为内存的两倍,在这种情况下,内存+ 交换将是 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”是内核限制。设置限制的方法有以下三种:
选项 | 结果 |
---|---|
U != 0, K = inf(默认) | 这是在使用内核内存之前已经存在的标准内存限制机制。内核内存被完全忽略。 |
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 内核内存。
约束
默认情况下,容器的内核可以换出一定比例的匿名页面。要为容器设置此百分比,请指定一个--memory-swappiness
介于 0 和 100 之间的值。值 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-share 为 1024,另外两个的 cpu-share 设置为 512。当所有三个容器中的进程都尝试使用 100% 的 CPU 时,第一个容器将获得 50% 的 CPU总 CPU 时间。如果添加 cpu-share 为 1024 的第四个容器,则第一个容器仅获得 33% 的 CPU。其余容器分别获得 16.5%、16.5% 和 33% 的 CPU。
在多核系统上,CPU 时间份额分布在所有 CPU 内核上。即使容器被限制在少于 100% 的 CPU 时间,它也可以使用 100% 的每个单独的 CPU 内核。
例如,考虑具有三个以上内核的系统。如果你开始一个容器{C0}
与-c=512
运行的一个过程,而另一个容器 {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周期限制
默认 CPU CFS(完全公平调度程序)周期为 100 毫秒。我们可以通过 --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 约束
我们可以设置允许容器执行的 CPU。
例子:
$ 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 权重设置仅适用于直接 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
如果您同时指定 the--blkio-weight
和--blkio-weight-device
,Docker 将使用 the--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
标志限制了设备的读取速率(每秒字节数)。例如,此命令创建一个容器并将读取速率限制为1mb
每秒/dev/sda
:
$ docker run -it --device-read-bps /dev/sda:1mb ubuntu
该--device-write-bps
标志限制了设备的写入速率(每秒字节数)。例如,此命令创建一个容器并将写入速率限制为1mb
每秒/dev/sda
:
$ docker run -it --device-write-bps /dev/sda:1mb ubuntu
两个标志在:[unit]
格式上都有限制。读取和写入速率都必须是正整数。您可以以kb
(千字节)、mb
(兆字节)或gb
(千兆字节)为单位指定速率。
该--device-read-iops
标志限制了设备的读取速率(每秒 IO)。例如,此命令创建一个容器并将读取速率限制为每秒 1000
IO /dev/sda
:
$ docker run -ti --device-read-iops /dev/sda:1000 ubuntu
该--device-write-iops
标志限制了设备的写入速率(每秒 IO)。例如,此命令创建一个容器并将1000
每秒 IO的写入速率限制 为/dev/sda
:
$ docker run -ti --device-write-iops /dev/sda:1000 ubuntu
两个标志在:
格式上都有限制。读取和写入速率都必须是正整数。
–group-add
--group-add: Add additional groups to run as
默认情况下,docker 容器进程与为指定用户查找的补充组一起运行。如果想要向该组列表添加更多,则可以使用此标志:
$ docker run --rm --group-add audio --group-add nogroup --group-add 777 busybox iduid=0(root) gid=0(root) groups=10(wheel),29(audio),99(nogroup),777
运行时特权和 Linux 功能
选项 | 描述 |
---|---|
--cap-add | 添加 Linux 功能 |
--cap-drop | 删除 Linux 功能 |
--privileged | 授予此容器扩展权限 |
--device=[] | 允许您在没有 --privileged 标志的情况下在容器内运行设备。 |
默认情况下,Docker 容器是“无特权的”,例如,不能在 Docker 容器内运行 Docker 守护程序。这是因为默认情况下不允许容器访问任何设备,但“特权”容器可以访问所有设备(请参阅有关cgroups 设备的文档)。
当操作符执行时docker run --privileged
,Docker 将启用对主机上所有设备的访问,并在 AppArmor 或 SELinux 中设置一些配置,以允许容器几乎与在主机上容器外运行的进程一样访问主机。Docker 博客--privileged
上提供了 有关 running with 的其他信息。
如果您想限制对特定设备的访问,您可以使用该--device
标志。它允许您指定一个或多个可在容器内访问的设备。
$ docker run --device=/dev/snd:/dev/snd ...
默认情况下,容器就可以read
,write
和mknod
这些设备。这可以使用:rwm
每个--device
标志的第三组选项覆盖:
$ docker run --device=/dev/sda:/dev/xvdc --rm -it ubuntu fdisk /dev/xvdcCommand (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/xvdccrash....$ 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 功能选项。
功能键 | 能力描述 |
---|---|
审计_写 | 将记录写入内核审计日志。 |
周恩 | 对文件 UID 和 GID 进行任意更改(请参阅 chown(2))。 |
DAC_OVERRIDE | 绕过文件读取、写入和执行权限检查。 |
福纳 | 绕过通常需要进程的文件系统 UID 与文件的 UID 匹配的操作的权限检查。 |
FSETID | 修改文件时不要清除 set-user-ID 和 set-group-ID 权限位。 |
杀 | 绕过发送信号的权限检查。 |
MKNOD | 使用 mknod(2) 创建特殊文件。 |
NET_BIND_SERVICE | 将套接字绑定到 Internet 域特权端口(端口号小于 1024)。 |
NET_RAW | 使用 RAW 和 PACKET 套接字。 |
SETFCAP | 设置文件能力。 |
设置标识符 | 对进程 GID 和补充 GID 列表进行任意操作。 |
SETPCAP | 修改过程能力。 |
SETUID | 对进程 UID 进行任意操作。 |
SYS_CHROOT | 使用 chroot(2),更改根目录。 |
下表显示了默认情况下未授予但可以添加的功能。
功能键 | 能力描述 |
---|---|
审计_控制 | 启用和禁用内核审计;更改审计过滤规则;检索审计状态和过滤规则。 |
AUDIT_READ | 允许通过多播 netlink 套接字读取审计日志。 |
BLOCK_SUSPEND | 允许防止系统挂起。 |
BPF | 允许创建 BPF 映射、加载 BPF 类型格式 (BTF) 数据、检索 BPF 程序的 JIT 代码等等。 |
CHECKPOINT_RESTORE | 允许检查点/恢复相关操作。在内核 5.9 中引入。 |
DAC_READ_SEARCH | 绕过文件读取权限检查和目录读取和执行权限检查。 |
IPC_LOCK | 锁定内存(mlock(2)、mlockall(2)、mmap(2)、shmctl(2))。 |
IPC_所有者 | 绕过对 System V IPC 对象操作的权限检查。 |
租 | 在任意文件上建立租约(请参阅 fcntl(2))。 |
LINUX_IMMUTABLE | 设置 FS_APPEND_FL 和 FS_IMMUTABLE_FL i-node 标志。 |
MAC_管理员 | 允许 MAC 配置或状态更改。为 Smack LSM 实现。 |
MAC_OVERRIDE | 覆盖强制访问控制 (MAC)。为 Smack Linux 安全模块 (LSM) 实现。 |
网络管理员 | 执行各种与网络相关的操作。 |
网络广播 | 进行套接字广播,并收听多播。 |
性能 | 允许使用 perf_events、i915_perf 和其他内核子系统的系统性能和可观察性特权操作 |
系统管理员 | 执行一系列系统管理操作。 |
SYS_BOOT | 使用reboot(2) 和kexec_load(2),重新启动并加载新内核供以后执行。 |
系统模块 | 加载和卸载内核模块。 |
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 | 覆盖资源限制。 |
系统时间 | 设置系统时钟(settimeofday(2), stime(2), adjtimex(2)); 设置实时(硬件)时钟。 |
SYS_TTY_CONFIG | 使用 vhangup(2); 在虚拟终端上使用各种特权 ioctl(2) 操作。 |
系统日志 | 执行特权 syslog(2) 操作。 |
WAKE_ALARM | 触发一些会唤醒系统的东西。 |
更多参考信息可在capabilities(7) - Linux 手册页和Linux 内核源代码中找到。
两个标志都支持 value ALL
,因此允许容器使用除以下以外的所有功能MKNOD
:
$ docker run --cap-add=ALL --cap-drop=MKNOD ...
```bash在`--cap-add`和`--cap-drop`同一个指定的能力的标志接受`CAP_`前缀。因此,以下示例是等效的:```bash
$ 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 dummyRTNETLINK 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 /mntfuse: failed to open /dev/fuse: Operation not permitted$ docker run --rm -it --device /dev/fuse sshfs sshfs sven@10.10.10.20:/home/sven /mntfusermount: 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/dockertotal 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 配置文件将调整到选定的功能,以允许使用功能允许的设施,因此您不必调整它。
驱动日志 (–log-driver)
容器可以具有与 Docker 守护进程不同的日志驱动程序。--log-driver=VALUE
与docker run
命令一起使用来配置容器的日志记录驱动程序。支持以下选项:
司机 | 描述 |
---|---|
none | 禁用容器的任何日志记录。docker logs 此驱动程序将不可用。 |
json-file | Docker 的默认日志驱动程序。将 JSON 消息写入文件。此驱动程序不支持日志记录选项。 |
syslog | Docker 的 Syslog 日志驱动程序。将日志消息写入 syslog。 |
journald | 用于 Docker 的日志记录驱动程序。将日志消息写入journald . |
gelf | 用于 Docker 的 Graylog 扩展日志格式 (GELF) 日志记录驱动程序。将日志消息写入 GELF 端点,如 Graylog 或 Logstash。 |
fluentd | 用于 Docker 的 Fluentd 日志驱动程序。将日志消息写入fluentd (转发输入)。 |
awslogs | 用于 Docker 的 Amazon CloudWatch Logs 日志记录驱动程序。将日志消息写入 Amazon CloudWatch Logs |
splunk | 用于 Docker 的 Splunk 日志驱动程序。splunk 使用事件 Http 收集器写入日志消息。 |
该docker logs
命令仅适用于json-file
和journald
日志驱动程序。有关使用日志驱动程序的详细信息,请参阅 配置日志驱动程序。
覆盖 Dockerfile 镜像默认值
当开发人员从Dockerfile构建映像 或提交映像时,开发人员可以设置许多默认参数,这些参数在映像作为容器启动时生效。
在Dockerfile命令的四个不能在运行时被覆盖:FROM
, MAINTAINER
,RUN
,和ADD
。其他所有内容在docker run
. 我们将介绍开发人员可能在每个 Dockerfile 指令中设置的内容以及操作员如何覆盖该设置。
- CMD(默认命令或选项)
- ENTRYPOINT(在运行时执行的默认命令)
- EXPOSE(传入端口)
- ENV(环境变量)
- 健康检查
- 卷(共享文件系统)
- 用户
- 工作目录
CMD(默认命令或选项)
回想一下COMMAND
Docker 命令行中的可选项:
$ docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
此命令是可选的,因为创建者IMAGE
可能已经COMMAND
使用 DockerfileCMD
指令提供了默认值。作为操作员(从镜像运行容器的人),您CMD
只需指定一个新的 COMMAND
.
如果图像还指定了 ,ENTRYPOINT
则CMD
或COMMAND
将作为参数附加到ENTRYPOINT
.
ENTRYPOINT(运行时执行的默认命令)
--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
笔记
>
传递--entrypoint
将清除图像上设置的任何默认命令(即CMD
用于构建它的 Dockerfile 中的任何指令)。
–EXPOSE(传入端口)
以下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 hostformat: ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort | containerPortBoth hostPort and containerPort can be specified as arange of ports. When specifying ranges for both, thenumber of container ports in the range must match thenumber of host ports in the range, for example:-p 1234-1236:1234-1236/tcpWhen specifying a range for hostPort only, thecontainerPort must not be a range. In this case thecontainer port is published somewhere within thespecified 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(因此镜像开发人员EXPOSE 80
在 Dockerfile 中指定)。在运行时,端口可能绑定到主机上的 42800。要查找主机端口和公开端口之间的映射,请使用docker port
.
如果运营商--link
在默认桥接网络中启动新的客户端容器时使用,那么客户端容器可以通过私有网络接口访问暴露的端口。如果--link
在用户定义的网络中启动容器时使用,如网络概述 中所述,它将为所链接的容器提供命名别名。
–ENV(环境变量)
Docker 在创建 Linux 容器时会自动设置一些环境变量。Docker 在创建 Windows 容器时不会设置任何环境变量。
为 Linux 容器设置了以下环境变量:
多变的 | 价值 |
---|---|
HOME | 根据值设置 USER |
HOSTNAME | 与容器关联的主机名 |
PATH | 包括流行的目录,例如 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
TERM | xterm 如果容器被分配了一个伪 TTY |
此外,操作员可以通过使用一个或多个标志来设置容器中的任何环境变量-e
,甚至可以覆盖上面提到的那些,或者已经由开发人员使用 Dockerfile 定义的ENV
。如果操作符命名环境变量而不指定值,则命名变量的当前值将传播到容器的环境中:
$ export today=Wednesday
$ docker run -e "deep=purple" -e today --rm alpine envPATH=/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
同样,运营商可以设置HOSTNAME(Linux)或计算机名(Windows)驱动-h
。
–health(健康)
--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.
下面安装一个空的tmpfs与容器中的例子rw
, noexec
,nosuid
,和size=65536k
选项。
$ 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
,则您可能无法在卷上使用shared
或rshared
传播。
卷命令非常复杂,在volumes部分有自己的文档。开发人员可以定义一个或多个VOLUME
与映像相关联的 ,但只有操作员可以授予从一个容器到另一个容器(或从容器到安装在主机上的卷)的访问权限。
在container-dest
必须始终是绝对路径,例如/src/docs
。的host-src
可以是一个绝对路径或name
值。如果您为 提供绝对路径host-src
,Docker 将绑定安装到您指定的路径。如果你提供了name
,Docker 会通过它创建一个命名卷name
。
甲name
值必须以字母数字字符,接着启动a-z0-9
,_
(下划线), .
(周期)或-
(连字符)。绝对路径以/
(正斜杠)开头。
例如,您可以指定/foo
或foo
一个host-src
值。如果您提供该/foo
值,Docker 会创建一个绑定挂载。如果您提供foo
规范,Docker 会创建一个命名卷。
–user(用户)
root
(id = 0) 是容器内的默认用户。图像开发人员可以创建其他用户。这些用户可以通过名称访问。传递数字 ID 时,用户不必存在于容器中。
开发者可以通过 DockerfileUSER
指令设置一个默认用户来运行第一个进程。启动容器时,操作员可以USER
通过传递-u
选项来覆盖指令。
-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(工作目录)
在容器中运行二进制文件的默认工作目录是根目录 ( /
)。可以使用 DockerfileWORKDIR
命令设置不同的工作目录。操作员可以使用以下方法覆盖它:
-w="", --workdir="": Working directory inside the container
更多推荐
【翻译docker run的官方参考文档】
发布评论