Docker學習總結之Run命令介紹
本文由Vikings(http://www.cnblogs.com/vikings-blog/) 原創,轉載請標明.謝謝!linux
在使用Docker時,執行最多的命令某過於run了。這個命令能夠說是全部docker操做的入口。在Docker官方Reference中單獨列出了一個章節來介紹Run的各類參數使用,也足以看出Docker run的重要性。有感於此,我感受有必要好好學習一下Run命令,所以特地看了一下Run命令介紹,結合平常中的使用心得,分享一下。如下文檔大部分翻譯於Docker 官方Reference,確定會存在很多錯誤之處,但願能拋磚引玉,你們共同討論。
Docker在執行時會將相關進程封裝到相互隔離的容器(container)中。當執行 docker run時,Docker會啓動一個進程,同時給這個進程分配其獨佔的文件系統,獨佔的網絡資源和以此進程爲根進程的進程組。在Docker啓動container時加載的Image,或許已經定義好了默認的啓動進程,須要exposer的網絡端口和其餘在Dockerfile中定義好的資源。但使用docker run 均可以從新對這個image進行默認定義。這就是爲何run命令參數比docker其餘命令參數都多的緣由。
最基本的docker run命令是以下格式:
$ sudo docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG…]
若是須要查看[OPTIONS]的詳細使用說明,請參考Docker關於OPTIONS的說明。這裏僅簡要介紹Run所使用到的參數。
OPTIONS總起來講分爲兩類:git
1. 設定操做執行方式:設定image的默認資源,也就是image使用者能夠用此命令來覆蓋image開發者在build階段所設定的默認值docker run [OPTIONS]可讓image使用者徹底控制container的生命週期,容許image使用者覆蓋全部image開發者在執行docker build時所設定的參數,甚至也能夠修改自己由Docker所控制的內核級參數。 1. 決定container的運行方式,前臺執行仍是後臺執行設定containerID設定network參數設定container的CPU和Memory參數設定權限(Privileges )和LXC參數
Operator exclusive options 當執行docker run時能夠設定的資源以下:redis
* Detached vs ForegroundContainer IdentificationIPC SettingNetwork SettingsClean Up (--rm)Runtime Constraints on CPU and MemoryRuntime Privilege, Linux Capabilities, and LXC Configuration
咱們依次進行介紹。
Detached vs foreground 當咱們啓動一個container時,首先須要肯定這個container是運行在前臺模式仍是運行在後臺模式。
-d=false: Detached mode: Run container in the background, print new container id
Detached (-d) 若是在docker run 後面追加-d=true或者-d,則containter將會運行在後臺模式(Detached mode)。此時全部I/O數據只能經過網絡資源或者共享卷組來進行交互。由於container再也不監聽你執行docker run的這個終端命令行窗口。但你能夠經過執行docker attach 來從新掛載這個container裏面。須要注意的時,若是你選擇執行-d使container進入後臺模式,那麼將沒法配合」–rm」參數。
Foregroud
若是在docker run後面沒有追加-d參數,則container將默認進入前臺模式(Foregroud mode)。Docker會啓動這個container,同時將當前的命令行窗口掛載到container的標準輸入,標準輸出和標準錯誤中。也就是container中全部的輸出,你均可以再當前窗口中查看到。甚至docker能夠虛擬出一個TTY窗口,來執行信號中斷。這一切都是能夠配置的:docker
-a=[] : Attach to STDIN
, STDOUT
and/or STDERR
-t=false : Allocate a pseudo-tty
–sig-proxy=true : Proxify all received signal to the process (non-TTY mode only)
-i=false : Keep STDIN open even if not attached
若是在執行run命令時沒有指定-a,那麼docker默認會掛載全部標準數據流,包括輸入輸出和錯誤。你能夠特別指定掛載哪一個標準流。shell
$ sudo docker run -a stdin -a stdout -i -t ubuntu /bin/bash (只掛載標準輸入輸出)apache
對於執行容器內的交互式操做,例如shell腳本。咱們必須使用 -i -t來申請一個控制檯同容器進行數據交互。可是當經過管道同容器進行交互時,就不能使用-t. 例以下面的命令
echo test | docker run -i busybox cat
Container identification Name (–name) 給container命名有三種方式:ubuntu
1. 使用UUID長命名(「f78375b1c487e03c9438c729345e54db9d20cfa2ac1fc3494b6eb60872e74778」)
2. 使用UUID短命令(「f78375b1c487」)
3. 使用Name(「evil_ptolemy」)
這個UUID標示是由Docker deamon來生成的。若是你在執行docker run時沒有指定 –name,那麼deamon會自動生成一個隨機數字符串當作UUID。可是對於一個container來講有個name會很是方便,由於你能夠當你須要link其它容器時或者其餘相似須要區分其它容器時,使用容器名稱會簡化操做。不管container運行在前臺或者後臺,這個名字都是有效的。
PID equivalent 當你在運行docker時有自動化的要求,那麼你能夠要求Docker將containerID 輸出到你指定的文件中(PIDfile).這種行爲就相似於有些應用程序將自身ID輸出到文件中,方便後續腳本操做。
–cidfile=」「: Write the container ID to the file
Image[:tag] 當一個image的名稱不足以分辨這個image所表明的含義時,你能夠經過tag將版本信息添加到run 命令中來執行特定版本的image。例如: docker run ubuntu:14.04
IPC Settings 默認狀況下,全部容器都開啓了IPC命名空間。
–ipc=」」 : Set the IPC mode for the container,
‘container:centos
若是是MLS系統,則使用下面的命令:安全
使用下面的命令能夠在container內禁用安全策略:bash
若是你須要在container內執行更爲嚴格的安全策略,那麼你能夠爲這個container指定一個策略替代。好比你可使用下面的命令來指定container只容許監聽apache port
注意:此時,在你的host環境中必須存在一個名爲svirt_apache_t的安全策略。
Runtime constraints on CPU and memory 下面的參數能夠用來調整container內的性能參數。
-m=」「: Memory limit (format: , where unit = b, k, m or g)
-c=0 : CPU shares (relative weight)
經過docker run -m 能夠很方便的調整container所使用的內存資源。若是host支持swap內存,那麼使用-m能夠設定比host物理內存還大的值。
一樣,經過-c 能夠調整container的cpu優先級。默認狀況下,全部的container享有相同的cpu優先級和cpu調度週期。但你能夠經過Docker來通知內核給予某個或某幾個container更多的cpu計算週期。
默認狀況下,使用-c或者–cpu-shares 參數值爲0,能夠賦予當前活動container 1024個cpu共享週期。這個0值能夠針對活動的container進行修改來調整不一樣的cpu循環週期。
好比,咱們使用-c或者–cpu-shares =0啓動了C0,C1,C2三個container,使用-c/–cpu-shares=512啓動了C3.這時,C0,C1,C2能夠100%的使用CPU資源(1024),但C3只能使用50%的CPU資源(512)。若是這個host的OS是時序調度類型的,每一個CPU時間片是100微秒,那麼C0,C1,C2將徹底使用掉這100微秒,而C3只能使用50微秒。
Runtime privilege, Linux capabilities, and LXC configuration
–cap-add: Add Linux capabilities
–cap-drop: Drop Linux capabilities
–privileged=false: Give extended privileges to this container
–device=[]: Allows you to run devices inside the container without the –privileged flag.
–lxc-conf=[]: (lxc exec-driver only) Add custom lxc options –lxc-conf=」lxc.cgroup.cpuset.cpus = 0,1」
默認狀況下,Docker的container是沒有特權的。例如不能再container裏面再啓動一個container。這是由於默認狀況下container是不能訪問任何其餘設備的。可是經過」privileged」,container就擁有了訪問任何其餘設備的權限。
當操做者執行docker run –privileged時,Docker將擁有訪問host全部設備的權限,同時Docker也會在apparmor或者selinux作一些設置,使container能夠容易的訪問那些運行在container外部的設備。你能夠訪問Docker blog來獲取更多關於–privileged的用法。
同時,你也能夠限制container只能訪問一些指定的設備。下面的命令將容許container只訪問一些特定設備:
$ sudo docker run –device=/dev/snd:/dev/snd …
默認狀況下,container擁有對設備的讀,寫,建立設備文件的權限。使用:rwm來配合–device,你能夠控制這些權限。
$ sudo docker run –device=/dev/sda:/dev/xvdc –rm -it ubuntu fdisk /dev/xvdc
Command (m for help): q $ sudo 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 $ sudo docker run --device=/dev/sda:/dev/xvdc:w --rm -it ubuntu fdisk /dev/xvdc crash.... $ sudo docker run --device=/dev/sda:/dev/xvdc:m --rm -it ubuntu fdisk /dev/xvdc fdisk: unable to open /dev/xvdc: Operation not permitted
使用–cap-add和–cap-drop,配合–privileged,你能夠更細緻的控制container。默認使用這兩個參數的狀況下,container擁有一系列的內核修改權限。這兩個參數都支持all值,若是你想讓某個container擁有除了MKNOD以外的全部內核權限,那麼能夠執行下面的命令:
RTNETLINK answers: Operation not permitted
fuse: failed to open /dev/fuse: Operation not permitted
The authenticity of host ‘10.10.10.20 (10.10.10.20)’ can’t be established.
ECDSA key fingerprint is 25:34:85:75:25:b0:17:46:05:19:04:93:b5:dd:5f:c6.
Are you sure you want to continue connecting (yes/no)? yes
sven@10.10.10.20’s password:
root@30aa0cfaf1b5:/# ls -la /mnt/src/docker
total 1516
drwxrwxr-x 1 1000 1000 4096 Dec 4 06:08 .
drwxrwxr-x 1 1000 1000 4096 Dec 4 11:46 ..
-rw-rw-r– 1 1000 1000 16 Oct 8 00:09 .dockerignore
-rwxrwxr-x 1 1000 1000 464 Oct 8 00:09 .drone.yml
drwxrwxr-x 1 1000 1000 4096 Dec 4 06:11 .git
-rw-rw-r– 1 1000 1000 461 Dec 4 06:08 .gitignore
若是docker啓動時選擇了lxc-driver,(docker -d –exec-driver=lxc)。那麼就可使用–lxc-conf來設定LXC參數。但須要注意的是,將來host上面的docker deamon有可能不會使用LXC,因此這些參數有可能會包含一些沒有實現的配置功能。那麼意味着,操做者在操做這些參數時必需要十分熟悉LXC。
特別注意:當你使用–lxc-conf修改container參數後,docker deamon將再也不管理這些參數,那麼必須由操做者自行進行管理。好比說,你使用–lxc-conf修改了container的IP地址,那麼在/etc/hosts裏面是不會自動體現的,須要你自行維護。
Overriding Dockerfile image defaults 當開發者使用Dockerfile進行build或者使用commit提交container時,開發人員能夠設定一些image默認參數。
這些參數中,有四個是沒法被覆蓋的: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)USERWORKDIR
CMD (default command or options)
$ sudo docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG…]
這條命令中的COMMAND部分是可選的。由於這個IMAGE在build時,開發人員可能已經設定了默認執行的command。做爲操做人員,你可使用上面命令中新的command來覆蓋舊的command。
若是image中設定了ENTRYPOINT,那麼命令中的CMD也能夠做爲參數追加到ENTRYPOINT中。
ENTRYPOINT (default command to execute at runtime)
–entrypoint=」「: Overwrite the default entrypoint set by the image
這個ENTRYPOINT和COMMAND相似,它指定了當container執行時,須要啓動哪些進程。相對COMMAND而言,ENTRYPOINT是比較困難進行覆蓋的,這個ENTRYPOINT可讓container設定默認啓動行爲,因此當container啓動時,你能夠執行任何一個二進制可執行程序。你也能夠經過COMMAND給這個ENTRYPOINT傳遞參數。但當你須要再container中執行其餘進程時,你就能夠指定其餘ENTRYPOINT了。
下面就是一個例子,container能夠在啓動時自動執行shell,而後啓動其它進程。
$ sudo docker run -i -t –entrypoint /bin/bash example/redis
EXPOSE (incoming ports) Dockefile在網絡方面除了提供一個EXPOSE以外,沒有提供其它選項。下面這些參數能夠覆蓋Dockefile的expose默認值:
–expose=[]: Expose a port or a range of ports from the container
without publishing it to your host
-P=false : Publish all exposed ports to the host interfaces
-p=[] : Publish a container᾿s port to the host (format:
ip:hostPort:containerPort | ip::containerPort |
hostPort:containerPort | containerPort)
(use ‘docker port’ to see the actual mapping)
–link=」」 : Add link to another container (name:alias)
–expose可讓container接受外部傳入的數據。container內監聽的port不須要和外部host的port相同。好比說在container內部,一個HTTP服務監聽在80端口,對應外部host的port就多是49880.
操做人員可使用–expose,讓新的container訪問到這個container。具體有三個方式:
1. 使用-p來啓動container。
2. 使用-P來啓動container。
3. 使用–link來啓動container。
若是使用-p或者-P,那麼container會開發部分端口到host,只要對方能夠鏈接到host,就能夠鏈接到container內部。當使用-P時,docker會在host中隨機從49153 和65535之間查找一個未被佔用的端口綁定到container。你可使用docker port來查找這個隨機綁定端口。
當你使用–link方式時,做爲客戶端的container能夠經過私有網絡形式訪問到這個container。同時Docker會在客戶端的container中設定一些環境變量來記錄綁定的IP和PORT。
ENV (environment variables)VariableValueHOMESet based on the value of USERHOSTNAMEThe hostname associated with the containerPATHIncludes popular directories, such as :
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binTERMxterm if the container is allocated a psuedo-TTY 當container啓動時,會自動在container中初始化這些變量。
操做人員能夠經過-e來設定任意的環境變量。甚至覆蓋已經存在的環境變量,或者是在Dockerfile中經過ENV設定的環境變量。
$ sudo docker run -e 「deep=purple」 –rm ubuntu /bin/bash -c export
declare -x HOME=」/」
declare -x HOSTNAME=」85bc26a0e200」
declare -x OLDPWD
declare -x PATH=」/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin」
declare -x PWD=」/」
declare -x SHLVL=」1」
declare -x container=」lxc」
declare -x deep=」purple」
操做人員能夠經過-h來設定hostname。也可使用」–link name:alias」來設定環境變量,當使用–link後,docker將根據後面提供的IP和PORT信息來鏈接服務端container。下面就是使用redis的例子:
$ sudo docker run -d –name redis-name dockerfiles/redis
4241164edf6f5aca5b0e9e4c9eccd899b0b8080c64c0cd26efe02166c73208f3
declare -x HOME=」/」
declare -x HOSTNAME=」acda7f7b1cdc」
declare -x OLDPWD
declare -x PATH=」/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin」
declare -x PWD=」/」
declare -x REDIS_ALIAS_NAME=」/distracted_wright/redis」
declare -x REDIS_ALIAS_PORT=」tcp://172.17.0.32:6379」
declare -x REDIS_ALIAS_PORT_6379_TCP=」tcp://172.17.0.32:6379」
declare -x REDIS_ALIAS_PORT_6379_TCP_ADDR=」172.17.0.32」
declare -x REDIS_ALIAS_PORT_6379_TCP_PORT=」6379」
declare -x REDIS_ALIAS_PORT_6379_TCP_PROTO=」tcp」
declare -x SHLVL=」1」
declare -x container=」lxc」