docker container run
| 描述 | 從映像檔建立並執行新容器 |
|---|---|
| 使用方式 | docker container run [選項] 映像檔 [指令] [參數...] |
| 別名 | docker run |
描述
docker run 指令會在一個新的容器中執行指令,必要時會拉取映像檔並啟動容器。
您可以使用 docker start 重新啟動已停止的容器,並保留其先前的所有變更。使用 docker ps -a 查看所有容器的列表,包括已停止的容器。
選項
| 選項 | 預設值 | 描述 |
|---|---|---|
--add-host | 新增自訂主機到 IP 的映射 (host:ip) | |
--annotation | API 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 | |
--cgroupns | API 1.41+ 使用的 Cgroup 命名空間 (host|private) 'host': 在 Docker 主機的 cgroup 命名空間中執行容器 'private': 在容器自己的私有 cgroup 命名空間中執行容器 '': 使用由 daemon 上的 default-cgroupns-mode 設定配置的 cgroup 命名空間(預設) --cidfile | |
將容器 ID 寫入檔案 | --cpu-count | |
CPU 數量(僅限 Windows) | --cpu-percent | |
CPU 百分比(僅限 Windows) | API 1.25+ 限制 CPU 即時週期(微秒) | |
--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 | 在背景執行容器並印出容器 ID | |
--cpuset-cpus | 允許執行任務的 CPU (0-3, 0,1) | |
--cpuset-mems | 允許執行的記憶體節點 (MEMs) (例如:0-3, 0,1) | |
-d, --detach | 新增主機裝置到容器 | |
--detach-keys | 覆寫用於分離容器的按鍵序列 | |
--device | --device-cgroup-rule | |
新增規則到 cgroup 允許的裝置列表 | --device-read-bps | |
限制裝置的讀取速率(每秒位元組數) | --device-read-iops | |
限制裝置的讀取速率(每秒 IO 次數) | --device-write-bps | |
限制裝置的寫入速率(每秒位元組數) | --device-write-iops | |
限制裝置的寫入速率(每秒 IO 次數) | 設定自訂 DNS 伺服器 | |
--disable-content-trust | true | 跳過映像檔驗證 |
--dns | 設定 DNS 選項 | |
--dns-option | 設定自訂 DNS 搜尋網域 | |
--dns-search | --domainname | |
容器 NIS 網域名稱 | 公開一個連接埠或連接埠範圍 | |
--entrypoint | 覆寫映像檔的預設 ENTRYPOINT | |
-e, --env | 設定環境變數 | |
--env-file | 讀取環境變數檔案 | |
--expose | --gpus | |
API 1.40+ 要新增至容器的 GPU 裝置('all' 表示傳遞所有 GPU) | 新增額外的群組以加入 | |
--group-add | 執行檢查之間的時間 (ms|s|m|h)(預設 0s) | |
--health-cmd | 執行以檢查健康的命令 | |
--health-interval | API 1.44+ 啟動期間執行檢查之間的時間 (ms|s|m|h)(預設 0s) | |
--health-retries | 報告不健康所需的連續失敗次數 | |
--health-start-interval | API 1.29+ 容器在開始健康檢查重試倒數計時前的初始化期間 (ms|s|m|h)(預設 0s) | |
--health-start-period | 允許一次檢查執行的最長時間 (ms|s|m|h)(預設 0s) | |
--health-timeout | --help | |
列印使用說明 | -h, --hostname | |
容器主機名稱 | API 1.25+ 在容器內執行一個轉發訊號並回收行程的 init 程序 | |
--init | --io-maxbandwidth | |
-i, --interactive | 即使未附加也保持 STDIN 開啟 | |
系統磁碟的最大 IO 頻寬限制(僅限 Windows) | --io-maxiops | |
系統磁碟的最大 IOps 限制(僅限 Windows) | IPv4 位址(例如 172.30.100.104) | |
--ip | IPv6 位址(例如 2001:db8::33) | |
--ip6 | --ipc | |
要使用的 IPC 模式 | 設定容器的後設資料 | |
--isolation | 容器隔離技術 | |
--kernel-memory | 核心記憶體限制 | |
-l, --label | --label-file | |
讀取以行分隔的標籤檔案 | 容器 IPv4/IPv6 本地連結位址 | |
--link | 新增至另一個容器的連結 | |
--link-local-ip | 容器的日誌驅動程式 | |
--log-driver | 日誌驅動程式選項 | |
--log-opt | 容器 MAC 位址(例如 92:d0:c6:0a:29:33) | |
--mac-address | 交換空間限制等於記憶體加交換空間:'-1' 啟用無限交換 | |
-m, --memory | 記憶體限制 | |
--memory-reservation | 記憶體軟限制 | |
--memory-swap | 調整容器記憶體 swappiness(0 到 100) | |
--memory-swappiness | -1 | 將檔案系統掛載附加至容器 |
--mount | --network-alias | |
--name | 為容器指派名稱 | |
--network | 將容器連線至網路 | |
停用任何容器指定的 HEALTHCHECK | 為容器新增網路範圍內的別名 | |
--no-healthcheck | 停用 OOM Killer | |
--oom-kill-disable | 調整主機的 OOM 偏好設定(-1000 到 1000) | |
--oom-score-adj | --pid | |
要使用的 PID 命名空間 | 調整容器 pids 限制(設為 -1 表示無限) | |
--pids-limit | -P, --publish-all | |
--platform | API 1.32+ 若伺服器支援多平台,可設定平台架構 | |
--privileged | 授予此容器擴展權限 | |
-p, --publish | 將容器的連接埠發佈到主機 | |
將所有公開的連接埠發布到隨機連接埠 | missing | |
--pull | 執行前先拉取映像檔 ( | 抑制拉取輸出 |
-q, --quiet | 將容器的根檔案系統掛載為唯讀 | |
--read-only | 在退出時自動移除容器及其關聯的匿名磁碟區 | |
--restart | no | 容器退出時套用的重新啟動策略 |
--rm | --runtime | |
用於此容器的執行時期 | 安全性選項 | |
--security-opt | /dev/shm 的大小 | |
--shm-size | 將接收到的訊號代理至行程 | |
--sig-proxy | true | 停止容器的訊號 |
--stop-signal | --stop-timeout | |
API 1.25+ 停止容器的逾時時間(以秒為單位) | --storage-opt | |
容器的儲存驅動程式選項 | Sysctl 選項 | |
--sysctl | 掛載 tmpfs 目錄 | |
--tmpfs | --use-api-socket | |
-t, --tty | 分配虛擬 TTY | |
--ulimit | Ulimit 選項 | |
繫結掛載 Docker API socket 和必要的驗證 | --userns | |
-u, --user | 使用者名稱或 UID (格式:<名稱|UID>[:<群組|GID>]) | |
要使用的使用者命名空間 | --uts | |
要使用的 UTS 命名空間 | --volume-driver | |
-v, --volume | 綁定掛載 (bind mount) 一個卷冊 | |
容器的選用磁碟區驅動程式 | --volumes-from | |
從指定的容器掛載磁碟區 | 指派名稱 (--name) | |
-w, --workdir | 容器內的工作目錄 |
範例
--name 旗標可讓您為容器指定自訂識別碼。以下範例在 分離模式下使用 nginx:alpine 映像檔執行名為 test 的容器。
您可以在其他指令中使用名稱來參照容器。例如,以下指令會停止並移除名為 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
如果您未使用 --name 旗標指定自訂名稱,daemon 會為容器指派一個隨機生成的名稱,例如 vibrant_cannon。使用自訂名稱的好處是容器識別碼易於記憶。
$ docker stop test
test
$ docker rm test
test
此外,如果您將容器連接到使用者定義的橋接網路,同一網路上的其他容器可以透過 DNS 使用名稱來參照該容器。
擷取容器 ID (--cidfile)
$ 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
...
為了輔助自動化,您可以讓 Docker 將容器 ID 寫入您選擇的檔案中。這類似於某些程式可能會將其行程 ID 寫入檔案(您可能見過它們作為 PID 檔案)。
這會建立一個容器並將 test 印出到主控台。cidfile 旗標會讓 Docker 嘗試建立一個新檔案並將容器 ID 寫入其中。如果該檔案已存在,Docker 會傳回錯誤。當 docker run 退出時,Docker 會關閉此檔案。
$ docker run --cidfile /tmp/docker_test.cid ubuntu echo "test"
PID 設定 (--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 containerPID 命名空間提供行程隔離。PID 命名空間移除了對系統行程的檢視,並允許重複使用行程 ID(包括 PID 1)。
在某些情況下,您希望容器共用主機的行程命名空間,讓容器內的行程能夠看到系統上的所有行程。例如,您可以建構一個包含 strace 或 gdb 等偵錯工具的容器,但希望在偵錯容器內的行程時使用這些工具。
範例:在容器內執行 htop
要在共用主機行程命名空間的容器中執行 htop
執行一個帶有 --pid=host 選項的 alpine 容器
在容器中安裝
htop$ docker run --rm -it --pid=host alpine呼叫
htop指令。/ # apk add --quiet htop範例,加入另一個容器的 PID 命名空間
/ # htop
加入另一個容器的 PID 命名空間對於偵錯該容器很有用。
啟動執行 Redis 伺服器的容器
執行一個將
--pid命名空間附加到my-nginx容器的 Alpine 容器$ docker run --rm --name my-nginx -d nginx:alpine在 Alpine 容器中安裝
strace$ docker run --rm -it --pid=container:my-nginx \ --cap-add SYS_PTRACE \ --security-opt seccomp=unconfined \ alpine附加到行程 1(
my-nginx容器的 PID)/ # apk add strace停用容器的使用者命名空間重新映射 (--userns)
/ # strace -p 1 strace: Process 1 attached
如果您在 daemon 上啟用了使用者命名空間,則所有容器預設都會在啟用使用者命名空間的情況下啟動。若要停用特定容器的使用者命名空間重新映射,您可以將 --userns 旗標設為 host。
host 是 --userns 旗標唯一有效的值。
docker run --userns=host hello-world
如需更多資訊,請參閱 使用使用者命名空間隔離容器。
UTS 設定 (--uts)
UTS 命名空間用於設定在該命名空間中執行行程可見的主機名稱和網域。預設情況下,所有容器(包括 --network=host 的容器)都有自己的 UTS 命名空間。將 --uts 設定為 host 會導致容器使用與主機相同的 UTS 命名空間。
--uts="" : Set the UTS namespace mode for the container
'host': use the host's UTS namespace inside the containerDocker 不允許將 --hostname 和 --domainname 旗標與 --uts=host 組合使用。這是為了防止在主機 UTS 命名空間中執行的容器嘗試更改主機的配置。
注意如果您希望容器的主機名稱隨著主機主機名稱的更改而更改,您可能希望與主機共用 UTS 命名空間。更進階的使用案例是從容器更改主機的主機名稱。
IPC 設定 (--ipc)
--ipc 旗標接受以下值
--ipc="MODE" : Set the IPC mode for the container使用 daemon 的預設值。
| 值 | 描述 |
|---|---|
| "" | "none" |
| 擁有私有 IPC 命名空間,且未掛載 /dev/shm。 | "private" |
| 擁有私有 IPC 命名空間。 | "shareable" |
| 擁有私有 IPC 命名空間,並可與其他容器共用。 | "container:<名稱或 ID>" |
| 加入另一個("shareable")容器的 IPC 命名空間。 | "host" |
| 使用主機系統的 IPC 命名空間。 | 如果未指定,則使用 daemon 預設值,該值可能是 "private" 或 "shareable",具體取決於 daemon 版本和配置。 |
System V 行程間通訊 (IPC) 命名空間提供對具名共用記憶體區段、號誌和訊息佇列的隔離。
共用記憶體區段用於以記憶體速度加速行程間通訊,而不是透過管道或網路堆疊。資料庫和客製化(通常是 C/OpenMPI,C++ 使用 boost 函式庫)高效能應用程式通常使用共用記憶體進行科學計算和金融服務產業。如果這類應用程式被拆分為多個容器,您可能需要透過主(即 "提供者")容器的 "shareable" 模式以及其他容器的 "container:<提供者名稱或 ID>" 來共用容器的 IPC 機制。
提升容器權限 (--privileged)
--privileged 旗標會賦予容器以下能力
啟用所有 Linux 核心能力
- 停用預設 seccomp 設定檔
- 停用預設 AppArmor 設定檔
- 停用 SELinux 行程標籤
- 授予對所有主機裝置的存取權
- 將
/sys設為讀寫 - 將 cgroups 掛載設為讀寫
- 換句話說,容器可以執行主機幾乎能做的所有事。此旗標存在是為了允許特殊使用案例,例如 Docker in Docker。
請謹慎使用 --privileged 旗標。帶有 --privileged 的容器不是一個安全沙箱行程。在此模式下的容器可以取得主機上的 root shell 並控制系統。
警告對於大多數使用案例,此旗標不應是首選解決方案。如果您的容器需要提升權限,您應該優先考慮明確授予必要的權限,例如使用
--cap-add新增個別核心能力。如需更多資訊,請參閱 執行時期權限和 Linux 能力
以下範例無法運作,因為預設情況下,Docker 會捨棄大多數潛在危險的核心能力,包括
CAP_SYS_ADMIN(掛載檔案系統所需)。
當您新增 --privileged 旗標時,它就可以運作了
$ docker run -t -i --rm ubuntu bash
root@bc338942ef20:/# mount -t tmpfs none /mnt
mount: permission denied
設定工作目錄 (-w, --workdir)
$ 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 選項在指定的目錄(本範例中為 /path/to/dir/)內執行指令。如果路徑不存在,Docker 會在容器內建立它。
$ docker run -w /path/to/dir/ ubuntu pwd
設定容器的儲存驅動程式選項 (--storage-opt)
此 (size) 在建立時將容器檔案系統大小限制為 120G。此選項僅適用於 btrfs、overlay2、windowsfilter 和 zfs 儲存驅動程式。
$ docker run -it --storage-opt size=120G fedora /bin/bash
對於 overlay2 儲存驅動程式,size 選項僅在底層檔案系統為 xfs 並以 pquota 掛載選項掛載時才可用。在這些條件下,您可以傳遞任何小於底層檔案系統大小的數值。
對於 windowsfilter、btrfs 和 zfs 儲存驅動程式,您不能傳遞小於預設 BaseFS 大小的數值。
掛載 tmpfs (--tmpfs)
--tmpfs 旗標可讓您建立 tmpfs 掛載。
您可以傳遞給 --tmpfs 的選項與 Linux mount -t tmpfs -o 指令完全相同。以下範例以 rw、noexec、nosuid、size=65536k 選項將空的 tmpfs 掛載到容器中。
如需更多資訊,請參閱 tmpfs 掛載。
$ docker run -d --tmpfs /run:rw,noexec,nosuid,size=65536k my_image
掛載磁碟區 (-v)
上面的範例使用 -v 旗標將當前目錄掛載到容器中的相同路徑,並將其設為工作目錄,然後在容器內執行 pwd 指令。
$ docker run -v $(pwd):$(pwd) -w $(pwd) -i -t ubuntu pwd
自 Docker Engine 23 版本起,您可以在主機上使用相對路徑。
上面的範例使用 -v 旗標將當前目錄中的 content 目錄掛載到容器中的 /content 路徑,將其設為工作目錄,然後在容器內執行 pwd 指令。
$ docker run -v ./content:/content -w /content -i -t ubuntu pwd
當綁定掛載磁碟區的主機目錄不存在時,Docker 會自動為您在主機上建立此目錄。在上面的範例中,Docker 會在啟動容器之前建立 /doesnt/exist 資料夾。
$ docker run -v /doesnt/exist:/foo -w /foo -i -t ubuntu bash
唯讀掛載磁碟區 (--read-only)
您可以將磁碟區與 --read-only 旗標結合使用,以控制容器寫入檔案的位置。--read-only 旗標將容器的根檔案系統掛載為唯讀,禁止寫入容器指定磁碟區以外的位置。
$ docker run --read-only -v /icanwrite busybox touch /icanwrite/here
透過綁定掛載 Docker Unix socket 和靜態連結的 Docker 二進位檔(請參閱 取得 Linux 二進位檔),您授予容器建立和操作主機 Docker daemon 的完整權限。
$ docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/static-docker-binary:/usr/bin/docker busybox sh
在 Windows 上,您必須使用 Windows 風格的路徑語法指定路徑。
以下範例在使用基於 Windows 的容器時會失敗,因為容器內磁碟區或綁定掛載的目的地必須是以下其中之一:不存在或空的目錄;或者除了 C: 以外的磁碟機。此外,綁定掛載的來源必須是本機目錄,而不是檔案。
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關於磁碟區的深入資訊,請參閱 管理容器中的資料
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。
發布或公開連接埠 (-p, --expose)
範例
$ 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
這會將容器的 8080 連接埠繫結到主機 127.0.0.1 上的 TCP 連接埠 80。您也可以指定 udp 和 sctp 連接埠。網路概觀頁面詳細解釋了如何使用 Docker 發布連接埠。
$ docker run -p 127.0.0.1:80:8080/tcp nginx:alpine
如果您在發布容器連接埠時未指定 IP 位址(例如使用 -p 80:80 而非 -p 127.0.0.1:80:80),Docker 預設會將連接埠發布到所有介面(位址 0.0.0.0)。這些連接埠是外部可存取的。如果您配置了 UFW 以封鎖此特定連接埠,這也適用,因為 Docker 管理自己的 iptables 規則。閱讀更多
注意這會公開容器的
80連接埠,而不將其發布到主機系統的介面。
$ docker run --expose 80 nginx:alpine
發布所有公開的連接埠 (-P, --publish-all)
-P 或 --publish-all 旗標會將所有公開的連接埠發布到主機。Docker 會將每個公開的連接埠繫結到主機上的隨機連接埠。
$ docker run -P nginx:alpine
-P 旗標僅發布明確標記為公開的連接埠號碼(透過 Dockerfile EXPOSE 指令或 docker run 指令的 --expose 旗標)。
連接埠範圍位於 /proc/sys/net/ipv4/ip_local_port_range 定義的暫時連接埠範圍內。使用 -p 旗標明確對應單個連接埠或連接埠範圍。
設定拉取策略 (--pull)
使用 --pull 旗標在建立(並執行)容器時設定映像檔拉取策略。
--pull 旗標可以採用以下值之一
missing(預設)
| 值 | 描述 |
|---|---|
| 如果映像檔快取中找不到映像檔,則拉取它,否則使用快取的映像檔。 | never |
不要拉取映像檔,即使它缺失;如果映像檔不存在於映像檔快取中,則產生錯誤。 | always |
always | 在建立容器前務必執行拉取。 |
當從映像檔建立(並執行)容器時,daemon 會檢查映像檔是否在本地映像檔快取中。如果映像檔缺失,會將錯誤傳回給 CLI,讓其發起拉取。
預設值 (missing) 僅在 daemon 的映像檔快取中不存在該映像檔時才拉取。此預設值允許您執行僅存在於本地的映像檔(例如,您從 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 用戶端會檢查變數在本地環境中的值並將其傳遞給容器。如果未提供 = 且該變數在您的本地環境中未匯出,則該變數在容器中為未設定。
您也可以從檔案載入環境變數。此檔案應使用 <變數>=值 的語法(這會將變數設定為給定值)或 <變數>(這會從本地環境取得值),以及 # 作為註解。以 # 開頭的行會被視為行註解並被忽略,而出現在行中任何其他位置的 # 則被視為變數值的一部分。
$ cat env.list
# This is a comment
VAR1=value1
VAR2=value2
USER
$ docker run --env-file env.list ubuntu env | grep -E 'VAR|USER'
VAR1=value1
VAR2=value2
USER=jonzeolla
設定容器上的後設資料 (-l, --label, --label-file)
標籤是一個 鍵=值 對,可將後設資料套用到容器。若要用兩個標籤標記容器
$ docker run -l my-label --label com.example.foo=bar ubuntu bash
my-label 鍵未指定值,因此標籤預設為空字串 ("")。若要新增多個標籤,請重複標籤旗標 (-l 或 --label)。
鍵=值 必須是唯一的,以避免覆寫標籤值。如果您指定鍵相同但值不同的標籤,則每個後續值都會覆寫前一個。Docker 會使用您提供的最後一個 鍵=值。
使用 --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 網路或自訂外掛,連接到同一多主機網路但從不同 Engine 啟動的容器也可以透過這種方式進行通訊。
注意預設的橋接網路僅允許容器使用內部 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 | 停用任何容器指定的 HEALTHCHECK | 為容器新增網路範圍內的別名 |
ip | --ip | IPv6 位址(例如 2001:db8::33) |
ip6 | --ip6 | --ipc |
mac-address | --mac-address | 交換空間限制等於記憶體加交換空間:'-1' 啟用無限交換 |
link-local-ip | --link-local-ip | 容器的日誌驅動程式 |
driver-opt | docker 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=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 選項。如果您在 --rm 的情況下使用 -d,則容器會在退出或 daemon 退出時(以先發生者為準)被移除。
請勿將 service x start 指令傳遞給分離的容器。例如,此指令嘗試啟動 nginx 服務。
$ docker run -d -p 80:80 my_image service nginx start
這成功啟動了容器內的 nginx 服務。但是,它違背了分離容器範式,因為根行程 (service nginx start) 會傳回,而分離的容器會按設計停止。結果,nginx 服務啟動了但無法使用。相反地,要啟動像 nginx 網路伺服器這樣的行程,請執行以下操作
$ docker run -d -p 80:80 my_image nginx -g 'daemon off;'
要與分離的容器進行輸入/輸出,請使用網路連線或共用磁碟區。這是必須的,因為容器不再監聽執行 docker run 的命令列。
覆寫分離序列 (--detach-keys)
使用 --detach-keys 選項來覆寫 Docker 分離金鑰序列。如果您使用的預設 Docker 序列與您為其他應用程式使用的金鑰序列衝突,這很有用。定義您自己的分離金鑰序列有兩種方式:作為每個容器的覆寫,或作為整個配置的配置屬性。
若要覆寫個別容器的序列,請在 docker attach 指令中使用 --detach-keys="<sequence>" 旗標。<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 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 規格(JSON 或 YAML 檔案)在執行 daemon 的系統上可用,並位於已配置的 CDI 規格目錄之一中。
- CDI 功能已在 daemon 中啟用;請參閱 啟用 CDI 裝置。
附加至 STDIN/STDOUT/STDERR (-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 -
以下範例不會印出任何內容到主控台,除非發生錯誤,因為輸出僅附加到容器的 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 程序
您可以使用 --init 旗標來表示在容器中應將 init 程序用作 PID 1。指定一個 init 程序可確保 init 系統的常見責任(例如回收殭屍行程)在建立的容器內執行。
使用的預設 init 程序是在 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 可以使用 echo-off 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 <次要編號> 該裝置。
注意您仍然需要明確地將最初存在的裝置新增到
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 | Always 重新啟動容器如果它停止。如果它被手動停止,只有在 Docker daemon 重新啟動或容器本身手動重新啟動時,它才會重新啟動。 |
unless-stopped | 與 always 類似,除了當容器停止(手動或其他方式)時,即使 Docker daemon 重新啟動,它也不會被重新啟動。 |
$ docker run --restart=always redis
這以 always 的重新啟動策略執行 redis 容器。如果容器退出,Docker 會將其重新啟動。
當容器上啟用重新啟動策略時,它會在 docker ps 中顯示為 Up 或 Restarting。使用 docker events 查看生效的重新啟動策略也很有用。
每次重新啟動前會增加一個延遲(延遲時間加倍,從 100 毫秒開始),以防止伺服器癱瘓。這意味著 daemon 會等待 100 毫秒,然後是 200 毫秒、400、800、1600 等,直到達到 on-failure 限制、最大延遲 1 分鐘,或者當您 docker stop 或 docker 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 daemon 不同的日誌驅動程式。使用 --log-driver=<DRIVER> 搭配 docker run 指令來配置容器的日誌驅動程式。
若要了解支援的日誌驅動程式以及如何使用它們,請參閱 配置日誌驅動程式。
若要停用容器的日誌記錄,請將 --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>=<軟限制>[:<硬限制>] 的格式指定 --ulimit 及其軟硬限制。例如
$ docker run --ulimit nofile=1024:1024 --rm debian sh -c "ulimit -n"
1024
注意如果您不提供硬限制值,Docker 會將軟限制值用於這兩個值。如果您不提供任何值,它們將繼承自 daemon 上設定的預設
ulimits。
注意
as選項已被棄用。換句話說,以下指令稿不被支援$ docker run -it --ulimit as=1024 fedora /bin/bash
--ulimit 的支援選項
| 選項 | 描述 |
|---|---|
core | 建立的 core 檔案最大大小 (RLIMIT_CORE) |
cpu | CPU 時間限制(以秒為單位)(RLIMIT_CPU) |
data | 最大資料區段大小 (RLIMIT_DATA) |
fsize | 最大檔案大小 (RLIMIT_FSIZE) |
locks | 檔案鎖定的最大數量 (RLIMIT_LOCKS) |
memlock | 記憶體鎖定最大位址空間 (RLIMIT_MEMLOCK) |
msgqueue | POSIX 訊息佇列中的最大位元組數 (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 將這些值傳送到對應的作業系統 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
第 4 個容器會失敗並報告 "[8] System error: resource temporarily unavailable" 錯誤。失敗原因是呼叫者設定了 nproc=3,導致前三個容器耗盡了為 daemon 使用者設定的三個行程配額。
以訊號停止容器 (--stop-signal)
--stop-signal 旗標會將系統呼叫訊號傳送到容器以使其退出。此訊號可以是 SIG<NAME> 格式的訊號名稱(例如 SIGKILL),或符合核心 syscall 表中位置的不帶正負號數字(例如 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") 的 daemon 上的容器啟用 seccomp。 |
--security-opt="seccomp=profile.json" | 用作 seccomp 過濾器的白名單 syscalls 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.txt 或 registry://keyname 的格式。
以逾時停止容器 (--stop-timeout)
--stop-timeout 旗標設定在傳送預定義(請參閱 --stop-signal)系統呼叫訊號後,等待容器停止的秒數。如果容器在逾時後沒有退出,它會被 SIGKILL 訊號強行終止。
如果您將 --stop-timeout 設為 -1,則不會套用逾時,daemon 會無限期地等待容器退出。
Daemon 會決定預設值,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 daemon 的 --exec-opt 或系統預設值(見下方)指定的值。 |
process | 共用核心命名空間隔離。 |
hyperv | 基於 Hyper-V hypervisor 分割區的隔離。 |
Windows 伺服器作業系統上的預設隔離為 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 用戶端的 daemon 執行,則這些指令是等效的,並且會導致 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。該大小被報告為 "Total Physical Memory"。PS C:\> docker run -it -m 2GB --isolation=hyperv microsoft/nanoserver powershell Get-ComputerInfo *memory* CsTotalPhysicalMemory : 2683355136 CsPhyicallyInstalledMemory : OsTotalVisibleMemorySize : 2620464 OsFreePhysicalMemory : 2306552 OsTotalVirtualMemorySize : 2620464 OsFreeVirtualMemory : 2356692 OsInUseVirtualMemory : 263772 OsMaxProcessMemorySize : 137438953344
在執行時期配置命名空間核心參數 (sysctls) (--sysctl)
--sysctl 設定容器中的命名空間核心參數 (sysctls)。例如,若要開啟容器網路命名空間中的 IP 轉發,請執行此指令
$ docker run --sysctl net.ipv4.ip_forward=1 someimage
注意並非所有 sysctls 都是命名空間的。Docker 不支援更改也會修改主機系統的容器內 sysctls。隨著核心發展,我們預計會看到更多的 sysctls 變成命名空間的。
目前支援的 sysctls
IPC 命名空間
kernel.msgmax,kernel.msgmnb,kernel.msgmni,kernel.sem,kernel.shmall,kernel.shmmax,kernel.shmmni,kernel.shm_rmid_forced。- 以
fs.mqueue.*開頭的 Sysctls - 如果您使用
--ipc=host選項,則不允許這些 sysctls。
網路命名空間
- 以
net.*開頭的 Sysctls - 如果您使用
--network=host選項,則不允許使用這些 sysctls。