docker run
从镜像创建和运行一个新的容器
用法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
描述
docker run命令在一个新的容器中运行一个命令,如果需要的话会拉取镜像并启动容器。
你可以使用docker start重新启动一个已经停止的容器,并保留其之前的所有更改。使用docker ps -a可以查看包括已停止的容器在内的所有容器列表。
选项
选项简写默认值描述
--add-host添加自定义主机到IP映射(host:ip)
--annotationAPI 1.43+ 添加一个注释到容器(通过OCI运行时传递)
--attach-a附加到STDIN、STDOUT或STDERR
--blkio-weight块IO(相对权重),介于10和1000之间,或者0表示禁用
--blkio-weight-device块IO权重(相对设备权重)
--cap-add添加Linux功能
--cap-drop删除Linux功能
--cgroup-parent可选的父cgroup用于容器
--cgroupnsAPI 1.41+ 要使用的cgroup命名空间
--cidfile将容器ID写入文件
--cpu-countCPU数量(仅适用于Windows)
--cpu-percentCPU百分比(仅适用于Windows)
--cpu-period限制CPU CFS(完全公平调度器)周期
--cpu-quota限制CPU CFS(完全公平调度器)配额
--cpu-rt-periodAPI 1.25+限制CPU实时周期(以微秒为单位)
--cpu-rt-runtimeAPI 1.25+限制CPU实时运行时间(以微秒为单位)
--cpu-shares-cCPU份额(相对权重)
--cpusAPI 1.25+CPU数量
--cpuset-cpus允许执行的CPU
--cpuset-mems允许执行的MEM
--detach-d以后台模式运行容器并打印容器ID
--detach-keys覆盖分离容器的键序列
--device向容器添加主机设备
--device-cgroup-rule向cgroup允许设备列表添加规则
--device-read-bps从设备读取速率(每秒字节数)
--device-read-iops从设备读取速率(每秒IO数)
--device-write-bps写入速率(每秒字节数)到设备
--device-write-iops写入速率(每秒IO数)到设备
--disable-content-trusttrue跳过镜像验证
--dns设置自定义DNS服务器
--dns-opt设置DNS选项
--dns-option设置DNS选项
--dns-search设置自定义DNS搜索域
--domainname容器的NIS域名
--entrypoint覆盖镜像的默认ENTRYPOINT
--env-e设置环境变量
--env-file从文件中读取环境变量
--expose暴露一个端口或一段端口
--gpusAPI 1.40+要添加到容器中的GPU设备
--group-add添加额外的组加入
--health-cmd运行以检查健康状态的命令
--health-interval运行检查之间的时间间隔
--health-retries连续失败次数报告不健康
--health-start-periodAPI 1.29+启动周期,用于在启动健康计数器倒计时之前初始化容器
--health-timeout允许单个检查运行的最长时间
--help打印用法
--hostname-h容器主机名
--initAPI 1.25+在容器内部运行一个init,转发信号并回收进程
--interactive-i保持STDIN打开,即使没有附加
--io-maxbandwidth系统驱动器的最大IO带宽限制
--io-maxiops系统驱动器的最大IOps限制
--ipIPv4地址
--ip6IPv6地址
--ipc要使用的IPC模式
--isolation容器隔离技术
--kernel-memory内核内存限制
--label-l在容器上设置元数据
--label-file从标签文件中读取
--link添加到另一个容器的链接
--link-local-ip容器IPv4/IPv6链路本地地址
--log-driver容器的日志记录驱动程序
--log-opt日志驱动程序选项
--mac-address容器的MAC地址
--memory-m内存限制
--memory-reservation内存软限制
--memory-swap交换限制等于内存加交换
--memory-swappiness-1调整容器内存的使用率
--mount附加文件系统挂载到容器
--name为容器分配一个名称
--net将容器连接到网络
--net-alias为容器添加网络作用域的别名
--network将容器连接到网络
--network-alias为容器添加网络作用域的别名
--no-healthcheck禁用容器指定的任何健康检查
--oom-kill-disable禁用OOM Killer
--oom-score-adj调整主机的OOM首选项
--pid要使用的PID命名空间
--pids-limit调整容器进程数限制
--platformAPI 1.32+设置平台
--privileged为该容器提供扩展权限
--publish-p将容器的端口发布到主机
--publish-all-P将所有暴露的端口发布到随机端口
--pullmissing运行前拉取镜像
--quiet-q抑制拉取输出
--read-only将容器的根文件系统挂载为只读
--restartno容器退出时应用的重启策略
--rm容器退出时自动删除容器
--runtime要使用的运行时
--security-opt安全选项
--shm-size/dev/shm的大小
--sig-proxytrue将接收到的信号代理给进程
--stop-signal停止容器的信号
--stop-timeoutAPI 1.25+停止容器的超时时间
--storage-opt容器的存储驱动程序选项
--sysctlSysctl选项
--tmpfs挂载一个临时文件系统目录
--tty-t分配伪TTY
--ulimitUlimit选项
--user-u用户名或UID
--userns要使用的用户命名空间
--uts要使用的UTS命名空间
--volume-v绑定挂载一个卷
--volume-driver可选的卷驱动程序用于容器
--volumes-from从指定的容器中挂载卷
--workdir-w容器内的工作目录
示例
分配名称和分配伪终端(--name, -it)
docker run --name test -it debian
这个示例使用debian:latest镜像运行一个名为test的容器。选项-it告诉Docker分配一个连接到容器stdin的伪终端,从而在容器中创建一个交互式bash shell。示例通过输入exit 13来退出bash shell,将退出码传递给docker run的调用者,并记录在test容器的元数据中。
执行结果:
root@d6c0fe130dba:/# exit 13
echo $?
13
docker ps -a | grep test
d6c0fe130dba debian:7 "/bin/bash" 26 seconds ago Exited (13) 17 seconds ago test
这个例子创建了一个名为test的容器,并向控制台打印了test。cidfile标志使Docker尝试创建一个新文件并将容器ID写入其中。如果文件已经存在,则Docker返回错误。Docker在docker run退出时关闭此文件。
完整的容器权限(--privileged)
docker run -t -i --rm --privileged ubuntu bash
默认情况下,Docker会禁用大多数潜在危险的内核功能,包括需要CAP_SYS_ADMIN(用于挂载文件系统)的功能。然而,--privileged标志可以允许它运行。
docker run -t -i --privileged ubuntu bash
--privileged标志给予容器所有权限,并解除了设备cgroup控制器施加的所有限制。换句话说,容器可以做主机能做的几乎所有事情。这个标志存在是为了允许特殊的用例,比如在Docker内部运行Docker。
设置工作目录(-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。此选项仅适用于devicemapper、btrfs、overlay2、windowsfilter和zfs存储驱动程序。
对于overlay2存储驱动程序,仅当底层文件系统为xfs并使用pquota挂载选项挂载时,才可使用size选项。在这些条件下,可以传递小于底层文件系统大小的任何大小。
对于windowsfilter、devicemapper、btrfs和zfs存储驱动程序,无法传递小于默认BaseFS大小的大小。
挂载tmpfs(--tmpfs)
docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image
--tmpfs标志将一个空的tmpfs挂载到容器中,使用rw、noexec、nosuid和size=65536k选项。
挂载卷(-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
上面的示例将当前目录中的content目录绑定到容器的/content路径,使用-v标志,并将其设置为工作目录,然后在容器内部运行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二进制文件,您可以使容器完全访问并操作主机的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标志的详细信息以及与-v和--volume的比较,请参考Bind mounts。
尽管没有计划废弃--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 ubuntu bash
这将将容器的端口8080绑定到主机机器上127.0.0.1的TCP端口80。您还可以指定UDP和SCTP端口。Docker用户指南详细介绍了如何在Docker中使用端口。
请注意,未绑定到主机的端口(例如-p 80:80而不是-p 127.0.0.1:80:80)是外部可访问的。这也适用于如果配置了UFW来阻止此特定端口,因为Docker管理自己的iptables规则。
docker run --expose 80 ubuntu bash
这将公开容器的端口80,但不将该端口发布到主机系统的接口上。
设置拉取策略(--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)
使用-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)
标签是一个应用元数据到容器的键值对。要使用两个标签为容器打上标签:
docker run -l my-label --label com.example.foo=bar ubuntu bash
my-label键没有指定值,因此标签默认为空字符串("")。要添加多个标签,请重复-l或--label标志。
key=value必须是唯一的,以避免覆盖标签值。如果指定了具有相同键但不同值的标签,每个后续值都会覆盖先前的值。Docker使用您提供的最后一个key=value。
使用--label-file标志从文件中加载多个标签。在文件中的每个标签之间用EOL标记分隔。以下示例从当前目录中的labels文件加载标签:
docker run --label-file ./labels ubuntu bash
label-file格式与加载环境变量的格式类似(不同于环境变量,容器内运行的进程看不到标签)。以下示例显示了label-file格式:
com.example.label1="a label"
# this is a comment
com.example.label2=another\ label
com.example.label3
您可以通过提供多个--label-file标志来加载多个label-file。
有关使用标签的其他信息,请参阅Docker用户指南中的“Labels - custom metadata in Docker”部分。
连接容器到网络(--network)
要启动容器并将其连接到网络,请使用--network选项。
以下命令创建一个名为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
如果要将正在运行的容器添加到网络,请使用docker network connect子命令。
您可以将多个容器连接到同一网络。一旦连接,容器之间就可以使用另一个容器的IP地址或名称进行通信。对于支持多主机连接性的覆盖网络或自定义插件,连接到同一多主机网络但从不同引擎启动的容器也可以以这种方式通信。
请注意:
默认的桥接网络只允许容器使用内部IP地址相互通信。用户创建的桥接网络可提供容器名称的DNS解析。
您可以使用docker network disconnect命令断开容器与网络的连接。
有关在使用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使用私有未共享标签对内容进行标记。只有当前容器可以使用私有卷。
附加到STDIN/STDOUT/STDERR(-a, --attach)
--attach(或-a)标志告诉docker run绑定到容器的STDIN、STDOUT或STDERR。这使得可以根据需要操纵输出和输入。
echo "test" | docker run -i -a stdin ubuntu cat -
这将数据传送到容器,并通过仅连接到容器的STDIN来打印出容器的ID。
docker run -a stderr ubuntu echo test
这不会将任何内容打印到控制台,除非有错误发生,因为输出仅连接到容器的STDERR。容器的日志仍然存储写入STDERR和STDOUT的内容。
cat somefile | docker run -i -a stdin mybuilder dobuild
此示例演示了使用--attach通过管道将文件传送到容器中。命令在构建完成后打印出容器的ID,并可以使用docker logs检索构建日志。这在需要将文件或其他内容传送到容器中并在容器完成运行后检索容器的ID时非常有用。
另请参阅docker cp命令。
覆盖分离序列(--detach-keys)
使用--detach-keys选项可以覆盖Docker分离的键序列。如果Docker默认的序列与您用于其他应用程序的键序列冲突,这是很有用的。有两种方法来定义自己的分离键序列,作为每个容器的覆盖,或作为整个配置的配置属性。
要为单个容器覆盖序列,请使用带有--detach-keys="<sequence>"标志的docker attach命令。<sequence>的格式可以是一个字母[a-Z],或ctrl-加上以下任意组合:
a-z(一个小写字母)
@(at符号)
[(左方括号)
\(两个反斜杠)
_(下划线)
^(脱字符)
这些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 标志)中,并让应用程序直接访问它。
默认情况下,容器可以读取、写入和创建这些设备节点。可以使用每个 --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
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 选项不能安全地与临时设备一起使用。不应该将可能被移除的块设备添加到不受信任的容器中。
对于 Windows,--device 选项传递的字符串格式为 --device=<IdType>/<Id>。从 Windows Server 2019 和 Windows 10 October 2018 Update 开始,Windows 只支持类别(class)作为 IdType,并且 Id 是设备接口类 GUID。请参考 Windows 容器文档中定义的表格,以获取支持的容器设备接口类 GUID 的列表。
如果在独立进程隔离的 Windows 容器中指定此选项,Docker 会使所有实现请求的设备接口类 GUID 的设备在容器中可用。例如,下面的命令使主机上的所有 COM 端口在容器中可见:
PS C:\> docker run --device=class/86E0D1E0-8089-11D0-9CE4-08003E301F73 mcr.microsoft.com/windows/servercore:ltsc2019
使用动态创建的设备(--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 <minor>来创建所需的设备。
注意: - 您仍然需要显式地将最初存在的设备添加到docker run或docker create命令中。
访问NVIDIA GPU
--gpus标志允许您访问NVIDIA GPU资源。首先,您需要安装nvidia-container-runtime。
阅读有关指定容器资源的更多信息。
要使用--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"' nvidia-smi
## 重启策略(--restart)
使用 --restart 标志可以指定容器的重启策略。重启策略控制 Docker 守护程序在容器退出后是否重新启动它。Docker 支持以下重启策略:
策略结果
no容器退出时不自动重启。这是默认值。
on-failure[:max-retries]仅在容器以非零退出状态退出时重启。可以选择限制 Docker 守护程序尝试的重启次数。
unless-stopped除非显式停止容器或 Docker 本身停止或重启,否则重启容器。
always无论退出状态如何,始终重启容器。当指定 always 时,Docker 守护程序会无限次尝试重启容器。容器始终在守护程序启动时启动,不考虑容器的当前状态。
例如,以下命令将使用 always 重启策略运行 redis 容器,以便在容器退出时 Docker 会重新启动它:
docker run --restart=always redis
您可以在 Docker 运行参考页面的 Restart Policies (--restart) 部分中找到更详细的重启策略信息。
向容器的hosts文件添加条目(--add-host)
您可以使用一个或多个 --add-host 标志将其他主机添加到容器的 /etc/hosts 文件中。下面的示例在容器中为名为 docker 的主机添加了一个静态地址:
docker run --add-host=docker:93.184.216.34 --rm -it alpine
然后,您可以在容器内部使用该主机名进行访问。例如,在容器中执行 ping docker 命令会得到以下输出:
/ # ping docker
PING docker (93.184.216.34): 56 data bytes
64 bytes from 93.184.216.34: seq=0 ttl=37 time=93.052 ms
64 bytes from 93.184.216.34: seq=1 ttl=37 time=92.467 ms
64 bytes from 93.184.216.34: seq=2 ttl=37 time=92.252 ms
^C
--- docker ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 92.209/92.495/93.052 ms
--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
docker run \
--add-host host.docker.internal:host-gateway \
curlimages/curl -s host.docker.internal:8000/hello
输出结果:
hello from host!
在容器中设置ulimits(--ulimit)
由于在容器中设置ulimit设置需要额外的权限,在默认容器中不可用,您可以使用 --ulimit 标志来设置这些限制。以 <type>=<soft limit>[:<hard limit>] 的格式指定 --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会将这些值发送给适当的操作系统系统调用,并不执行任何字节转换。在设置这些值时要考虑到这一点。
对于 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] System error: resource temporarily unavailable" 错误。这是因为调用方将 nproc=3 设置为导致前三个容器使用了为 daemon 用户设置的三个进程配额。
使用信号停止容器(--stop-signal)
--stop-signal 标志向容器发送系统调用信号以退出。该信号可以是格式为 SIG<NAME> 的信号名称,例如 SIGKILL,或者与内核系统调用表中的位置相匹配的无符号数字,例如 9。
默认值由镜像中的 STOPSIGNAL 定义,如果镜像没有定义 STOPSIGNAL,则默认值为 SIGTERM。
例如,下面的命令将以 always 重启策略运行 redis 容器:
docker run --restart=always redis
您可以在 Docker 运行参考页面的 Restart Policies (--restart) 部分中找到更详细的重启策略信息。
可选的安全选项(--security-opt)
在 Windows 上,您可以使用该标志来指定 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 上,唯一支持的选项是使用 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 Server 操作系统上,默认的隔离技术是 process,在 Windows 客户端操作系统(如 Windows 10)上是 hyperv。Process 隔离性能更好,但要求镜像和主机使用相同的内核版本。
在 Windows Server 上,假设默认配置情况下,这些命令是等效的,并且都使用了 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 上,根据您使用的隔离类型,容器会以不同的方式受到影响。
对于进程隔离,在 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 上会创建一个足够大的实用虚拟机来容纳内存限制,以及托管容器所需的最小操作系统。该大小被报告为 "Total Physical Memory"。
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
注意: - 并非所有的 sysctl 都具有命名空间。Docker 不支持同时修改容器内部和主机系统的 sysctl。随着内核的演进,我们预计会看到更多的 sysctl 变得具有命名空间。
目前支持的 sysctl: IPC 命名空间: - kernel.msgmax - kernel.msgmnb - kernel.msgmni - kernel.sem - kernel.shmall - kernel.shmmax - kernel.shmmni - kernel.shm_rmid_forced 以 fs.mqueue.* 开头的 sysctl
如果使用 --ipc=host 选项,则不允许使用这些 sysctl。
网络命名空间: 以 net.* 开头的 sysctl
如果使用 --network=host 选项,则不允许使用这些 sysctl。