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 | 附加到标准输入、标准输出或标准错误 | |
--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 | 允许执行操作的 MEMs (0-3, 0,1) | |
-d, --detach | 在后台运行容器并打印容器 ID | |
--detach-keys | 覆盖用于分离容器的按键序列 | |
--device | 向容器添加主机设备 | |
--device-cgroup-rule | 向 cgroup 允许设备列表添加规则 | |
--device-read-bps | 限制设备的读取速率(字节/秒) | |
--device-read-iops | 限制设备的读取速率(每秒 I/O 操作数) | |
--device-write-bps | 限制设备的写入速率(字节/秒) | |
--device-write-iops | 限制设备的写入速率(每秒 I/O 次数) | |
--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 | 分配伪终端 | |
--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附加到
my-nginx容器的进程 ID 为 1 的进程:/ # 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 containerUTS 命名空间用于设置在该命名空间中运行的进程可见的主机名和域名。默认情况下,所有容器,包括带有 --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。 |
| "私有" | 私有 IPC 命名空间。 |
| "可共享" | 拥有私有的 IPC 命名空间,并可以与其他容器共享。 |
| "container:<name-or-ID>" | 加入另一个(“可共享”)容器的 IPC 命名空间。 |
| "主机" | 使用主机系统的 IPC 命名空间。 |
如果未指定,则使用守护进程默认值,该值可以是 "private"
或 "shareable",具体取决于守护进程版本和配置。
System V 进程间通信 (IPC) namespaces 提供了对命名共享内存段、信号量和消息队列的隔离。
共享内存段用于以内存速度加速进程间通信,而不是通过管道或网络协议栈。共享内存通常被数据库和定制构建(通常为 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
此选项在创建时将容器文件系统大小限制为 120G。
此选项仅适用于 btrfs、overlay2、windowsfilter
和 zfs 存储驱动程序。
对于 overlay2 存储驱动程序,size 选项仅当后备文件系统为 xfs 且挂载时使用了 pquota 挂载选项时才可用。
在这些条件下,您可以传递任何小于后备文件系统大小的 size 参数。
对于 windowsfilter、btrfs 和 zfs 存储驱动,您不能传递小于默认 BaseFS 大小的大小。
挂载 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 Binaries(参考 获取 Linux Binaries), 您授予容器创建和操作主机 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 键未指定值,因此标签默认为空字符串 ("")。要添加多个标签,请重复使用 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
sysctl 个以 net.ipv4.、net.ipv6. 或 net.mpls. 开头的设置可以使用带有 driver-opt 标签的 com.docker.network.endpoint.sysctls 按接口进行设置。
接口名称必须是字符串 IFNAME。
要为接口设置多个sysctl,请引用整个driver-opt字段,
必要时记得为 shell 转义引号。例如,如果
接口my-net被命名为eth0,以下示例将设置 sysctls
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)标志将容器作为后台进程启动,不会占用您的终端窗口。按设计,以分离模式启动的容器在用于运行容器的根进程退出时也会退出,除非您还指定了 --rm 选项。如果您使用 -d 配合 --rm,则当容器退出或守护进程退出时(以先发生的为准),该容器将被移除。
不要向分离容器传递 service x start 命令。例如,
此命令尝试启动 nginx 服务。
$ docker run -d -p 80:80 my_image service nginx start
这成功地在容器内启动了nginx服务。然而,它违反了分离式容器的范式,因为根进程(service nginx start)返回后,按设计预期的分离式容器会停止。结果是,nginx服务虽然启动,但无法使用。相反,若要启动类似nginx的 Web 服务器这样的进程,请执行以下操作:
$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'
\n要与分离的容器进行输入/输出操作,请使用网络连接或共享卷。这是必需的,因为容器不再监听运行docker run的命令行。
覆盖分离序列 (--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标志)中,并让应用程序直接访问它。
默认情况下,容器能够 read、write 和 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,传递给 --device 选项的字符串格式为 --device=<IdType>/<Id>。从 Windows Server 2019 和 Windows 10 2018 年 10 月更新版本开始,Windows 仅支持 IdType 为 class,且 Id 为
设备接口类 GUID。
有关容器支持的接口类 GUID 列表,请参阅
Windows 容器文档中定义的表格。
如果您为进程隔离的 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 规范(JSON 或 YAML 文件) 在运行守护进程的系统上,位于其中一个配置的 CDI 规范目录中。
- CDI 功能已在守护进程中启用;请参见 启用 CDI 设备。
附加到标准输入/标准输出/标准错误 (-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 -
\n以下示例不会向控制台输出任何内容,除非发生错误,因为输出仅附加到容器的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 标志来指示将初始化进程用作容器中的 PID 1。指定一个初始化进程可确保在创建的容器内执行初始化系统的常规职责,例如回收僵尸进程。
默认使用的初始化进程是 Docker 守护进程系统路径中找到的第一个docker-init可执行文件。此docker-initBinaries包含在默认安装中,由
tini支持。
分配伪终端 (-t, --tty)
--tty(或 -t)标志将伪终端(pseudo-TTY)附加到容器,将您的终端连接到容器的 I/O 流。为容器分配伪终端意味着您可以获得 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 标志。这仍会为容器分配一个伪终端,但无法向 STDIN 写入。仅在容器的输出需要 TTY 环境时,此操作可能有用。
指定自定义 cgroups
使用 --cgroup-parent 标志,您可以将特定的 cgroup 指定为容器的运行环境。这允许您独立创建和管理 cgroup。您可以为这些 cgroup 定义自定义资源,并将容器置于一个共同的父组之下。
使用动态创建的设备(--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
The --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 支持以下重启策略:
| Flag | 描述 |
|---|---|
no | 不要自动重启容器。(默认) |
on-failure[:max-retries] | 如果容器因错误(表现为非零退出代码)而退出,则重新启动容器。可以选择使用 :max-retries 选项限制 Docker 守护进程尝试重启容器的次数。on-failure 策略仅在容器因故障退出时提示重新启动。如果守护进程重新启动,它不会重新启动容器。 |
always | 如果容器停止,请始终重新启动它。如果它是手动停止的,则仅在 Docker 守护进程重启或容器本身被手动重启时才会重新启动。 |
unless-stopped | 与 always 类似,不同之处在于当容器停止(手动或其他方式)时,即使在 Docker 守护进程重启后也不会重新启动。 |
$ docker run --restart=always redis
这将启动 redis 容器,并设置重启策略为 always。
如果容器退出,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会无限次尝试重启容器。
以下示例运行 redis 容器,并设置重启策略为
on-failure,最大重启次数为 10。
$ 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 守护进程不同的日志驱动程序。使用
--log-driver=<DRIVER> 配合 docker run 命令来配置
容器的日志驱动程序。
要了解支持的日志驱动程序及其使用方法,请参阅 配置日志驱动程序。
\n要禁用容器的日志记录,请将 --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 的使用
设置 nproc 时请小心使用 ulimit 标志,因为 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,也可以是匹配内核系统调用表中位置的无符号数字,例如 9。
默认值由
STOPSIGNAL
在镜像中定义,或者如果镜像未定义STOPSIGNAL,则为SIGTERM。
可选安全选项 (--security-opt)
| 选项 | 描述 |
|---|---|
--security-opt="label=user:USER" | 为容器设置用户标签 |
--security-opt="label=role:ROLE" | 为容器设置标签 role |
--security-opt="label=type:TYPE" | 设置容器的标签类型 |
--security-opt="label=level:LEVEL" | 设置容器的标签级别 |
--security-opt="label=disable" | \n关闭容器的标签限制 |
--security-opt="apparmor=PROFILE" | 设置要应用于容器的 AppArmor 配置文件 |
--security-opt="no-new-privileges=true" | 禁止容器进程获取新权限 |
--security-opt="seccomp=unconfined" | \n关闭容器的 seccomp 限制 |
--security-opt="seccomp=builtin" | 使用默认的(内置)seccomp 配置文件以运行容器。这可用于在守护进程上启用 seccomp,即使该守护进程设置了自定义默认配置文件,或 seccomp 处于禁用状态("unconfined")。 |
--security-opt="seccomp=profile.json" | 白名单系统调用 seccomp JSON 文件,用作 seccomp 过滤器 |
--security-opt="systempaths=unconfined" | \n关闭容器对系统路径(屏蔽路径、只读路径)的强制限制 |
--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 Server 操作系统上的默认隔离级别为 process,而在 Windows 客户端操作系统(如 Windows 10)上则为 hyperv。进程隔离具有更好的性能,但要求镜像和主机使用相同的内核版本。
在 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 daemon 上设置了 --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)
The --sysctl 设置容器内命名空间的内核参数(sysctls)。例如,要在容器的网络命名空间中启用 IP 转发,请运行以下命令:
$ docker run --sysctl net.ipv4.ip_forward=1 someimage
注意
并非所有 sysctl 都是命名空间隔离的。Docker 不支持在容器内修改那些会同时影响主机系统的 sysctl 参数。随着内核的演进,我们预期会有更多的 sysctl 实现命名空间隔离。
当前支持的 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选项,则不允许这些 sysctl 参数。
网络命名空间:
- Sysctls 以
net.*开头 - 如果您使用
--network=host选项,则不允许使用这些 sysctl 参数。