docker container run

說明從映象建立並執行新容器
用法docker container run [選項] 映象 [命令] [引數...]
別名
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 capabilities
--cap-drop丟棄 Linux capabilities
--cgroup-parent容器的可選父 cgroup
--cgroupnsAPI 1.41+ 要使用的 Cgroup 名稱空間 (host|private)
'host':在 Docker 主機的 cgroup 名稱空間中執行容器
'private':在容器自己的私有 cgroup 名稱空間中執行容器
'':使用由 daemon 上的
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限制從裝置讀取速率(IOPS)
--device-write-bps限制向裝置寫入速率(位元組/秒)
--device-write-iops限制向裝置寫入速率(IOPS)
--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執行檢查之間的時間間隔 (ms|s|m|h)(預設值 0s)
--health-retries報告不健康所需的連續失敗次數
--health-start-intervalAPI 1.44+ 啟動期間執行檢查之間的時間間隔 (ms|s|m|h)(預設值 0s)
--health-start-periodAPI 1.29+ 容器在開始健康檢查重試倒計時前進行初始化的啟動週期 (ms|s|m|h)(預設值 0s)
--health-timeout允許一次檢查執行的最大時間 (ms|s|m|h)(預設值 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調整容器記憶體 swappiness(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 表示無限制)
--platformAPI 1.32+ 如果伺服器支援多平臺,則設定平臺
--privileged賦予此容器擴充套件許可權
-p, --publish將容器埠釋出到主機
-P, --publish-all將所有暴露的埠釋出到隨機埠
--pullmissing執行前拉取映象 (`always`, `missing`, `never`)
-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分配一個偽終端 (pseudo-TTY)
--ulimitUlimit 選項
-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。

在某些情況下,您可能希望容器共享主機的程序名稱空間,以便容器內的程序可以看到系統上的所有程序。例如,您可以構建一個包含 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:<捐贈者名稱或 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。此選項僅適用於 btrfsoverlay2windowsfilterzfs 儲存驅動程式。

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

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

掛載 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 套接字和靜態連結的 Docker 二進位制檔案(請參閱獲取 Linux 二進位制檔案),您可以授予容器完全訪問許可權來建立和操作主機的 Docker daemon。

在 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 選項在建立容器時停用(隱式)拉取映象,並且僅使用映象快取中可用的映象。如果找不到指定的映象,則會產生錯誤,並且不會建立容器。此選項在網路不可用或在建立容器時防止隱式拉取映象的情況下很有用。

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

$ docker run --pull=never hello-world
docker: Error response from daemon: No such image: hello-world:latest.

設定環境變數 (-e, --env, --env-file)

$ docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash

使用 -e--env--env-file 標誌在您執行的容器中設定簡單的(非陣列)環境變數,或覆蓋您正在執行的映象的 Dockerfile 中定義的環境變數。

您可以在執行容器時定義變數及其值

$ docker run --env VAR1=value1 --env VAR2=value2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2

您也可以使用匯出到本地環境的變數

export VAR1=value1
export VAR2=value2

$ docker run --env VAR1 --env VAR2 ubuntu env | grep VAR
VAR1=value1
VAR2=value2

執行命令時,Docker CLI 客戶端會檢查變數在本地環境中的值並將其傳遞給容器。如果未提供 = 並且該變數未在本地環境中匯出,則在容器中取消設定該變數。

您也可以從檔案中載入環境變數。此檔案應使用 <variable>=value(將變數設定為給定值)或 <variable>(從本地環境獲取值)的語法,並使用 # 進行註釋。以 # 開頭的行被視為行註釋並被忽略,而出現在行中其他任何位置的 # 被視為變數值的一部分。

$ cat env.list
# This is a comment
VAR1=value1
VAR2=value2
USER

$ docker run --env-file env.list ubuntu env | grep -E 'VAR|USER'
VAR1=value1
VAR2=value2
USER=jonzeolla

設定容器元資料 (-l, --label, --label-file)

標籤是應用於容器元資料的 key=value 對。為一個容器設定兩個標籤

$ docker run -l my-label --label com.example.foo=bar ubuntu bash

my-label 鍵未指定值,因此標籤預設為空字串("")。要新增多個標籤,請重複使用標籤標誌(-l--label)。

key=value 必須是唯一的,以避免覆蓋標籤值。如果您指定具有相同鍵但不同值的標籤,則每個後續值都會覆蓋前一個值。Docker 使用您提供的最後一個 key=value

使用 --label-file 標誌從檔案中載入多個標籤。使用換行符分隔檔案中的每個標籤。以下示例從當前目錄的標籤檔案中載入標籤

$ 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 網路或自定義外掛,連線到同一多主機網路但從不同引擎啟動的容器也可以透過這種方式通訊。

注意

預設的 bridge 網路只允許容器使用內部 IP 地址相互通訊。使用者建立的 bridge 網路使用容器名稱提供容器之間的 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 (單個小寫字母)
  • @ (@ 符號)
  • [ (左方括號)
  • \\ (兩個反斜槓)
  • _ (下劃線)
  • ^ (脫字元)

這些 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 這些裝置。這可以使用每個 --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 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 容器。

容器裝置介面 (CDI) 是一種標準化的機制,用於容器執行時建立能夠與第三方裝置互動的容器。

透過 CDI,裝置配置使用 JSON 或 YAML 檔案進行宣告性定義。除了使容器能夠與裝置節點互動外,它還允許您指定裝置的附加配置,例如環境變數、主機掛載(如共享物件)和可執行鉤子。

您可以使用裝置的完全限定名透過 --device 標誌引用 CDI 裝置,如以下示例所示

$ docker run --device=vendor.com/class=device-name --rm -it ubuntu

這將啟動一個可訪問指定 CDI 裝置 vendor.com/class=device-nameubuntu 容器,前提是

  • 執行守護程序的系統上,在配置的 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 標誌指示應將初始化程序用作容器中的 PID 1。指定初始化程序可確保在建立的容器內執行初始化系統的常規職責,例如收割殭屍程序。

使用的預設初始化程序是在 Docker daemon 程序的系統路徑中找到的第一個 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 可以使用 TTY 的回顯關閉功能抑制字元輸出到終端。

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

指定自定義 cgroups

使用 --cgroup-parent 標誌,您可以傳遞特定的 cgroup 來在其中執行容器。這允許您自行建立和管理 cgroups。您可以為這些 cgroups 定義自定義資源,並將容器置於一個共同的父組下。

使用動態建立的裝置 (--device-cgroup-rule)

Docker 在容器建立時分配可用的裝置。分配的裝置會被新增到 cgroup.allow 檔案中,並在容器執行時建立到容器中。當您需要向正在執行的容器新增新裝置時,這會帶來問題。

一種解決方案是向容器新增更寬鬆的規則,使其能夠訪問更廣泛的裝置。例如,假設容器需要訪問主裝置號為 42 且次裝置號可以是任意數字(隨著新裝置出現而新增)的字元裝置,請新增以下規則

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

然後,使用者可以要求 udev 執行一個指令碼,以便在新裝置新增時使用 docker exec my-container mknod newDevX c 42 <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 daemon 在容器退出後是否重啟容器。Docker 支援以下重啟策略

標誌說明
no不要自動重啟容器。(預設)
on-failure[:max-retries]如果容器因錯誤退出而導致非零退出程式碼,則重啟容器。可選地,使用 :max-retries 選項限制 Docker daemon 嘗試重啟容器的次數。on-failure 策略僅在容器因失敗退出時才提示重啟。如果 daemon 重啟,它不會重啟容器。
always如果容器停止,則始終重啟它。如果是手動停止,則僅在 Docker daemon 重啟或容器本身手動重啟時才會重啟。
unless-stopped類似於 always,但當容器停止(手動或其他方式)時,即使在 Docker daemon 重啟後也不會重啟。
$ docker run --restart=always redis

這將執行具有 always 重啟策略的 redis 容器。如果容器退出,Docker 會重啟它。

當容器上激活了重啟策略時,它會在 docker ps 中顯示為 UpRestarting。使用 docker events 檢視生效的重啟策略也很有用。

每次重啟前都會增加一個遞增的延遲(從 100 毫秒開始,是前一次延遲的兩倍),以防止伺服器過載。這意味著 daemon 會等待 100 毫秒,然後是 200 毫秒、400、800、1600 等,直到達到 on-failure 限制、達到最長 1 分鐘的延遲,或者您使用 docker stopdocker 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 伺服器,透過解析為主機內部 IP 的 host.docker.internal 主機名,將檔案從主機提供給容器。

$ 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

在容器中設定 ulimits (--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 配置。這可用於在設定了自定義預設配置或停用("unconfined")seccomp 的守護程序上執行的容器啟用 seccomp。
--security-opt="seccomp=profile.json"用於作為 seccomp 過濾器的白名單系統呼叫 seccomp Json 檔案
--security-opt="systempaths=unconfined"關閉容器對系統路徑(掩碼路徑、只讀路徑)的約束

--security-opt 標誌允許你覆蓋容器的預設標籤方案。在以下命令中指定級別,可以實現在容器之間共享相同內容。

$ docker run --security-opt label=level:s0:c100,c200 -it fedora bash

注意

不支援 MLS 標籤的自動翻譯。

要完全停用容器的安全標籤,可以使用 label=disable

$ docker run --security-opt label=disable -it ubuntu bash

如果你想對容器內的程序實施更嚴格的安全策略,可以指定一個自定義的 type 標籤。以下示例執行一個只允許監聽 Apache 埠的容器。

$ docker run --security-opt label=type:svirt_apache_t -it ubuntu bash

注意

你需要編寫策略來定義 svirt_apache_t 型別。

為防止容器程序獲取額外許可權,可以使用以下命令

$ docker run --security-opt no-new-privileges -it ubuntu bash

這意味著 `su` 或 `sudo` 等提升許可權的命令將不再起作用。它還會導致 seccomp 過濾器在許可權被丟棄後才應用,這可能意味著你可以擁有更嚴格的過濾器集。更多詳情,請參閱核心文件

在 Windows 上,可以使用 --security-opt 標誌來指定 credentialspec 選項。credentialspec 必須採用 file://spec.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 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 守護程序上設定了 --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,其大小足以容納記憶體限制,再加上託管容器所需的最少 OS。該大小被報告為“總物理記憶體”。

    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。