docker container run

描述從映象建立並執行一個新容器
用法docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
別名
docker run

描述

docker run 命令在新容器中執行命令,如果需要則拉取映象並啟動容器。

您可以使用 docker start 重新啟動一個已停止的容器,並保留其所有之前的更改。使用 docker ps -a 檢視所有容器的列表,包括已停止的容器。

選項

選項預設值描述
--add-host新增自定義主機到 IP 對映 (host:ip)
--annotationAPI 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
--cgroupnsAPI 1.41+ 要使用的 Cgroup 名稱空間(host|private)
'host':在 Docker 主機的 cgroup 名稱空間中執行容器
'private':在自己的私有 cgroup 名稱空間中執行容器
'':使用守護程序上
default-cgroupns-mode 選項配置的 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 即時執行時(微秒)
-c, --cpu-sharesCPU 共享(相對權重)
--cpusAPI 1.25+ CPU 數量
--cpuset-cpus允許執行的 CPU (0-3, 0,1)
--cpuset-mems允許執行的記憶體(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-trusttrue跳過映象驗證
--dns設定自定義 DNS 伺服器
--dns-option設定 DNS 選項
--dns-search設定自定義 DNS 搜尋域
--domainname容器 NIS 域名
--entrypoint覆蓋映象的預設 ENTRYPOINT
-e, --env設定環境變數
--env-file從檔案讀取環境變數
--expose暴露一個埠或一系列埠
--gpusAPI 1.40+ 要新增到容器的 GPU 裝置('all' 表示傳遞所有 GPU)
--group-add新增要加入的額外組
--health-cmd執行以檢查健康的命令
--health-interval執行檢查之間的時間(毫秒|秒|分|小時)(預設 0s)
--health-retries報告不健康狀態所需的連續失敗次數
--health-start-intervalAPI 1.44+ 在啟動期間執行檢查之間的時間(毫秒|秒|分|小時)(預設 0s)
--health-start-periodAPI 1.29+ 容器在開始健康重試倒計時之前初始化的啟動週期(毫秒|秒|分|小時)(預設 0s)
--health-timeout允許一次檢查執行的最長時間(毫秒|秒|分|小時)(預設 0s)
--help列印使用說明
-h, --hostname容器主機名
--initAPI 1.25+ 在容器內部執行一個 init 程序,它轉發訊號並回收程序
-i, --interactive即使未連線也保持 STDIN 開啟
--io-maxbandwidth系統驅動器的最大 IO 頻寬限制(僅限 Windows)
--io-maxiops系統驅動器的最大 IOPS 限制(僅限 Windows)
--ipIPv4 地址(例如,172.30.100.104)
--ip6IPv6 地址(例如,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調整容器 PID 限制(設定為 -1 表示無限制)
--platformAPI 1.32+ 如果伺服器支援多平臺,則設定平臺
--privileged為此容器授予擴充套件許可權
-p, --publish將容器的埠釋出到主機
-P, --publish-all將所有暴露的埠釋出到隨機埠
--pull缺失執行前拉取映象(alwaysmissingnever
-q, --quiet抑制拉取輸出
--read-only將容器的根檔案系統掛載為只讀
--restartno容器退出時應用的重啟策略
--rm容器退出時自動刪除容器及其關聯的匿名卷
--runtime此容器使用的執行時
--security-opt安全選項
--shm-size/dev/shm 的大小
--sig-proxytrue將接收到的訊號代理到程序
--stop-signal停止容器的訊號
--stop-timeoutAPI 1.25+ 停止容器的超時時間(秒)
--storage-opt容器的儲存驅動程式選項
--sysctlSysctl 選項
--tmpfs掛載 tmpfs 目錄
-t, --tty分配一個偽 TTY
--ulimitUlimit 選項
--use-api-socket繫結掛載 Docker API socket 和所需的認證
-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"

這會建立一個容器並向控制檯列印 testcidfile 標誌使 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。

在某些情況下,您希望容器共享主機的程序名稱空間,允許容器內的程序檢視系統上的所有程序。例如,您可以構建一個包含 stracegdb 等除錯工具的容器,但希望在除錯容器內的程序時使用這些工具。

示例:在容器內執行 htop

要在共享主機程序名稱空間的容器中執行 htop

  1. 執行帶有 --pid=host 選項的 alpine 容器

    $ docker run --rm -it --pid=host alpine
    
  2. 在容器中安裝 htop

    / # apk add --quiet htop
    
  3. 呼叫 htop 命令。

    / # htop
    

例如,加入另一個容器的 PID 名稱空間

加入另一個容器的 PID 名稱空間對於除錯該容器非常有用。

  1. 啟動一個執行 Redis 伺服器的容器

    $ docker run --rm --name my-nginx -d nginx:alpine
    
  2. 執行一個 Alpine 容器,它將 --pid 名稱空間連線到 my-nginx 容器

    $ docker run --rm -it --pid=container:my-nginx \
      --cap-add SYS_PTRACE \
      --security-opt seccomp=unconfined \
      alpine
    
  3. 在 Alpine 容器中安裝 strace

    / # apk add strace
    
  4. 連線到程序 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/ ubuntu pwd

-w 選項在指定目錄(本例中為 /path/to/dir/)內執行執行的命令。如果路徑不存在,Docker 會在容器內部建立它。

為每個容器設定儲存驅動程式選項 (--storage-opt)

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

這(大小)在建立時將容器檔案系統大小限制為 120G。此選項僅適用於 btrfsoverlay2windowsfilterzfs 儲存驅動程式。

對於 overlay2 儲存驅動程式,僅當後端檔案系統為 xfs 且使用 pquota 掛載選項掛載時,大小選項才可用。在這些條件下,您可以傳遞小於後端檔案系統大小的任何大小。

對於 windowsfilterbtrfszfs 儲存驅動程式,您不能傳遞小於預設 BaseFS 大小的大小。

掛載 tmpfs (--tmpfs)

--tmpfs 標誌允許您建立 tmpfs 掛載。

您可以傳遞給 --tmpfs 的選項與 Linux mount -t tmpfs -o 命令的選項相同。以下示例將一個空的 tmpfs 掛載到容器中,並帶有 rwnoexecnosuidsize=65536k 選項。

$ 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 socket 和靜態連結的 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。您還可以指定 udpsctp 埠。網路概述頁面詳細解釋瞭如何使用 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 選項在建立容器時停用(隱式)拉取映象,並且只使用映象快取中可用的映象。如果找不到指定的映象,則會產生錯誤,並且不會建立容器。此選項在網路不可用或為防止在建立容器時隱式拉取映象的情況下非常有用。

以下示例顯示了 docker run 設定了 --pull=never 選項,由於映象在映象快取中缺失,因此會產生錯誤

$ 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--ipIPv4 地址(例如,172.30.100.104)
ip6--ip6IPv6 地址(例如,2001:db8::33)
mac-address--mac-address容器 MAC 地址(例如,92:d0:c6:0a:29:33)
link-local-ip--link-local-ip容器 IPv4/IPv6 鏈路本地地址
driver-optdocker network connect --driver-opt網路驅動程式選項
gw-priority最高的 gw-priority 提供預設閘道器。接受正值和負值。
$ 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

net.ipv4.net.ipv6.net.mpls. 開頭的 sysctl 設定可以透過 driver-opt 標籤 com.docker.network.endpoint.sysctls 按介面設定。介面名稱必須是字串 IFNAME

要為一個介面設定多個 sysctl,請引用整個 driver-opt 欄位,並在必要時記住轉義 shell 的引號。例如,如果連線到 my-net 的介面名為 eth0,以下示例設定 sysctls net.ipv4.conf.eth0.log_martians=1net.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;'

要與分離的容器進行輸入/輸出,請使用網路連線或共享卷。這些是必需的,因為容器不再偵聽執行 docker run 的命令列。

覆蓋分離序列 (--detach-keys)

使用 --detach-keys 選項來覆蓋 Docker 的分離鍵序列。如果 Docker 的預設序列與您用於其他應用程式的鍵序列衝突,這會很有用。有兩種方法可以定義自己的分離鍵序列,作為每個容器的覆蓋或作為整個配置的配置屬性。

要覆蓋單個容器的序列,請將 --detach-keys="<sequence>" 標誌與 docker attach 命令一起使用。<sequence> 的格式可以是字母 [a-Z],也可以是 ctrl- 與以下任何一項的組合

  • a-z(單個小寫字母字元)
  • @(at 符號)
  • [(左括號)
  • \\(兩個反斜槓)
  • _(下劃線)
  • ^(插入符)

這些 actrl-aXctrl-\\ 值都是有效鍵序列的示例。要為所有容器配置不同的配置預設鍵序列,請參閱配置檔案部分

將主機裝置新增到容器 (--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 標誌),並讓應用程式直接訪問它。

預設情況下,容器能夠 readwritemknod 這些裝置。這可以透過使用第三組 :rwm 選項來覆蓋每個 --device 標誌。如果容器以特權模式執行,則 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 October 2018 Update 開始,Windows 只支援 class 的 IdType 和作為裝置介面類 GUID 的 Id。請參閱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 容器,並且自 Docker Engine 28.3.0 起預設啟用。

透過 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 繫結到容器的 STDINSTDOUTSTDERR。這使得可以根據需要操作輸出和輸入。您可以指定要連線到三個標準流(STDINSTDOUTSTDERR)中的哪一個,例如

$ docker run -a stdin -a stdout -i -t ubuntu /bin/bash

以下示例將資料管道輸入到容器中,並透過僅連線到容器的 STDIN 來列印容器的 ID。

$ echo "test" | docker run -i -a stdin ubuntu cat -

以下示例不會在控制檯上列印任何內容,除非出現錯誤,因為輸出僅連線到容器的 STDERR。容器的日誌仍然儲存寫入 STDERRSTDOUT 的內容。

$ docker run -a stderr ubuntu echo test

以下示例展示了使用 --attach 將檔案匯入容器的方法。該命令在構建完成後列印容器的 ID,您可以使用 docker logs 檢索構建日誌。這在您需要將檔案或其他內容匯入容器並在容器執行完成後檢索容器 ID 時非常有用。

$ cat somefile | docker run -i -a stdin mybuilder dobuild
注意

在容器內作為 PID 1 執行的程序被 Linux 特殊處理:它忽略任何具有預設操作的訊號。因此,程序不會在 SIGINTSIGTERM 上終止,除非它被編碼為這樣做。

另請參閱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 功能抑制字元輸出到終端。

您可以不帶 -i 標誌使用 -t 標誌。這仍然會為容器分配一個偽 TTY,但無法寫入 STDIN。唯一可能有用的是容器的輸出需要 TTY 環境的情況。

指定自定義 cgroup

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

--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 中顯示為 UpRestarting。使用 docker events 檢視生效的重啟策略也可能很有用。

每次重啟前都會增加延遲(是前一次延遲的兩倍,從 100 毫秒開始),以防止伺服器泛洪。這意味著守護程式會等待 100 毫秒,然後 200 毫秒,400,800,1600,依此類推,直到達到 on-failure 限制、最大延遲 1 分鐘,或者您 docker stopdocker 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 標誌進行設定。以 <type>=<soft limit>[:<hard limit>] 格式指定 --ulimit,其中包含軟限制和硬限制。例如

$ 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

--ulimit 支援的選項

選項描述
core建立的核心檔案的最大大小 (RLIMIT_CORE)
cpuCPU 時間限制(秒)(RLIMIT_CPU)
data最大資料段大小 (RLIMIT_DATA)
fsize最大檔案大小 (RLIMIT_FSIZE)
locks最大檔案鎖數量 (RLIMIT_LOCKS)
memlock鎖定在記憶體中的最大地址空間 (RLIMIT_MEMLOCK)
msgqueuePOSIX 訊息佇列中的最大位元組數 (RLIMIT_MSGQUEUE)
nice最大 nice 優先順序調整 (RLIMIT_NICE)
nofile最大開啟檔案描述符數 (RLIMIT_NOFILE)
nproc最大可用程序數 (RLIMIT_NPROC)
rss最大常駐集大小 (RLIMIT_RSS)
rtprio最大即時排程優先順序 (RLIMIT_RTPRIO)
rttime最大即時執行時間 (RLIMIT_RTTIME)
sigpending最大掛起訊號數 (RLIMIT_SIGPENDING)
stack最大堆疊大小 (RLIMIT_STACK)

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] System error: resource temporarily unavailable”錯誤。這會失敗,因為呼叫者設定了 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"為容器設定標籤角色
--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 過濾器的白名單系統呼叫 Seccomp Json 檔案
--security-opt="systempaths=unconfined"關閉容器系統路徑( masked paths、read-only paths)的限制

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

這意味著提升許可權的命令(例如 susudo)不再起作用。它還會導致任何 Seccomp 過濾器在許可權被刪除後應用,這可能意味著您可以擁有更嚴格的過濾器集。有關更多詳細資訊,請參閱核心文件

在 Windows 上,您可以使用 --security-opt 標誌指定 credentialspec 選項。credentialspec 必須採用 file://spec.txtregistry://keyname 格式。

帶超時停止容器 (--stop-timeout)

--stop-timeout 標誌設定傳送預定義(參見 --stop-signal)系統呼叫訊號後等待容器停止的秒數。如果容器在超時後未退出,則會使用 SIGKILL 訊號強制終止它。

如果您將 --stop-timeout 設定為 -1,則不應用超時,守護程式將無限期等待容器退出。

守護程式決定預設值,Linux 容器為 10 秒,Windows 容器為 30 秒。

為容器指定隔離技術 (--isolation)

此選項在您在 Windows 上執行 Docker 容器時很有用。--isolation=<value> 選項設定容器的隔離技術。在 Linux 上,唯一支援的是使用 Linux 名稱空間的 default 選項。這兩個命令在 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 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 會建立一個足夠大的實用程式 VM,以容納記憶體限制,以及託管容器所需的最小作業系統。該大小報告為“總物理記憶體”。

    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

IPC 名稱空間

  • kernel.msgmaxkernel.msgmnbkernel.msgmnikernel.semkernel.shmallkernel.shmmaxkernel.shmmnikernel.shm_rmid_forced
  • fs.mqueue.* 開頭的 Sysctls
  • 如果您使用 --ipc=host 選項,則不允許使用這些 sysctls。

網路名稱空間

  • net.* 開頭的 Sysctls
  • 如果您使用 --network=host 選項,則不允許使用這些 sysctls。