Docker會在隔離的容器中運行進程。當運行
docker run
命令時,Docker會啓動一個進程,併爲這個進程分配其獨佔的文件系統、網絡資源和以此進程爲根進程的進程組。在容器啓動時,
鏡像可能已經定義了要運行的二進制文件、暴露的網絡端口等,可是用戶能夠經過
docker run
命令從新定義(譯者注:docker run能夠控制一個容器運行時的行爲,它能夠覆蓋
docker build
在構建鏡像時的一些默認配置),這也是爲何
run
命令相比於其它命令有如此多的參數的緣由。
命令格式
最基本的
docker run
命令的格式以下:
若是須要查看[OPTIONS]的詳細使用說明,請參考Docker關於OPTIONS的
章節。這裏僅簡要介紹Run所使用到的參數。OPTIONS總起來講能夠分爲兩類:
- 設置運行方式:
- 決定容器的運行方式,前臺執行仍是後臺執行;
- 設置containerID;
- 設置網絡參數;
- 設置容器的CPU和內存參數;
- 設置權限和LXC參數;
- 設置鏡像的默認資源,也就是說用戶可使用該命令來覆蓋在鏡像構建時的一些默認配置。
docker run [OPTIONS]
可讓用戶徹底控制容器的生命週期,並容許用戶覆蓋執行
docker build
時所設定的參數,甚至也能夠修改自己由Docker所控制的內核級參數。
Operator exclusive options
當執行
docker run
時能夠設置如下參數:
- Detached vs Foreground
- Detached (-d)
- Foreground
- Container Identification
- Name (--name)
- PID Equivalent
- IPC Setting
- Network Settings
- Clean Up (--rm)
- Runtime Constraints on CPU and Memory
- Runtime Privilege, Linux Capabilities, and LXC Configuration
接下來咱們依次進行介紹。
Detached vs foreground
當咱們啓動一個容器時,首先須要肯定這個容器是運行在前臺仍是運行在後臺。
Detached (-d)
若是在
docker run
後面追加
-d=true
或者
-d
,那麼容器將會運行在後臺模式。此時全部I/O數據只能經過網絡資源或者共享卷組來進行交互。由於容器再也不監聽你執行
docker run
的這個終端命令行窗口。但你能夠經過執行
docker attach
來從新附着到該容器的回話中。須要注意的是,容器運行在後臺模式下,是不能使用
--rm
選項的。
Foregroud
在前臺模式下(不指定
-d
參數便可),Docker會在容器中啓動進程,同時將當前的命令行窗口附着到容器的標準輸入、標準輸出和標準錯誤中。也就是說容器中全部的輸出均可以在當前窗口中看到。甚至它均可以虛擬出一個TTY窗口,來執行信號中斷。這一切都是能夠配置的:
若是在執行run命令時沒有指定
-a
參數,那麼Docker默認會掛載全部標準數據流,包括輸入輸出和錯誤,你能夠單獨指定掛載哪一個標準流。
若是要進行交互式操做(例如Shell腳本),那咱們必須使用
-i -t
參數同容器進行數據交互。可是當經過管道同容器進行交互時,就不須要使用
-t
參數,例以下面的命令:
容器識別
Name(--name)
能夠經過三種方式爲容器命名:
1. 使用UUID長命名("f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778")
2. 使用UUID短命令("f78375b1c487")
3. 使用Name("evil_ptolemy")
這個UUID標示是由Docker deamon生成的。若是你在執行
docker run
時沒有指定
--name
,那麼deamon會自動生成一個隨機字符串UUID。可是對於一個容器來講有個name會很是方便,當你須要鏈接其它容器時或者相似須要區分其它容器時,使用容器名稱能夠簡化操做。不管容器運行在前臺或者後臺,這個名字都是有效的。
PID equivalent
若是在使用Docker時有自動化的需求,你能夠將containerID輸出到指定的文件中(PIDfile),相似於某些應用程序將自身ID輸出到文件中,方便後續腳本操做。
Image[:tag]
當一個鏡像的名稱不足以分辨這個鏡像所表明的含義時,你能夠經過tag將版本信息添加到run命令中,以執行特定版本的鏡像。例如:
docker run ubuntu:14.04
IPC Settings
默認狀況下,全部容器都開啓了IPC命名空間。
IPC(POSIX/SysV IPC)命名空間提供了相互隔離的命名共享內存、信號燈變量和消息隊列。
共享內存能夠提升進程數據的交互速度。共享內存通常用在數據庫和高性能應用(C/OpenMPI、C++/using boost libraries)上或者金融服務上。若是須要容器中部署上述類型的應用,那麼就應該在多個容器直接使用共享內存了。
Network settings
默認狀況下,全部的容器都開啓了網絡接口,同時能夠接受任何外部的數據請求。
你能夠經過
docker run --net none
來關閉網絡接口,此時將關閉全部網絡數據的輸入輸出,你只能經過STDIN、STDOUT或者files來完成I/O操做。默認狀況下,容器使用主機的DNS設置,你也能夠經過
--dns
來覆蓋容器內的DNS設置。同時Docker爲容器默認生成一個MAC地址,你能夠經過
--mac-address 12:34:56:78:9a:bc
來設置你本身的MAC地址。
Docker支持的網絡模式有:
- none。關閉容器內的網絡鏈接
- bridge。經過veth接口來鏈接容器,默認配置。
- host。容許容器使用host的網絡堆棧信息。 注意:這種方式將容許容器訪問host中相似D-BUS之類的系統服務,因此認爲是不安全的。
- container。使用另一個容器的網絡堆棧信息。
None模式
將網絡模式設置爲none時,這個容器將不容許訪問任何外部router。這個容器內部只會有一個loopback接口,並且不存在任何能夠訪問外部網絡的router。
Bridge模式
Docker默認會將容器設置爲bridge模式。此時在主機上面將會存在一個docker0的網絡接口,同時會針對容器建立一對veth接口。其中一個veth接口是在主機充當網卡橋接做用,另一個veth接口存在於容器的命名空間中,而且指向容器的loopback。Docker會自動給這個容器分配一個IP,而且將容器內的數據經過橋接轉發到外部。
Host模式
當網絡模式設置爲host時,這個容器將徹底共享host的網絡堆棧。host全部的網絡接口將徹底對容器開放。容器的主機名也會存在於主機的hostname中。這時,容器全部對外暴露的端口和對其它容器的鏈接,將徹底失效。
Container模式
當網絡模式設置爲Container時,這個容器將徹底複用另一個容器的網絡堆棧。同時使用時這個容器的名稱必需要符合下面的格式:--net container:<name|id>.
好比當前有一個綁定了本地地址localhost的Redis容器。若是另一個容器須要複用這個網絡堆棧,則須要以下操做:
管理/etc/hosts
/etc/hosts文件中會包含容器的hostname信息,咱們也可使用
--add-host
這個參數來動態添加/etc/hosts中的數據。
Clean up (--rm)
默認狀況下,每一個容器在退出時,它的文件系統也會保存下來,這樣一方面調試會方便些,由於你能夠經過查看日誌等方式來肯定最終狀態。另一方面,你也能夠保存容器所產生的數據。可是當你僅僅須要短暫的運行一個容器,而且這些數據不須要保存,你可能就但願Docker能在容器結束時自動清理其所產生的數據。
這個時候你就須要--rm這個參數了。 注意:--rm 和 -d不能共用!
Security configuration
你能夠經過
--security-opt
修改容器默認的schema標籤。好比說,對於一個MLS系統來講(譯者注:MLS應該是指Multiple Listing System),你能夠指定MCS/MLS級別。使用下面的命令能夠在不一樣的容器間分享內容:
若是是MLS系統,則使用下面的命令:
使用下面的命令能夠在容器內禁用安全策略:
若是你須要在容器內執行更爲嚴格的安全策略,那麼你能夠爲這個容器指定一個策略替代,好比你可使用下面的命令來指定容器只監聽Apache端口:
注意:此時,你的主機環境中必須存在一個名爲svirt_apache_t的安全策略。
Runtime constraints on CPU and memory
下面的參數能夠用來調整容器內的性能。
經過
docker run -m
能夠調整容器所使用的內存資源。若是主機支持swap內存,那麼可使用
-m
能夠設定比主機物理內存還大的值。
一樣,經過
-c
能夠調整容器的CPU優先級。默認狀況下,全部的容器擁有相同的CPU優先級和CPU調度週期,但你能夠經過Docker來通知內核給予某個或某幾個容器更多的CPU計算週期。
好比,咱們使用
-c
或者
--cpu-shares =0
啓動了C0、C一、C2三個容器,使用-c/--cpu-shares=512啓動了C3容器。這時,C0、C一、C2能夠100%的使用CPU資源(1024),但C3只能使用50%的CPU資源(512)。若是這個主機的操做系統是時序調度類型的,每一個CPU時間片是100微秒,那麼C0、C一、C2將徹底使用掉這100微秒,而C3只能使用50微秒。
Runtime privilege, Linux capabilities, and LXC configuration
默認狀況下,Docker的容器是沒有特權的,例如不能在容器中再啓動一個容器。這是由於默認狀況下容器是不能訪問任何其它設備的。可是經過"privileged",容器就擁有了訪問任何其它設備的權限。
當操做者執行
docker run --privileged
時,Docker將擁有訪問主機全部設備的權限,同時Docker也會在apparmor或者selinux作一些設置,使容器能夠容易的訪問那些運行在容器外部的設備。你能夠訪問
Docker博客來獲取更多關於--privileged的用法。
同時,你也能夠限制容器只能訪問一些指定的設備。下面的命令將容許容器只訪問一些特定設備:
默認狀況下,容器擁有對設備的讀、寫、建立設備文件的權限。使用
:rwm
來配合
--device
,你能夠控制這些權限。
使用
--cap-add
和
--cap-drop
,配合
--privileged
,你能夠更細緻的控制人哦怒氣。默認使用這兩個參數的狀況下,容器擁有一系列的內核修改權限,這兩個參數都支持
all
值,若是你想讓某個容器擁有除了MKNOD以外的全部內核權限,那麼能夠執行下面的命令:
若是須要修改網絡接口數據,那麼就建議使用
--cap-add=NET_ADMIN
,而不是使用
--privileged
。
若是要掛載一個FUSE文件系統,那麼就須要
--cap-add
和
--device
了。
若是Docker守護進程在啓動時選擇了
lxc
lxc-driver(
docker -d --exec-driver=lxc
),那麼就可使用
--lxc-conf
來設定LXC參數。但須要注意的是,將來主機上的Docker deamon有可能不會使用LXC,因此這些參數有可能會包含一些沒有實現的配置功能。這意味着,用戶在操做這些參數時必需要十分熟悉LXC。
特別注意:當你使用
--lxc-conf
修改容器參數後,Docker deamon將再也不管理這些參數,那麼用戶必須自行進行管理。好比說,你使用
--lxc-conf
修改了容器的IP地址,那麼在/etc/hosts裏面是不會自動體現的,須要你自行維護。
Overriding Dockerfile image defaults
當開發者使用
Dockerfile進行build或者使用commit提交容器時,開發人員能夠設定一些鏡像默認參數。
這些參數中,有四個是沒法被覆蓋的:FROM、MAINTAINER、RUN和ADD,其他參數均可以經過
docker run
進行覆蓋。咱們將介紹如何對這些參數進行覆蓋。
- CMD (Default Command or Options)
- ENTRYPOINT (Default Command to Execute at Runtime)
- EXPOSE (Incoming Ports)
- ENV (Environment Variables)
- VOLUME (Shared Filesystems)
- USER
- WORKDIR
CMD (default command or options)
這個命令中的COMMAND部分是可選的。由於這個IMAGE在build時,開發人員可能已經設定了默認執行的命令。做爲操做人員,你可使用上面命令中新的command來覆蓋舊的command。
若是鏡像中設定了ENTRYPOINT,那麼命令中的CMD也能夠做爲參數追加到ENTRYPOINT中。
ENTRYPOINT (default command to execute at runtime)
這個ENTRYPOINT和COMMAND相似,它指定了當容器執行時,須要啓動哪些進程。相對COMMAND而言,ENTRYPOINT是很難進行覆蓋的,這個ENTRYPOINT可讓容器設定默認啓動行爲,因此當容器啓動時,你能夠執行任何一個二進制可執行程序。你也能夠經過COMMAND爲ENTRYPOINT傳遞參數。但當你須要在容器中執行其它進程時,你就能夠指定其它ENTRYPOINT了。
下面就是一個例子,容器能夠在啓動時自動執行Shell,而後啓動其它進程。
EXPOSE (incoming ports)
Dockefile在網絡方面除了提供一個EXPOSE以外,沒有提供其它選項。下面這些參數能夠覆蓋Dockefile的expose默認值:
--expose可讓容器接受外部傳入的數據。容器內監聽的端口不須要和外部主機的端口相同。好比說在容器內部,一個HTTP服務監聽在80端口,對應外部主機的端口就多是49880.
若是使用
-p
或者
-P
,那麼容器會開放部分端口到主機,只要對方能夠鏈接到主機,就能夠鏈接到容器內部。當使用
-P
時,Docker會在主機中隨機從49153 和65535之間查找一個未被佔用的端口綁定到容器。你可使用
docker port
來查找這個隨機綁定端口。
當你使用
--link
方式時,做爲客戶端的容器能夠經過私有網絡形式訪問到這個容器。同時Docker會在客戶端的容器中設定一些環境變量來記錄綁定的IP和PORT。
ENV (environment variables)
當容器啓動時,會自動在容器中初始化這些變量。
操做人員能夠經過
-e
來設定任意的環境變量,甚至覆蓋已經存在的環境變量,或者是在Dockerfile中經過ENV設定的環境變量。
操做人員能夠經過
-h
來設定hostname。也可使用"--link name:alias"來設定環境變量,當使用
--link
後,Docker將根據後面提供的IP和PORT信息來鏈接服務端容器。下面就是使用redis的例子:
你使用
--link
後,就能夠獲取到關於Redis容器的相關信息。
Docker也會將這個alias的IP地址寫入到/etc/hosts文件中。而後你就能夠經過別名來訪問link後的容器。
若是你重啓了源容器(servicename),相關聯的容器也會同步更新/etc/hosts。
VOLUME (shared filesystems)
關於volume參數,能夠在
Managing data in containers查看詳細說明,須要注意的是開發人員能夠在Dockerfile中設定多個volume,可是隻能由運維人員設置容器直接的volume訪問。
USER
容器中默認的用戶是root,可是開發人員建立新的用戶以後,這些新用戶也是可使用的。開發人員能夠經過Dockerfile的USER設定默認的用戶,並經過"-u "來覆蓋這些參數。
WORKDIR
容器中默認的工做目錄是根目錄(/)。開發人員能夠經過Dockerfile的WORKDIR來設定默認工做目錄,操做人員能夠經過"-w"來覆蓋默認的工做目錄。
原文連接:
Docker run reference(譯者:vikings 審校:李穎傑)