docker container run
描述 | 从镜像创建并运行一个新的容器 |
---|---|
用法 | docker container run [OPTIONS] IMAGE [COMMAND] [ARG...] |
别名 | docker run |
描述
docker run
命令在一个新的容器中运行命令,如果需要则拉取镜像并启动容器。
您可以使用 docker start
重启已停止的容器,并保留其所有之前的更改。 使用 docker ps -a
查看所有容器的列表,包括已停止的容器。
选项
选项 | 默认值 | 描述 |
---|---|---|
--add-host | 添加自定义主机到IP映射 (host:ip) | |
--annotation | API 1.43+ 向容器添加注释(传递到OCI运行时) | |
-a, --attach | 附加到 STDIN、STDOUT 或 STDERR | |
--blkio-weight | 块IO(相对权重),介于10和1000之间,或0以禁用(默认值0) | |
--blkio-weight-device | 块IO权重(相对设备权重) | |
--cap-add | 添加Linux功能 | |
--cap-drop | 删除Linux功能 | |
--cgroup-parent | 容器的可选父cgroup | |
--cgroupns | API 1.41+ 要使用的cgroup命名空间 (host|private) 'host':在Docker主机的cgroup命名空间中运行容器 'private':在它自己的专用cgroup命名空间中运行容器 '': 使用守护程序上配置的cgroup命名空间, 由default-cgroupns-mode选项配置 (默认) | |
--cidfile | 将容器ID写入文件 | |
--cpu-count | CPU数量(仅限Windows) | |
--cpu-percent | CPU百分比(仅限Windows) | |
--cpu-period | 限制CPU CFS(完全公平调度器)周期 | |
--cpu-quota | 限制CPU CFS(完全公平调度器)配额 | |
--cpu-rt-period | API 1.25+ 以微秒为单位限制CPU实时周期 | |
--cpu-rt-runtime | API 1.25+ 以微秒为单位限制CPU实时运行时间 | |
-c, --cpu-shares | CPU份额(相对权重) | |
--cpus | API 1.25+ CPU数量 | |
--cpuset-cpus | 允许执行的CPU (0-3, 0,1) | |
--cpuset-mems | 允许执行的MEM (0-3, 0,1) | |
-d, --detach | 在后台运行容器并打印容器ID | |
--detach-keys | 覆盖分离容器的键序列 | |
--device | 向容器添加主机设备 | |
--device-cgroup-rule | 向cgroup允许的设备列表添加规则 | |
--device-read-bps | 限制从设备读取速率(每秒字节数) | |
--device-read-iops | 限制从设备读取速率(每秒IO次数) | |
--device-write-bps | 限制写入到设备的速率(每秒字节数) | |
--device-write-iops | 限制写入到设备的速率(每秒IO次数) | |
--disable-content-trust | true | 跳过镜像验证 |
--dns | 设置自定义DNS服务器 | |
--dns-option | 设置DNS选项 | |
--dns-search | 设置自定义DNS搜索域 | |
--domainname | 容器NIS域名 | |
--entrypoint | 覆盖镜像的默认ENTRYPOINT | |
-e, --env | 设置环境变量 | |
--env-file | 读取环境变量文件 | |
--expose | 公开端口或端口范围 | |
--gpus | API 1.40+ 要添加到容器的GPU设备('all'表示传递所有GPU) | |
--group-add | 添加要加入的其他组 | |
--health-cmd | 要运行以检查运行状况的命令 | |
--health-interval | 运行检查之间的时间间隔 (ms|s|m|h) (默认 0s) | |
--health-retries | 需要连续失败才能报告不健康 | |
--health-start-interval | API 1.44+ 启动期间运行检查之间的时间间隔 (ms|s|m|h) (默认 0s) | |
--health-start-period | API 1.29+ 容器在启动健康检查倒计时之前进行初始化的启动周期 (ms|s|m|h) (默认 0s) | |
--health-timeout | 允许一次检查运行的最长时间 (ms|s|m|h) (默认 0s) | |
--help | 打印使用说明 | |
-h, --hostname | 容器主机名 | |
--init | API 1.25+ 在容器内运行一个init进程,它可以转发信号并清理进程 | |
-i, --interactive | 即使未附加,也保持STDIN打开 | |
--io-maxbandwidth | 系统驱动器的最大IO带宽限制(仅限Windows) | |
--io-maxiops | 系统驱动器的最大IOps限制(仅限Windows) | |
--ip | IPv4地址(例如,172.30.100.104) | |
--ip6 | IPv6地址(例如,2001:db8::33) | |
--ipc | 要使用的IPC模式 | |
--isolation | 容器隔离技术 | |
--kernel-memory | 内核内存限制 | |
-l, --label | 设置容器的元数据 | |
--label-file | 读取标签的行分隔文件 | |
--link | 添加对另一个容器的链接 | |
--link-local-ip | 容器IPv4/IPv6本地链路地址 | |
--log-driver | 容器的日志驱动程序 | |
--log-opt | 日志驱动程序选项 | |
--mac-address | 容器MAC地址(例如,92:d0:c6:0a:29:33) | |
-m, --memory | 内存限制 | |
--memory-reservation | 内存软限制 | |
--memory-swap | 交换空间限制等于内存加交换空间:'-1' 表示启用无限交换空间 | |
--memory-swappiness | -1 | 调整容器内存交换率 (0 到 100) |
--mount | 将文件系统挂载附加到容器 | |
--name | 为容器分配名称 | |
--network | 将容器连接到网络 | |
--network-alias | 为容器添加网络范围别名 | |
--no-healthcheck | 禁用任何容器指定的HEALTHCHECK | |
--oom-kill-disable | 禁用OOM Killer | |
--oom-score-adj | 调整主机的OOM首选项 (-1000 到 1000) | |
--pid | 要使用的PID命名空间 | |
--pids-limit | 调整容器pids限制(设置为-1表示无限) | |
--platform | API 1.32+ 如果服务器支持多平台,则设置平台 | |
--privileged | 赋予此容器扩展权限 | |
-p, --publish | 将容器的端口发布到主机 | |
-P, --publish-all | 将所有公开端口发布到随机端口 | |
--pull | missing | 运行前拉取镜像 (always , missing , never ) |
-q, --quiet | 抑制拉取输出 | |
--read-only | 以只读方式挂载容器的根文件系统 | |
--restart | no | 容器退出时要应用的重启策略 |
--rm | 容器退出时自动删除容器及其关联的匿名卷 | |
--runtime | 要为此容器使用的运行时 | |
--security-opt | 安全选项 | |
--shm-size | /dev/shm 的大小 | |
--sig-proxy | true | 将接收到的信号代理到进程 |
--stop-signal | 停止容器的信号 | |
--stop-timeout | API 1.25+ 停止容器的超时时间(以秒为单位) | |
--storage-opt | 容器的存储驱动程序选项 | |
--sysctl | Sysctl选项 | |
--tmpfs | 挂载一个tmpfs目录 | |
-t, --tty | 分配一个伪TTY | |
--ulimit | Ulimit选项 | |
-u, --user | 用户名或UID(格式:<name|uid>[:<group|gid>]) | |
--userns | 要使用的用户命名空间 | |
--uts | 要使用的UTS命名空间 | |
-v, --volume | 绑定挂载卷 | |
--volume-driver | 容器的可选卷驱动程序 | |
--volumes-from | 从指定的容器挂载卷 | |
-w, --workdir | 容器内的工作目录 |
示例
分配名称(--name)
--name
标志允许您为容器指定自定义标识符。以下示例使用 分离模式 中的 nginx:alpine
镜像运行名为 test
的容器。
$ docker run --name test -d nginx:alpine
4bed76d3ad428b889c56c1ecc2bf2ed95cb08256db22dc5ef5863e1d03252a19
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bed76d3ad42 nginx:alpine "/docker-entrypoint.…" 1 second ago Up Less than a second 80/tcp test
您可以使用其他命令按名称引用容器。例如,以下命令停止并删除名为 test
的容器
$ docker stop test
test
$ docker rm test
test
如果您没有使用 --name
标志指定自定义名称,守护进程会为容器分配一个随机生成的名称,例如 vibrant_cannon
。使用自定义名称的好处是可以拥有易于记住的容器 ID。
此外,如果您将容器连接到用户定义的桥接网络,则同一网络上的其他容器可以通过 DNS 按名称引用该容器。
$ docker network create mynet
cb79f45948d87e389e12013fa4d969689ed2c3316985dd832a43aaec9a0fe394
$ docker run --name test --net mynet -d nginx:alpine
58df6ecfbc2ad7c42d088ed028d367f9e22a5f834d7c74c66c0ab0485626c32a
$ docker run --net mynet busybox:latest ping test
PING test (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.073 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.411 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.319 ms
64 bytes from 172.18.0.2: seq=3 ttl=64 time=0.383 ms
...
捕获容器 ID (--cidfile)
为了帮助自动化,您可以让 Docker 将容器 ID 写入您选择的某个文件中。这类似于某些程序如何将其进程 ID 写入文件(您可能见过它们作为 PID 文件)。
$ docker run --cidfile /tmp/docker_test.cid ubuntu echo "test"
这会创建一个容器并将 test
打印到控制台。cidfile
标志使 Docker 尝试创建一个新文件并将容器 ID 写入其中。如果文件已存在,Docker 将返回错误。docker run
退出时,Docker 会关闭此文件。
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
要在共享主机进程命名空间的容器中运行 htop
使用
--pid=host
选项运行 alpine 容器$ docker run --rm -it --pid=host alpine
在容器中安装
htop
/ # apk add --quiet htop
调用
htop
命令。/ # htop
示例:加入另一个容器的 PID 命名空间
加入另一个容器的 PID 命名空间对于调试该容器很有用。
启动运行 Redis 服务器的容器
$ docker run --rm --name my-nginx -d nginx:alpine
运行一个 Alpine 容器,该容器将
--pid
命名空间附加到my-nginx
容器$ docker run --rm -it --pid=container:my-nginx \ --cap-add SYS_PTRACE \ --security-opt seccomp=unconfined \ alpine
在 Alpine 容器中安装
strace
/ # apk add strace
附加到进程 1(
my-nginx
容器的进程 ID)/ # strace -p 1 strace: Process 1 attached
禁用容器的命名空间重新映射 (--userns)
如果在守护进程上启用用户命名空间,则所有容器默认情况下都启用用户命名空间。要为特定容器禁用用户命名空间重新映射,可以将 --userns
标志设置为 host
。
docker run --userns=host hello-world
host
是 --userns
标志的唯一有效值。
有关更多信息,请参阅 使用用户命名空间隔离容器。
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 命名空间。将 --uts
设置为 host
会导致容器使用与主机相同的 UTS 命名空间。
注意
Docker 不允许将
--hostname
和--domainname
标志与--uts=host
组合使用。这是为了防止在主机的 UTS 命名空间中运行的容器尝试更改主机的配置。
如果您希望容器的主机名随着主机的更改而更改,则可能希望与主机共享 UTS 命名空间。一个更高级的用例是从容器更改主机的主机名。
IPC 设置 (--ipc)
--ipc="MODE" : Set the IPC mode for the container
--ipc
标志接受以下值
值 | 描述 |
---|---|
"" | 使用守护进程的默认值。 |
"none" | 自己的私有 IPC 命名空间,未挂载 /dev/shm。 |
"private" | 自己的私有 IPC 命名空间。 |
"shareable" | 自己的私有 IPC 命名空间,可以与其他容器共享。 |
"container:<name-or-ID>" | 加入另一个(“shareable”)容器的 IPC 命名空间。 |
"host" | 使用主机系统的 IPC 命名空间。 |
如果未指定,则使用守护进程默认值,这可能是 "private"
或 "shareable"
,具体取决于守护进程版本和配置。
System V 进程间通信 (IPC) 命名空间提供命名共享内存段、信号量和消息队列的隔离。
共享内存段用于以内存速度而不是通过管道或网络堆栈来加速进程间通信。数据库和为科学计算和金融服务行业定制构建的(通常是 C/OpenMPI、C++/使用 boost 库)高性能应用程序通常使用共享内存。如果这些类型的应用程序被分解成多个容器,您可能需要共享容器的 IPC 机制,对主(即“捐赠者”)容器使用 "shareable"
模式,对其他容器使用 "container:<donor-name-or-ID>"
。
提升容器权限 (--privileged)
--privileged
标志为容器提供以下功能:
- 启用所有 Linux 内核功能
- 禁用默认 seccomp 配置文件
- 禁用默认 AppArmor 配置文件
- 禁用 SELinux 进程标签
- 授予对所有主机设备的访问权限
- 使
/sys
可读写 - 使 cgroups 挂载点可读写
换句话说,容器随后几乎可以执行主机可以执行的所有操作。此标志的存在是为了允许特殊用例,例如在 Docker 内运行 Docker。
警告
谨慎使用
--privileged
标志。具有--privileged
的容器不是安全沙盒化的进程。此模式下的容器可以在主机上获得 root shell 并控制系统。对于大多数用例,此标志不应该是首选解决方案。如果您的容器需要提升的权限,您应该更倾向于显式授予必要的权限,例如使用
--cap-add
添加单个内核功能。有关更多信息,请参阅 运行时权限和 Linux 功能
以下示例不起作用,因为默认情况下,Docker 会删除大多数潜在危险的内核功能,包括 CAP_SYS_ADMIN
(这对于挂载文件系统是必需的)。
$ docker run -t -i --rm ubuntu bash
root@bc338942ef20:/# mount -t tmpfs none /mnt
mount: permission denied
添加 --privileged
标志后,它就可以工作了。
$ docker run -t -i --privileged ubuntu bash
root@50e3f57e16e6:/# mount -t tmpfs none /mnt
root@50e3f57e16e6:/# df -h
Filesystem Size Used Avail Use% Mounted on
none 1.9G 0 1.9G 0% /mnt
设置工作目录 (-w, --workdir)
$ docker run -w /path/to/dir/ -i -t ubuntu pwd
-w
选项在指定目录(在此示例中为 /path/to/dir/
)内运行执行的命令。如果路径不存在,Docker 将在容器内创建它。
为每个容器设置存储驱动程序选项 (--storage-opt)
$ docker run -it --storage-opt size=120G fedora /bin/bash
这(size)在创建时将容器文件系统大小限制为 120G。此选项仅适用于 btrfs
、overlay2
、windowsfilter
和 zfs
存储驱动程序。
对于 overlay2
存储驱动程序,只有当后备文件系统是 xfs
并使用 pquota
挂载选项挂载时,才可以使用 size 选项。在此条件下,您可以传递小于后备文件系统大小的任何大小。
对于 windowsfilter
、btrfs
和 zfs
存储驱动程序,您不能传递小于默认 BaseFS 大小的 size。
挂载 tmpfs (--tmpfs)
--tmpfs
标志允许您创建 tmpfs
挂载点。
您可以传递给 --tmpfs
的选项与 Linux mount -t tmpfs -o
命令相同。以下示例使用 rw
、noexec
、nosuid
、size=65536k
选项将空的 tmpfs
挂载到容器中。
$ docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image
有关更多信息,请参阅 tmpfs 挂载点。
挂载卷 (-v)
$ docker run -v $(pwd):$(pwd) -w $(pwd) -i -t ubuntu pwd
上面的示例使用 -v
标志将当前目录挂载到容器中的同一路径,将其设置为工作目录,然后在容器内运行 pwd
命令。
从 Docker Engine 版本 23 开始,您可以在主机上使用相对路径。
$ docker run -v ./content:/content -w /content -i -t ubuntu pwd
上面的示例使用 -v
标志将当前目录中的 content
目录挂载到容器中的 /content
路径,将其设置为工作目录,然后在容器内运行 pwd
命令。
$ docker run -v /doesnt/exist:/foo -w /foo -i -t ubuntu bash
当绑定挂载卷的主机目录不存在时,Docker 会自动为您在主机上创建此目录。在上面的示例中,Docker 会在启动容器之前创建 /doesnt/exist
文件夹。
以只读模式挂载卷 (--read-only)
$ docker run --read-only -v /icanwrite busybox touch /icanwrite/here
您可以结合使用卷和--read-only
标志来控制容器写入文件的位置。--read-only
标志将容器的根文件系统挂载为只读模式,禁止写入容器指定卷之外的位置。
$ docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/static-docker-binary:/usr/bin/docker busybox sh
通过绑定挂载Docker Unix套接字和静态链接的Docker二进制文件(请参考获取Linux二进制文件),您可以赋予容器创建和操作主机Docker守护进程的完全权限。
在Windows上,必须使用Windows样式的路径语义指定路径。
PS C:\> docker run -v c:\foo:c:\dest microsoft/nanoserver cmd /s /c type c:\dest\somefile.txt
Contents of file
PS C:\> docker run -v c:\foo:d: microsoft/nanoserver cmd /s /c type d:\somefile.txt
Contents of file
在使用基于Windows的容器时,以下示例会失败,因为容器内卷或绑定挂载的目标必须是:不存在或为空的目录;或C:
以外的驱动器。此外,绑定挂载的源必须是本地目录,而不是文件。
net use z: \\remotemachine\share
docker run -v z:\foo:c:\dest ...
docker run -v \\uncpath\to\directory:c:\dest ...
docker run -v c:\foo\somefile.txt:c:\dest ...
docker run -v c:\foo:c: ...
docker run -v c:\foo:c:\existing-directory-with-contents ...
有关卷的详细信息,请参考在容器中管理数据
使用 --mount 标志添加绑定挂载或卷
--mount
标志允许您在容器中挂载卷、主机目录和tmpfs
挂载点。
--mount
标志支持-v
或--volume
标志支持的大多数选项,但使用不同的语法。有关--mount
标志的详细信息以及--volume
和--mount
的比较,请参考绑定挂载。
即使没有计划弃用--volume
,也建议使用--mount
。
示例
$ docker run --read-only --mount type=volume,target=/icanwrite busybox touch /icanwrite/here
$ docker run -t -i --mount type=bind,src=/data,dst=/data busybox sh
发布或公开端口 (-p, --expose)
$ docker run -p 127.0.0.1:80:8080/tcp nginx:alpine
这将容器的8080
端口绑定到主机的127.0.0.1
上的TCP 80
端口。您也可以指定udp
和sctp
端口。网络概述页面详细解释了如何使用Docker发布端口。
注意
如果您在发布容器端口时没有指定IP地址(即使用
-p 80:80
而不是-p 127.0.0.1:80:80
),Docker默认情况下会在所有接口(地址0.0.0.0
)上发布该端口。这些端口可在外部访问。如果您配置UFW来阻止此特定端口,这也适用,因为Docker管理它自己的iptables规则。阅读更多
$ docker run --expose 80 nginx:alpine
这将公开容器的80
端口,而不会将端口发布到主机系统的接口。
发布所有公开的端口 (-P, --publish-all)
$ docker run -P nginx:alpine
-P
或--publish-all
标志将所有公开的端口发布到主机。Docker将每个公开的端口绑定到主机上的随机端口。
-P
标志只发布明确标记为公开的端口号,可以使用Dockerfile的EXPOSE
指令或docker run
命令的--expose
标志。
端口范围在由/proc/sys/net/ipv4/ip_local_port_range
定义的_短暂端口范围_内。使用-p
标志显式映射单个端口或端口范围。
设置拉取策略 (--pull)
使用--pull
标志在创建(和运行)容器时设置镜像拉取策略。
--pull
标志可以取以下值:
值 | 描述 |
---|---|
missing (默认) | 如果镜像在镜像缓存中找不到,则拉取镜像;否则使用缓存的镜像。 |
never | 即使镜像丢失也不拉取镜像,如果镜像不存在于镜像缓存中,则产生错误。 |
always | 在创建容器之前始终执行拉取操作。 |
从镜像创建(和运行)容器时,守护进程会检查镜像是否存在于本地镜像缓存中。如果镜像丢失,则会向CLI返回错误,允许其启动拉取操作。
默认值(missing
)是只有在守护进程的镜像缓存中不存在镜像时才拉取镜像。此默认值允许您运行仅存在于本地的镜像(例如,您从Dockerfile构建但尚未推送到注册表的镜像),并减少网络流量。
always
选项在创建容器之前始终启动拉取操作。此选项确保镜像是最新的,并防止您使用过时的镜像,但在您想在推送之前测试本地构建的镜像的情况下可能不适用(因为拉取镜像会覆盖镜像缓存中现有的镜像)。
never
选项在创建容器时禁用(隐式)拉取镜像,并且只使用镜像缓存中可用的镜像。如果找不到指定的镜像,则会产生错误,并且不会创建容器。此选项在网络不可用或要防止在创建容器时隐式拉取镜像的情况下很有用。
以下示例显示带有--pull=never
选项设置的docker run
,由于镜像在镜像缓存中丢失,因此会产生错误。
$ docker run --pull=never hello-world
docker: Error response from daemon: No such image: hello-world:latest.
设置环境变量 (-e, --env, --env-file)
$ docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash
使用-e
、--env
和--env-file
标志在您正在运行的容器中设置简单的(非数组)环境变量,或覆盖您正在运行的镜像的Dockerfile中定义的变量。
您可以在运行容器时定义变量及其值。
$ docker run --env VAR1=value1 --env VAR2=value2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2
您也可以使用导出到本地环境的变量。
export VAR1=value1
export VAR2=value2
$ docker run --env VAR1 --env VAR2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2
运行命令时,Docker CLI客户端会检查变量在本地环境中的值,并将其传递给容器。如果没有提供=
并且该变量未在您的本地环境中导出,则该变量在容器中将被取消设置。
您还可以从文件中加载环境变量。此文件应使用语法<variable>=value
(将变量设置为给定的值)或<variable>
(从本地环境获取值),以及#
用于注释。以#
开头的行被视为行注释并被忽略,而出现在行中其他任何位置的#
都被视为变量值的一部分。
$ cat env.list
# This is a comment
VAR1=value1
VAR2=value2
USER
$ docker run --env-file env.list ubuntu env | grep -E 'VAR|USER'
VAR1=value1
VAR2=value2
USER=jonzeolla
在容器上设置元数据 (-l, --label, --label-file)
标签是一个key=value
对,它将元数据应用于容器。要使用两个标签标记容器:
$ docker run -l my-label --label com.example.foo=bar ubuntu bash
my-label
键没有指定值,因此标签默认为空字符串(""
)。要添加多个标签,请重复标签标志(-l
或--label
)。
key=value
必须唯一,以避免覆盖标签值。如果您指定具有相同键但不同值的标签,则每个后续值都会覆盖之前的值。Docker使用您提供的最后一个key=value
。
使用--label-file
标志从文件中加载多个标签。用EOL标记分隔文件中的每个标签。以下示例从当前目录中的标签文件加载标签:
$ docker run --label-file ./labels ubuntu bash
标签文件的格式类似于加载环境变量的格式。(与环境变量不同,标签对容器内运行的进程不可见。)以下示例显示标签文件的格式:
com.example.label1="a label"
# this is a comment
com.example.label2=another\ label
com.example.label3
您可以通过提供多个--label-file
标志来加载多个标签文件。
有关使用标签的更多信息,请参见标签。
将容器连接到网络 (--network)
要启动容器并将其连接到网络,请使用--network
选项。
如果您想将正在运行的容器添加到网络,请使用docker network connect
子命令。
您可以将多个容器连接到同一个网络。连接后,容器可以使用另一个容器的IP地址或名称进行通信。对于支持多主机连接的overlay
网络或自定义插件,从不同引擎启动但连接到相同多主机网络的容器也可以以这种方式进行通信。
注意
默认的桥接网络只允许容器使用内部IP地址相互通信。用户创建的桥接网络使用容器名称在容器之间提供DNS解析。
您可以使用docker network disconnect
命令将容器从网络断开连接。
以下命令创建一个名为my-net
的网络,并将busybox
容器添加到my-net
网络。
$ docker network create my-net
$ docker run -itd --network=my-net busybox
您也可以在用户定义的网络上启动容器时,使用--ip
和--ip6
标志为容器选择IP地址。要为容器分配静态IP,必须为网络指定子网块。
$ docker network create --subnet 192.0.2.0/24 my-net
$ docker run -itd --network=my-net --ip=192.0.2.69 busybox
要将容器连接到多个网络,请重复--network
选项。
$ docker network create --subnet 192.0.2.0/24 my-net1
$ docker network create --subnet 192.0.3.0/24 my-net2
$ docker run -itd --network=my-net1 --network=my-net2 busybox
要指定连接到多个网络时的选项,请使用--network
标志的扩展语法。可以在扩展的--network
语法中指定的逗号分隔的选项是:
选项 | 顶级等效项 | 描述 |
---|---|---|
name | 网络名称(必填) | |
alias | --network-alias | 为容器添加网络范围别名 |
ip | --ip | IPv4地址(例如,172.30.100.104) |
ip6 | --ip6 | IPv6地址(例如,2001:db8::33) |
mac-address | --mac-address | 容器MAC地址(例如,92:d0:c6:0a:29:33) |
link-local-ip | --link-local-ip | 容器IPv4/IPv6本地链路地址 |
driver-opt | docker network connect --driver-opt | 网络驱动程序选项 |
$ docker network create --subnet 192.0.2.0/24 my-net1
$ docker network create --subnet 192.0.3.0/24 my-net2
$ docker run -itd --network=name=my-net1,ip=192.0.2.42 --network=name=my-net2,ip=192.0.3.42 busybox
可以使用driver-opt
标签com.docker.network.endpoint.sysctls
为每个接口设置以net.ipv4.
、net.ipv6.
或net.mpls.
开头的sysctl
设置。接口名称必须是字符串IFNAME
。
要为接口设置多个sysctl
,请引用整个driver-opt
字段,如有必要,请记住为shell转义引号。例如,如果给定my-net
的接口名为eth0
,则以下示例设置sysctl
net.ipv4.conf.eth0.log_martians=1
和net.ipv4.conf.eth0.forwarding=0
,并分配IPv4地址192.0.2.42
。
$ docker network create --subnet 192.0.2.0/24 my-net
$ docker run -itd --network=name=my-net,\"driver-opt=com.docker.network.endpoint.sysctls=net.ipv4.conf.IFNAME.log_martians=1,net.ipv4.conf.IFNAME.forwarding=0\",ip=192.0.2.42 busybox
注意
网络驱动程序可能会限制可以修改的
sysctl
设置,并且为了保护网络的操作,将来可能会添加新的限制。
有关在使用run
命令时将容器连接到网络的更多信息,请参见Docker网络概述。
从容器挂载卷 (--volumes-from)
$ docker run --volumes-from 777f7dc92da7 --volumes-from ba8c0c54f0f2:ro -i -t ubuntu pwd
--volumes-from
标志会挂载来自引用容器的所有已定义卷。您可以通过重复--volumes-from
参数来指定多个容器。容器ID可以可选地后缀:ro
或:rw
,分别以只读或读写模式挂载卷。默认情况下,Docker以与参考容器相同的模式(读写或只读)挂载卷。
像SELinux这样的标签系统需要在挂载到容器中的卷内容上放置正确的标签。如果没有标签,安全系统可能会阻止容器内运行的进程使用内容。默认情况下,Docker不会更改操作系统设置的标签。
要更改容器上下文中的标签,您可以向卷挂载添加两个后缀中的一个:z
或:Z
。这些后缀告诉Docker重新标记共享卷上的文件对象。z
选项告诉Docker两个容器共享卷内容。结果,Docker使用共享内容标签标记内容。共享卷标签允许所有容器读取/写入内容。Z
选项告诉Docker使用私有未共享标签标记内容。只有当前容器可以使用私有卷。
分离模式 (-d, --detach)
--detach
(或-d
)标志将容器作为后台进程启动,该进程不占用您的终端窗口。根据设计,以分离模式启动的容器会在用于运行容器的root进程退出时退出,除非您还指定了--rm
选项。如果您将-d
与--rm
一起使用,则容器会在其退出或守护进程退出时被移除,以先发生者为准。
不要将service x start
命令传递给分离的容器。例如,此命令尝试启动nginx
服务。
$ docker run -d -p 80:80 my_image service nginx start
这成功地在容器内启动了nginx
服务。但是,它失败了分离容器范例,因为root进程(service nginx start
)返回,并且分离容器按设计停止。结果,nginx
服务启动但无法使用。相反,要启动nginx
web服务器等进程,请执行以下操作:
$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'
要与分离的容器进行输入/输出,请使用网络连接或共享卷。这是必需的,因为容器不再侦听运行docker run
的命令行。
覆盖分离序列 (--detach-keys)
使用--detach-keys
选项可以覆盖 Docker 的分离键序列。如果 Docker 的默认序列与您其他应用程序使用的键序列冲突,这将非常有用。有两种方法可以定义您自己的分离键序列:作为每个容器的覆盖,或作为整个配置的配置属性。
要覆盖单个容器的序列,请在docker attach
命令中使用--detach-keys="<sequence>"
标志。<sequence>
的格式可以是一个字母 [a-Z],或者ctrl-
组合以下任何字符:
a-z
(单个小写字母字符)@
(@ 符号)[
(左方括号)\\
(两个反斜杠)_
(下划线)^
(插入符)
这些a
、ctrl-a
、X
或ctrl-\\
值都是有效的键序列示例。要为所有容器配置不同的默认配置键序列,请参阅配置文件部分。
将主机设备添加到容器(--device)
$ docker run -it --rm \
--device=/dev/sdc:/dev/xvdc \
--device=/dev/sdd \
--device=/dev/zero:/dev/foobar \
ubuntu ls -l /dev/{xvdc,sdd,foobar}
brw-rw---- 1 root disk 8, 2 Feb 9 16:05 /dev/xvdc
brw-rw---- 1 root disk 8, 3 Feb 9 16:05 /dev/sdd
crw-rw-rw- 1 root root 1, 5 Feb 9 16:05 /dev/foobar
通常需要直接将设备暴露给容器。--device
选项允许这样做。例如,将特定的块存储设备、循环设备或音频设备添加到没有特权的容器(不使用--privileged
标志)中,并让应用程序直接访问它。
默认情况下,容器可以读取
、写入
和mknod
这些设备。可以使用每个--device
标志的第三个:rwm
选项集来覆盖此设置。如果容器在特权模式下运行,则 Docker 会忽略指定的权限。
$ 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:rw --rm -it ubuntu fdisk /dev/xvdc
Command (m for help): q
$ docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk /dev/xvdc
fdisk: unable to open /dev/xvdc: Operation not permitted
注意
--device
选项不能安全地与临时设备一起使用。您不应该使用--device
将可能被移除的块设备添加到不受信任的容器。
请参阅Windows 容器文档中定义的表格,以获取容器支持的设备接口类 GUID 列表。
如果您为进程隔离的 Windows 容器指定此选项,Docker 会使实现请求的设备接口类 GUID 的所有设备在容器中可用。例如,以下命令使主机上的所有 COM 端口在容器中可见。
PS C:\> docker run --device=class/86E0D1E0-8089-11D0-9CE4-08003E301F73 mcr.microsoft.com/windows/servercore:ltsc2019
注意
--device
选项仅支持进程隔离的 Windows 容器,如果容器隔离为hyperv
,则会产生错误。
CDI 设备
注意
CDI 功能处于实验阶段,可能随时更改。CDI 目前仅支持 Linux 容器。
容器设备接口 (CDI)是一种标准化机制,用于容器运行时创建能够与第三方设备交互的容器。
使用 CDI,设备配置使用 JSON 或 YAML 文件声明式定义。除了使容器能够与设备节点交互之外,还可以为设备指定其他配置,例如环境变量、主机挂载(例如共享对象)和可执行挂钩。
您可以使用--device
标志引用 CDI 设备,使用设备的全限定名,如下例所示:
$ docker run --device=vendor.com/class=device-name --rm -it ubuntu
这将启动一个ubuntu
容器,并访问指定的 CDI 设备vendor.com/class=device-name
,假设:
- 在运行守护程序的系统上,在已配置的 CDI 规范目录之一中,提供了请求设备的有效 CDI 规范(JSON 或 YAML 文件)。
- 守护程序中已启用 CDI 功能;请参阅启用 CDI 设备。
连接到 STDIN/STDOUT/STDERR (-a, --attach)
--attach
(或-a
)标志告诉docker run
绑定到容器的STDIN
、STDOUT
或STDERR
。这使得可以根据需要操作输出和输入。您可以指定要连接到的三个标准流(STDIN
、STDOUT
、STDERR
)中的哪一个,例如:
$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash
以下示例将数据输入容器,并通过仅连接到容器的STDIN
来打印容器的 ID。
$ echo "test" | docker run -i -a stdin ubuntu cat -
以下示例除非发生错误,否则不会向控制台打印任何内容,因为输出仅连接到容器的STDERR
。容器的日志仍然存储写入STDERR
和STDOUT
的内容。
$ docker run -a stderr ubuntu echo test
以下示例显示了使用--attach
将文件输入容器的方法。该命令在构建完成后打印容器的 ID,您可以使用docker logs
检索构建日志。如果您需要将文件或其他内容输入容器并在容器运行完成后检索容器的 ID,这将非常有用。
$ cat somefile | docker run -i -a stdin mybuilder dobuild
注意
在容器内作为 PID 1 运行的进程由 Linux 特殊处理:它忽略任何具有默认操作的信号。因此,除非对其进行编码,否则该进程不会在
SIGINT
或SIGTERM
上终止。
另请参阅docker cp
命令。
保持 STDIN 打开 (-i, --interactive)
--interactive
(或-i
)标志保持容器的STDIN
打开,并允许您通过标准输入向容器发送输入。
$ echo hello | docker run --rm -i busybox cat
hello
-i
标志最常与--tty
标志一起使用,以将容器的 I/O 流绑定到伪终端,为容器创建一个交互式终端会话。请参阅分配伪 TTY以获取更多示例。
$ docker run -it debian
root@10a3e71492b0:/# factor 90
90: 2 3 3 5
root@10a3e71492b0:/# exit
exit
单独使用-i
标志允许进行组合,例如将输入管道传输到容器。
$ docker run --rm -i busybox echo "foo bar baz" \
| docker run --rm -i busybox awk '{ print $2 }' \
| docker run --rm -i busybox rev
rab
指定 init 进程
您可以使用--init
标志指示应将 init 进程用作容器中的 PID 1。指定 init 进程可确保执行 init 系统的常用职责,例如收集僵尸进程,在创建的容器内执行。
使用的默认 init 进程是 Docker 守护程序进程的系统路径中找到的第一个docker-init
可执行文件。此docker-init
二进制文件包含在默认安装中,由tini支持。
分配伪 TTY (-t, --tty)
--tty
(或-t
)标志将伪 TTY 附加到容器,将您的终端连接到容器的 I/O 流。为容器分配伪 TTY 意味着您可以访问 TTY 设备提供的输入和输出功能。
例如,以下命令在debian
容器中运行passwd
命令,以设置root
用户的新的密码。
$ docker run -i debian passwd root
New password: karjalanpiirakka9
Retype new password: karjalanpiirakka9
passwd: password updated successfully
如果您仅使用-i
标志运行此命令(允许您将文本发送到容器的STDIN
),则passwd
提示符将以纯文本显示密码。但是,如果您尝试相同操作,但还添加了-t
标志,则密码将被隐藏。
$ docker run -it debian passwd root
New password:
Retype new password:
passwd: password updated successfully
这是因为passwd
可以使用 echo-off TTY 功能抑制将字符输出到终端。
您可以使用-t
标志而不使用-i
标志。这仍然会为容器分配伪 TTY,但无法写入STDIN
。这可能只有在容器的输出需要 TTY 环境时才有用。
指定自定义 cgroups
使用--cgroup-parent
标志,您可以传递特定的 cgroup 以在其中运行容器。这允许您创建和管理他们自己的 cgroups。您可以为这些 cgroups 定义自定义资源,并将容器放在一个公共父组下。
使用动态创建的设备(--device-cgroup-rule)
Docker 在创建时分配可用于容器的设备。分配的设备被添加到 cgroup.allow 文件中,并在容器运行时创建到容器中。当您需要向正在运行的容器添加新设备时,这会带来问题。
一种解决方案是向容器添加更宽松的规则,允许它访问更广泛的设备。例如,假设容器需要访问主设备号为42
且次设备号为任意数字(作为新设备出现时添加)的字符设备,请添加以下规则:
$ docker run -d --device-cgroup-rule='c 42:* rmw' --name my-container my-image
然后,用户可以请求udev
执行一个脚本,该脚本会在添加设备时docker exec my-container mknod newDevX c 42
所需的设备。
注意
您仍然需要将最初存在的设备显式添加到
docker run
/docker create
命令中。
访问 NVIDIA GPU
--gpus
标志允许您访问 NVIDIA GPU 资源。首先,您需要安装nvidia-container-runtime。
注意
您也可以使用
--device
标志将 GPU 指定为 CDI 设备,请参阅CDI 设备。
阅读指定容器的资源以获取更多信息。
要使用--gpus
,请指定要使用的 GPU(或全部)。如果您不提供任何值,Docker 将使用所有可用的 GPU。以下示例公开了所有可用的 GPU。
$ docker run -it --rm --gpus all ubuntu nvidia-smi
使用device
选项指定GPU。下面的示例公开了一个特定的GPU。
$ docker run -it --rm --gpus device=GPU-3a23c669-1f69-c64e-cf85-44e9b07e7a2a ubuntu nvidia-smi
下面的示例公开第一和第三个GPU。
$ docker run -it --rm --gpus '"device=0,2"' ubuntu nvidia-smi
重启策略 (--restart)
使用--restart
标志指定容器的*重启策略*。重启策略控制Docker守护进程在容器退出后是否重启容器。Docker支持以下重启策略:
标志 | 描述 |
---|---|
no | 不自动重启容器。(默认) |
on-failure[:max-retries] | 如果容器由于错误退出(表现为非零退出代码),则重启容器。可以使用:max-retries 选项限制Docker守护进程尝试重启容器的次数。on-failure 策略只有在容器以失败状态退出时才会提示重启。如果守护进程重启,它不会重启容器。 |
always | 如果容器停止,则始终重启容器。如果手动停止容器,只有在Docker守护进程重启或容器本身手动重启时才会重启。 |
unless-stopped | 类似于always ,但当容器停止(手动或其他方式)时,即使在Docker守护进程重启后也不会重启。 |
$ docker run --restart=always redis
这将使用**always**重启策略运行redis
容器。如果容器退出,Docker将重启它。
当容器上激活重启策略时,它在docker ps
中显示为Up
或Restarting
。使用docker events
查看生效的重启策略也很有用。
每次重启前都会增加一个递增的延迟(之前的延迟的两倍,从100毫秒开始),以防止服务器过载。这意味着守护进程将等待100毫秒,然后200毫秒,400毫秒,800毫秒,1600毫秒,依此类推,直到达到on-failure
限制、达到1分钟的最大延迟,或者您docker stop
或docker rm -f
容器。
如果容器成功重启(容器启动并运行至少10秒),则延迟将重置为其默认值100毫秒。
指定重启尝试限制
使用**on-failure**策略时,可以指定Docker尝试重启容器的最大次数。默认情况下,Docker永远不会停止尝试重启容器。
以下示例使用**on-failure**重启策略和最大重启次数10运行redis
容器。
$ docker run --restart=on-failure:10 redis
如果redis
容器以非零退出状态连续退出超过10次,Docker将停止尝试重启容器。提供最大重启限制仅对**on-failure**策略有效。
检查容器重启次数
可以使用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在容器退出时自动清理容器并删除文件系统,请使用--rm
标志。
--rm: Automatically remove the container when it exits
注意
如果设置了
--rm
标志,Docker还会在删除容器时删除与该容器关联的匿名卷。这类似于运行docker rm -v my-container
。只有未指定名称的卷才会被删除。例如,运行以下命令时,卷/foo
将被删除,但/bar
不会被删除。$ docker run --rm -v /foo -v awesome:/bar busybox top
通过
--volumes-from
继承的卷将使用相同的逻辑删除:如果原始卷指定了名称,则不会删除。
向容器hosts文件添加条目 (--add-host)
您可以使用一个或多个--add-host
标志将其他主机添加到容器的/etc/hosts
文件中。此示例为名为my-hostname
的主机添加静态地址。
$ docker run --add-host=my-hostname=8.8.8.8 --rm -it alpine
/ # ping my-hostname
PING my-hostname (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=37 time=93.052 ms
64 bytes from 8.8.8.8: seq=1 ttl=37 time=92.467 ms
64 bytes from 8.8.8.8: seq=2 ttl=37 time=92.252 ms
^C
--- my-hostname ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 92.209/92.495/93.052 ms
您可以将IPv6地址括在方括号中。
$ docker run --add-host my-hostname=[2001:db8::33] --rm -it alpine
--add-host
标志支持一个特殊的host-gateway
值,该值解析为主机的内部IP地址。当您希望容器连接到主机上运行的服务时,这非常有用。
通常使用host.docker.internal
作为主机名来引用host-gateway
。Docker Desktop会自动解析此主机名,请参阅探索网络功能。
以下示例显示了特殊host-gateway
值的工作方式。该示例运行一个HTTP服务器,该服务器通过host.docker.internal
主机名(解析为主机的内部IP)将文件从主机提供给容器。
$ echo "hello from host!" > ./hello
$ python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
$ docker run \
--add-host host.docker.internal=host-gateway \
curlimages/curl -s host.docker.internal:8000/hello
hello from host!
--add-host
标志也接受:
分隔符,例如:
$ docker run --add-host=my-hostname:8.8.8.8 --rm -it alpine
日志驱动程序 (--log-driver)
容器可以具有与Docker守护进程不同的日志驱动程序。使用docker run
命令中的--log-driver=<DRIVER>
配置容器的日志驱动程序。
要了解支持的日志驱动程序以及如何使用它们,请参阅配置日志驱动程序。
要禁用容器的日志记录,请将--log-driver
标志设置为none
。
$ docker run --log-driver=none -d nginx:alpine
5101d3b7fe931c27c2ba0e65fd989654d297393ad65ae238f20b97a020e7295b
$ docker logs 5101d3b
Error response from daemon: configured logging driver does not support reading
在容器中设置ulimit (--ulimit)
由于在容器中设置ulimit
设置需要默认容器中不可用的额外权限,因此您可以使用--ulimit
标志设置这些权限。使用软限制和硬限制指定--ulimit
,格式为<type>=<soft limit>[:<hard limit>]
。例如:
$ docker run --ulimit nofile=1024:1024 --rm debian sh -c "ulimit -n"
1024
注意
如果您不提供硬限制值,Docker将对这两个值使用软限制值。如果您不提供任何值,它们将从守护进程上设置的默认
ulimits
继承。
注意
as
选项已弃用。换句话说,以下脚本不受支持:$ docker run -it --ulimit as=1024 fedora /bin/bash
Docker将值发送到相应的OS syscall
,并且不执行任何字节转换。设置值时请考虑这一点。
关于nproc
的使用
使用ulimit
标志设置nproc
时要小心,因为Linux使用nproc
来设置用户可用的最大进程数,而不是容器。例如,使用daemon
用户启动四个容器:
$ docker run -d -u daemon --ulimit nproc=3 busybox top
$ docker run -d -u daemon --ulimit nproc=3 busybox top
$ docker run -d -u daemon --ulimit nproc=3 busybox top
$ docker run -d -u daemon --ulimit nproc=3 busybox top
第四个容器失败并报告“[8] 系统错误:资源暂时不可用”错误。这是因为调用者设置了nproc=3
,导致前三个容器用完了为daemon
用户设置的三个进程配额。
使用信号停止容器 (--stop-signal)
--stop-signal
标志向容器发送系统调用信号以退出。此信号可以是格式为SIG<NAME>
的信号名,例如SIGKILL
,也可以是与内核syscall表中的位置匹配的无符号数字,例如9
。
默认值由镜像中的STOPSIGNAL
定义,如果镜像未定义STOPSIGNAL
,则为SIGTERM
。
可选安全选项 (--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=builtin" | 对容器使用默认(内置)seccomp配置文件。这可用于为在具有自定义默认配置文件设置或seccomp已禁用(“unconfined”)的守护程序上运行的容器启用seccomp。 |
--security-opt="seccomp=profile.json" | 作为seccomp过滤器使用的白名单syscall seccomp Json文件。 |
--security-opt="systempaths=unconfined" | 关闭容器系统路径(屏蔽路径,只读路径)的限制。 |
--security-opt
标志允许您覆盖容器的默认标签方案。在以下命令中指定级别允许您在容器之间共享相同的内容。
$ docker run --security-opt label=level:s0:c100,c200 -it fedora bash
注意
不支持MLS标签的自动转换。
要完全禁用容器的安全标签,可以使用label=disable
。
$ docker run --security-opt label=disable -it ubuntu bash
如果您希望对容器内的进程实施更严格的安全策略,您可以指定自定义type
标签。以下示例运行一个仅允许在Apache端口上监听的容器。
$ docker run --security-opt label=type:svirt_apache_t -it ubuntu bash
注意
您需要编写定义
svirt_apache_t
类型的策略。
要防止容器进程获得额外权限,可以使用以下命令:
$ docker run --security-opt no-new-privileges -it ubuntu bash
这意味着提升权限的命令(如su
或sudo
)将不再工作。它还会导致任何seccomp过滤器在权限下降后稍后应用,这意味着您可以拥有更严格的过滤器集。更多详细信息,请参阅内核文档。
在Windows上,您可以使用--security-opt
标志指定credentialspec
选项。credentialspec
必须采用file://spec.txt
或registry://keyname
格式。
使用超时停止容器 (--stop-timeout)
--stop-timeout
标志设置发送预定义(请参阅--stop-signal
)系统调用信号后等待容器停止的秒数。如果容器在超时后仍未退出,则会使用SIGKILL
信号强制将其终止。
如果将--stop-timeout
设置为-1
,则不应用超时,并且守护进程将无限期地等待容器退出。
守护进程确定默认值,对于Linux容器为10秒,对于Windows容器为30秒。
指定容器的隔离技术 (--isolation)
此选项在您在Windows上运行Docker容器的情况下非常有用。--isolation=<value>
选项设置容器的隔离技术。在Linux上,唯一支持的选项是default
选项,它使用Linux命名空间。在Linux上,这两个命令是等效的:
$ docker run -d busybox top
$ docker run -d --isolation default busybox top
在Windows上,--isolation
可以采用以下值之一:
值 | 描述 |
---|---|
default | 使用Docker守护进程的--exec-opt 或系统默认值(见下文)指定的值。 |
process | 共享内核命名空间隔离。 |
hyperv | 基于Hyper-V虚拟机的分区隔离。 |
Windows服务器操作系统的默认隔离是process
,Windows客户端操作系统(如Windows 10)的默认隔离是hyperv
。进程隔离的性能更好,但要求镜像和主机使用相同的内核版本。
在Windows服务器上,假设默认配置,这些命令是等效的,并导致process
隔离:
PS C:\> docker run -d microsoft/nanoserver powershell echo process
PS C:\> docker run -d --isolation default microsoft/nanoserver powershell echo process
PS C:\> docker run -d --isolation process microsoft/nanoserver powershell echo process
如果您在 Docker 守护程序上设置了--exec-opt isolation=hyperv
选项,或运行在基于 Windows 客户端的守护程序上,则这些命令是等效的,并将导致hyperv
隔离。
PS C:\> docker run -d microsoft/nanoserver powershell echo hyperv
PS C:\> docker run -d --isolation default microsoft/nanoserver powershell echo hyperv
PS C:\> docker run -d --isolation hyperv microsoft/nanoserver powershell echo hyperv
指定容器可用内存的硬性限制 (-m, --memory)
这些参数始终设置容器可用内存的上限。Linux 在 cgroup 上设置此上限,容器中的应用程序可以在/sys/fs/cgroup/memory/memory.limit_in_bytes
查询它。
在 Windows 上,这会根据您使用的隔离类型以不同的方式影响容器。
使用
process
隔离,Windows 报告主机系统的全部内存,而不是容器内运行的应用程序的限制。PS C:\> docker run -it -m 2GB --isolation=process microsoft/nanoserver powershell Get-ComputerInfo *memory* CsTotalPhysicalMemory : 17064509440 CsPhyicallyInstalledMemory : 16777216 OsTotalVisibleMemorySize : 16664560 OsFreePhysicalMemory : 14646720 OsTotalVirtualMemorySize : 19154928 OsFreeVirtualMemory : 17197440 OsInUseVirtualMemory : 1957488 OsMaxProcessMemorySize : 137438953344
使用
hyperv
隔离,Windows 创建一个虚拟机,其大小足以容纳内存限制,以及托管容器所需的最小操作系统。该大小报告为“总物理内存”。PS C:\> docker run -it -m 2GB --isolation=hyperv microsoft/nanoserver powershell Get-ComputerInfo *memory* CsTotalPhysicalMemory : 2683355136 CsPhyicallyInstalledMemory : OsTotalVisibleMemorySize : 2620464 OsFreePhysicalMemory : 2306552 OsTotalVirtualMemorySize : 2620464 OsFreeVirtualMemory : 2356692 OsInUseVirtualMemory : 263772 OsMaxProcessMemorySize : 137438953344
在运行时配置命名空间内核参数 (sysctls) (--sysctl)
--sysctl
在容器中设置命名空间内核参数 (sysctls)。例如,要在容器的网络命名空间中启用 IP 转发,请运行此命令。
$ docker run --sysctl net.ipv4.ip_forward=1 someimage
注意
并非所有 sysctls 都是命名空间的。Docker 不支持更改容器内的 sysctls,这些 sysctls 也会修改主机系统。随着内核的发展,我们预计将看到更多 sysctls 成为命名空间的。
当前支持的 sysctls
IPC 命名空间
kernel.msgmax
,kernel.msgmnb
,kernel.msgmni
,kernel.sem
,kernel.shmall
,kernel.shmmax
,kernel.shmmni
,kernel.shm_rmid_forced
。- 以
fs.mqueue.*
开头的 Sysctls - 如果您使用
--ipc=host
选项,则不允许使用这些 sysctls。
网络命名空间
- 以
net.*
开头的 Sysctls - 如果您使用
--network=host
选项,则不允许使用这些 sysctls。