作者:半身风雪
上一节:带你跨入Docker的世界
简介:本节内容共计一万六千字,我将带领大家,学会docker run 系列的命令,通过命令大纲,再通过一个个的例子,和大家一同学习。

Docker 掌握核心技术

  • 一、docker run 简介
  • 二、docker run 命令集
  • 三、实例测试
    • 3.1、分配名称并分配pseudo-TTY(–name,-it)
    • 3.2、记录容器ID(–cidfile)
    • 3.3、完整的容器功能 (–privileged)
    • 3.4、设置工作目录 (-w)
    • 3.5、为每个容器设置存储驱动程序选项
    • 3.6、Mount tmpfs (–tmpfs)
    • 3.7、Mount volume (-v, –read-only)
    • 3.8、使用–mount flag
    • 3.9、发布或公开端口(-p,–expose)
    • 3.10、设置pull策略(–pull)
    • 3.11、设置环境变量(-e,–env,–env-file)
    • 3.12、在容器上设置元数据(-l,–label,–label-file)
    • 3.13、将容器连接到网络(–网络)
    • 3.14、从容器中安装卷(–volumes-from)
    • 3.15、附加到STDIN/STDOUT/STDERR(-a)
    • 3.16、将主机设备添加到容器(–device)
    • 3.17、使用动态创建的设备(–device-cgroup-rule)
    • 3.18、访问NVIDIA GPU
    • 3.19、重启策略(–restart)
    • 3.20、将条目添加到容器主机文件(–add-host)
    • 3.21、在容器中设置ulimits(–ulimit)
    • 3.22、对于nproc使用
    • 3.22、带有信号的停止容器(–stop-signal)
    • 3.23、可选的安全选项(–security-opt)
    • 3.24、停止带超时的容器(–停止超时)
    • 3.25、指定容器的隔离技术(–隔离)
    • 3.26、指定容器可用内存的硬限制(-m,–memory)
    • 3.27、在运行时配置命名空间内核参数(sysctls)

一、docker run 简介

docker run命令可以与docker commit命令结合使用,以改变容器运行的命令。

$ docker run [OPTIONS] IMAGE [COMMAND] [ARG…]

docker run命令首先在指定映像上creates可写的容器层,然后使用指定的命令starts它。也就是说,docker run等价于API /containers/create然后/containers/(id)/start。使用docker start,可以重新启动已停止的容器,并保存之前的更改。

二、docker run 命令集

这里的命令集比较多,如果你不太喜欢的话,可以迅速下滑值实例讲解区。我之所以把它放在最前面,是因为,我们以后要一直和它们交到,是需要熟悉的核心。

Name, shorthandDescription
–add-host添加自定义主机到IP映射(host:ip)
–attach , -a连接到STDIN、STDOUT或STDERR
–blkio-weight块IO(相对重量),在10到1000之间,或0禁用(默认0)
–blkio-weight-deviceBlock IO重量(相对设备重量)
–cap-add添加Linux功能
–cap-drop删除Linux功能
–cgroup-parent容器的可选父cgroup
–cgroupns(API 1.41+才新增)要使用的C组命名空间(host
–cidfile将容器ID写入文件
–cpu-countCPU计数(仅限Windows)
–cpu-percentCPU百分比(仅限Windows)
–cpu-period限制CPU CFS(完全公平的调度器)期限
–cpu-quota限制CPU CFS(完全公平的调度器)配额
–cpu-rt-period将CPU实时周期限制在微秒内
–cpu-rt-runtime将CPU实时运行时间限制在微秒内
–cpu-shares , -cCPU份额(相对权重)
–cpusCPU数量
–cpuset-cpus允许执行的CPU(0-3,0,1)
–cpuset-mems允许执行的MEM(0-3,0,1)
–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-trust跳过图像验证
–dns设置自定义DNS服务器
–dns-opt设置DNS选项
–dns-option设置DNS选项
–dns-search设置自定义DNS搜索域
–domainnameContainer NIS域名
–entrypoint覆盖图像的默认ENTRYPOINT
–env , -e设置环境变量
–env-file在环境变量文件中读取
–expose暴露一个端口或一系列端口
–gpus(IPI 1.40+)要添加到容器中的GPU设备(“全部”用于传递所有GPU)
–group-add添加其他组加入
–health-cmd命令运行以检查当前状态
–health-interval运行检查之间的时间(ms
–health-retries报告不健康需要连续失败
–health-start-period容器在开始健康再试倒计时前初始化的开始周期(ms
–health-timeout允许运行一个检查的最大时间(ms
–help打印使用情况
–hostname , -h容器主机名
–init在容器内运行init,转发信号并收割流程
–interactive , -i即使没有连接,也要保持STDIN打开
–io-maxbandwidth系统驱动器的最大IO带宽限制(仅限Windows)
–io-maxiops系统驱动器的最大 IOps 限制(仅限 Windows)
–ipIPv4地址(例如,172.30.100.104)
–ip6IPv6地址(例如,2001:db8:33)
–ipc使用的IPC模式
–isolation容器隔离技术
–kernel-memory内核内存限制
–label , -l在容器上设置元数据
–label-file在行分隔的标签文件中阅读
–link添加指向另一个容器的链接
–link-local-ip容器IPv4/IPv6链路本地地址
–log-driver容器的日志驱动程序
–log-opt记录驱动程序选项
–mac-address容器MAC地址(例如,92:d0:c6:0a:29:33)
–memory , -m内存限制
–memory-reservation内存软限制
–memory-swap交换限制等于内存加交换:“-1”以启用无限交换
–memory-swappiness调整容器内存交换(0到100)默认为 -1
–mount将文件系统挂载附加到容器中
–name为容器分配名称
–net将容器连接到网络
–net-alias为容器添加网络范围的别名
–network将容器连接到网络
–network-alias为容器添加网络范围的别名
–no-healthcheck禁用任何容器指定的HEALTHCHECK
–oom-kill-disable禁用OOM杀手
–oom-score-adj调整主机的OOM首选项(-1000至1000)
–pid要使用的PID命名空间
–pids-limit调整容器pids限制(无限设置-1)
–platform如果服务器支持多平台,请设置平台
–privileged授予此容器扩展权限
–publish , -p将容器的端口发布到主机
–publish-all , -P将所有公开的端口发布到随机端口
–pull运行前拉取图像(“always”,“missing”,“never”)默认(“missing”)
–read-only将容器的根文件系统装载为只读
–restart重新启动策略,以便在容器退出时应用 默认(No)
–rm容器退出时自动取出
–runtime用于此容器的运行时
–security-opt安全选项
–shm-size/dev/shm的大小
–sig-proxy代理收到该过程的信号 默认 true
–stop-signal停止容器的信号 默认 SIGTERM
–stop-timeout暂停(以秒为单位)以阻止容器
–storage-opt容器的存储驱动程序选项
–sysctlSysctl选项
–tmpfs挂载tmpfs目录
–tty , -t分配 pseudo-TTY
–ulimit限制选项
–user , -u用户名或UID (format: <name
–userns要使用的用户命名空间
–uts要使用的UTS命名空间
–volume , -v绑定安装卷
–volume-driver容器的可选音量驱动程序
–volumes-from从指定的容器中挂载卷
–workdir , -w容器内的工作目录

呼!累死宝宝了,,,这里的命令类型真的太多了。

三、实例测试

3.1、分配名称并分配pseudo-TTY(–name,-it)

我们先来创建一个使用debian:latest映像运行一个名为test的容器。-it 指示Docker分配一个pseudo-TTY 连接到容器的stdin;在容器中创建一个交互式bash shell

$ docker run –name test -it debian
root@d6c0fe130dba:/# exit 13
$ echo $?
13
$ docker ps -a | grep test
a131d2951e84 debian “bash” About a minute ago Exited (13) About a minute ago test

在上面命令中,输入exit 13退出bash shell。这个退出代码被传递给docker运行的调用者,并记录在测试容器的元数据中。

3.2、记录容器ID(–cidfile)

$ ocker run –cidfile /tmp/docker_test.cid ubuntu echo “test”

创建一个容器,并将test打印到控制台。cidfile标志使Docker尝试创建一个新文件,并将容器ID写入其中。如果文件已经存在,Docker将返回错误。Docker将在docker run退出时关闭此文件。

3.3、完整的容器功能 (–privileged)

$ docker run -t -i --rm ubuntu bash

上面的命令结果运行,直接提示我们没有权限,因为默认情况下,这是直接删除内核功能;包括cap_sys_admin(挂载文件系统需要)。然而,–privileged标志将允许它运行:

--privileged标志赋予容器所有功能,它还解除了devicecgroup控制器执行的所有限制。换句话说,容器几乎可以做主机能做的一切。此标签的存在是为了允许特殊用例,例如在Docker中运行Docker。

3.4、设置工作目录 (-w)

$ docker run -w /path/to/dir/ -i -t ubuntu pwd

-w允许在给定的目录内执行命令,此处为/path/to/dir/。如果路径不存在,则在容器内创建。

3.5、为每个容器设置存储驱动程序选项

$ docker run -it –storage-opt size=120G fedora /bin/bash

这个(size)将允许在创建时将容器rootfs大小设置为120G。此选项仅适用于devicemapper、btrfs、overlay2、windowsfilter和zfs图形驱动。对于devicemapper, btrfs, windowsfilter和zfs图形驱动,用户不能传递小于默认BaseFS 的大小。对于overlay2存储驱动程序,只有当备份文件fs是xfs并且使用pquota挂载选项挂载时,size选项才可用。在这些条件下,用户可以传递任何小于备份文件大小的大小。

3.6、Mount tmpfs (–tmpfs)

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

--tmpfs标志将一个空的tmpfs装入容器中,其中包含rw、noexec、nosuid、size=65536k选项

3.7、Mount volume (-v, –read-only)

$ docker run -v pwd:pwd -w pwd -i -t ubuntu pwd

-v标志将当前工作目录挂载到容器中。-w允许在当前工作目录中执行命令,方法是将命令更改为pwd返回的值。因此,此组合使用容器执行命令,但在当前工作目录中。

$ docker run -v /doesnt/exist:/foo -w /foo -i -t ubuntu bash

当绑定式卷的主机目录不存在时,Docker将自动在主机上为您创建此目录。在上面的示例中,Docker将在启动容器之前创建/doesnt/exist文件夹。

$ docker run –read-only -v /icanwrite busybox touch /icanwrite/here

Volumes 可以与--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 …

3.8、使用–mount flag

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

3.9、发布或公开端口(-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,而无需将端口发布到主机系统的接口。

3.10、设置pull策略(–pull)

在创建(和运行)容器时,使用--pull标志设置图像拉取策略。

--pull标志可以接受以下值之一:

ValueDescription
missing(默认)如果在图像缓存中找不到图像,请将其拉出,否则请使用缓存的图像。
never不要拉动图像,即使它丢失了,如果图像缓存中不存在图像,也会产生错误。
always在创建容器之前,请务必执行拉取。

从映像创建(和运行)容器时,守护进程会检查图像是否存在于本地映像缓存中。如果图像丢失,则会向cli返回错误,允许它启动拉取。

默认(missing)是仅在守护进程的图像缓存中不存在图像时提取图像。此默认值允许您运行仅在本地存在的映像(例如,您从Dockerfile构建但尚未推送到注册表的映像),并减少了网络。

在创建容器之前,always选项会启动拉取。此选项确保图像是最新的,并防止您使用过时的图像,但可能不适合在推送之前测试本地构建的图像(因为拉取图像会覆盖图像缓存中的现有图像)。

创建容器时,never选项禁用(隐式)提取图像,并且仅使用图像缓存中可用的图像。如果找不到指定的映像,则会产生错误,并且不会创建容器。此选项在网络不可用的情况下非常有用,或者可以防止在创建容器时隐式提取图像。

下面的例子显示了docker在运行时设置了——pull=never选项,这会产生一个错误,因为图像在图像缓存中丢失了:

$ docker run –pull=never hello-world

3.11、设置环境变量(-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 VA

您还可以使用已导出到本地环境的变量:

$ docker run –env VAR1 –env VAR2 ubuntu env | grep VAR

运行该命令时,Docker CLI客户端会检查变量在本地环境中的值,并将其传递给容器。如果未提供=,并且该变量未在本地环境中导出,则不会在容器中设置该变量。

您还可以从文件中加载环境变量。此文件应使用语法=value(将变量设置为给定值)或(从本地环境中获取值),以及**#**作为注释。

3.12、在容器上设置元数据(-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

标签文件格式与加载环境变量的格式相似。(与环境变量不同,在容器内运行的进程看不到标签。)以下示例说明了标签文件格式:

您可以通过提供多个--label-file标志来加载多个标签文件。

3.13、将容器连接到网络(–网络)

当您启动容器时,请使用--network标志将其连接到网络。这将busybox容器添加到my-net网络中。

$ docker run -itd –network=my-net busybox

当您在用户定义的网络上启动容器时,您还可以选择带有--ip和--ip6标志的容器的IP地址。

$ docker run -itd –network=my-net –ip=10.10.9.75 busybox

如果您想向网络添加正在运行的容器,请使用docker network connect子命令。

您可以将多个容器连接到同一网络。连接后,容器只能使用另一个容器的IP地址或名称轻松通信。对于支持多主机连接的overlay网络或自定义插件,连接到同一多主机网络但从不同引擎启动的容器也可以以这种方式通信。

默认网桥接网络上无法发现服务。默认情况下,容器可以通过其IP地址进行通信。要通过姓名进行沟通,必须链接。

您可以使用docker network disconnect命令断开容器与网络的连接。

3.14、从容器中安装卷(–volumes-from)

$ docker run –volumes-from 777f7dc92da7 –volumes-from ba8c0c54f0f2:ro -i -t ubuntu pwd

--volumes-from标志挂载所引用容器中的所有已定义。容器可以通过重复--volume -from参数来指定。容器ID后面可以加上“:ro”或“:rw”,分别以只读或读写方式挂载卷。默认情况下,卷的挂载方式与参考容器相同(可读可写或只读)。

像SELinux这样的标签系统要求在安装在容器中的卷内容上放置适当的标签。如果没有标签,安全系统可能会阻止容器内运行的进程使用内容。默认情况下,Docker不会更改操作系统设置的标签。

要在容器上下文中更改标签,您可以在卷挂载中添加两个后缀:z或:Z中的任何一个。这些后缀告诉Docker在共享卷上重新标记文件对象。z选项告诉Docker,两个容器共享卷内容。因此,Docker用共享内容标签对内容进行标签。共享卷标签允许所有容器读取/写入内容。Z选项告诉Docker用私有未共享标签对内容进行标签。只有当前容器可以使用私有卷。

3.15、附加到STDIN/STDOUT/STDERR(-a)

-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

这就是构建时将文件管道到容器中的方式。构建完成后,容器的ID将被打印,并且可以使用docker logs检索构建日志。如果您需要将文件或其他东西管道到容器中,并在容器运行完成后检索容器的ID,这非常有用。

3.16、将主机设备添加到容器(–device)

通常需要将设备直接暴露在容器中。--device选项启用了此功能。例如,可以将特定的块存储设备或循环设备或音频设备添加到其他非特权容器中(没有--privileged标志),并让应用程序直接访问它。

默认情况下,容器将能够read、write和mknod这些设备。这可以使用每个--device标志的第三组:rwm选项来重写。如果容器以特权模式运行,则指定的权限将被忽略。

--device选项无法安全地与短暂的设备一起使用。不得将可能删除的块设备添加到带有--device不受信任的容器中。

对于Windows,传递给–device选项的字符串格式为--device=/。从Windows Server 2019和Windows 10 2018年10月更新开始,Windows仅支持IdTypeclass和作为设备接口类GUID的ID。有关容器支持的设备接口类GUID的列表,请参阅Windows容器文档中定义的表。

如果为进程隔离的Windows容器指定了此选项,则容器中提供了所有实现请求的设备接口类GUID的设备。例如,下面的命令使主机上的所有COM端口在容器中可见。

PS C:> docker run –device=class/86E0D1E0-8089-11D0-9CE4-08003E301F73 mcr.microsoft.com/windows/servercore:ltsc2019

--device选项仅在进程隔离的Windows容器上受支持。如果容器隔离为hyperv或在Windows(LCOW)上运行Linux容器时,此选项将失败。

3.17、使用动态创建的设备(–device-cgroup-rule)

容器可用的设备在创建时被分配。分配的设备将添加到cgroup.allow文件中,并在运行后创建到容器中。当需要将新设备添加到正在运行的容器时,这会带来问题。

解决方案之一是为容器添加更宽松的规则,允许它访问更广泛的设备。例如,假设我们的容器需要访问大数42和任何次要数字的字符设备(在新设备出现时添加),将添加以下规则:

$ docker run -d –device-cgroup-rule=‘c 42:* rmw’ -name my-container my-image

然后,用户可以要求udev执行一个脚本,docker执行my-container mknod newDevX c 42 添加所需的设备。

最初的设备仍然需要显式地添加到docker run / docker create命令中。

3.18、访问NVIDIA GPU

--gpus标志允许您访问NVIDIA GPU资源。首先,您需要安装nvidia-container-runtime。有关更多信息,请访问指定容器的资源。

要使用--gpus,请指定要使用哪些GPU(或全部)。如果没有提供值,则使用所有可用的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

3.19、重启策略(–restart)

使用Docker的–restart指定容器的重新启动策略。重新启动策略控制Docker守护进程在退出后是否重新启动容器。Docker支持以下重新启动策略:

PolicyResult
no容器退出时不要自动重新启动。这是默认值。
on-failure[:max-retries]仅当容器以非零退出状态退出时,才重新启动。或者,限制重试Docker守护进程尝试的次数。
unless-stopped重新启动容器,除非它被显式停止或Docker本身被停止或重新启动。
always无论退出状态如何,请务必重新启动容器。当您始终指定时,Docker守护进程将尝试无限期地重新启动容器。无论容器的当前状态如何,容器也将始终在守护进程启动时启动。

$ docker run –restart=always redis

这将运行具有始终重新启动策略的redis容器,这样如果容器退出,Docker将重新启动它。

3.20、将条目添加到容器主机文件(–add-host)

您可以使用一个或多个--add-host标志将其他主机添加到容器的/etc/hosts文件中。此示例为名为docker的主机添加了静态地址:

有时,您需要从容器内连接到Docker主机。要启用此功能,请使用--add-host标志将Docker主机的IP地址传递给容器。要查找主机的地址,请使用ip addr show命令。

您传递给ip addr show的标志取决于您在容器中使用IPv4还是IPv6网络。对于名为eth0的网络设备,请使用以下标志进行IPv4地址检索:

$ HOSTIP=ip -4 addr show scope global dev eth0 | grep inet | awk '{print $2}' | cut -d / -f 1 | sed -n 1p
$ docker run –add-host=docker:${HOSTIP} –rm -it debian

对于IPv6,请使用-6标志而不是-4标志。对于其他网络设备,请将eth0替换为正确的设备名称(例如,桥接设备的docker0)。

3.21、在容器中设置ulimits(–ulimit)

由于在容器中设置ulimit设置需要默认容器中不可用的额外权限,您可以使用--ulimit标志设置这些权限。--ulimit使用软限制和硬限制指定如下:=[:],例如:

$ docker run –ulimit nofile=1024:1024 –rm debian sh -c “ulimit -n”

如果您不提供hard limit,soft limit将用于这两个值。如果没有设置ulimits,它们将从守护进程上设置的默认ulimits继承。as选项现已禁用。换句话说,不支持以下脚本:

$ docker run -it –ulimit as=1024 fedora /bin/bash

值在设置时发送到适当的syscall。Docker不执行任何字节转换。在设置值时考虑到这一点。

3.22、对于nproc使用

小心使用ulimit标志设置nproc,因为nproc是由Linux设计的,可以设置用户使用的最大进程数量,而不是容器。例如,使用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

第4个容器失败,并报告“[8]系统错误:资源暂时不可用”错误。这失败是因为调用者setnprocnproc=3导致前三个容器用完了为daemon用户设置的三个进程配额。

3.22、带有信号的停止容器(–stop-signal)

--stop-signal标志设置系统调用信号,该信号将发送到容器退出。此信号可以是SIG格式的信号名称,例如SIGKILL,也可以是与内核syscall表中位置匹配的无符号数字,例如9。

如果没有指定,默认值为SIGTERM

3.23、可选的安全选项(–security-opt)

在Windows上,此标志可用于指定 credentialspec选项。credentialspec必须位于formatfilefile://spec.txt或registry://keyname

3.24、停止带超时的容器(–停止超时)

--stop-timeout标志设置了发送预定义(见--stop-signal)系统调用信号后等待容器停止的秒数。如果容器在超时后没有退出,它将被SIGKILL信号强行杀死。

如果--stop-timeout设置为-1,则不应用超时,守护进程将无限期等待容器退出。

默认值由守护进程决定,Linux容器为10秒,Windows容器为30秒。

3.25、指定容器的隔离技术(–隔离)

此选项在Windows上运行Docker容器的情况下非常有用。--isolation=选项设置容器的隔离技术。在Linux上,唯一支持的是使用Linux命名空间的default选项。这两个命令在Linux上是等效的:

$ docker run -d busybox top
$ docker run -d –isolation default busybox top

在Windows上,–isolation可以采用以下值之一:

ValueDescription
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

如果您在Dockerdaemon上设置了--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

3.26、指定容器可用内存的硬限制(-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

3.27、在运行时配置命名空间内核参数(sysctls)

--sysctl在容器中设置命名空间内核参数(sysctls)。例如,要在容器网络命名空间中打开IP转发,请运行以下命令:

$ docker run –sysctl net.ipv4.ip_forward=1 someimage

并非所有系统都具有命名空间。Docker不支持在也修改主机系统的容器内更改系统。随着内核的发展,我们会看到更多的系统符号成为命名空间。
目前支持的sysctls
IPC命名空间:

kernel.msgmax,kernel.msgmnb,kernel.msgmni,kernel.sem,
kernel.shmall,kernel.shmmax,kernel.shmmni,
kernel.shm_rmid_forced。
Sysctls以fs.mqueue.*

如果您使用–ipc=host选项,则不允许使用这些sysctls。
网络命名空间:

Sysctls以net.*

如果您使用–network=host选项,则不允许使用这些系统。