效能環境之docker操作指南3(全網最全)
docker run
Usage: docker run [OPTIONS] IMAGE [COMMAND]
[ARG...]
-a
-a,
--attach=[]
Attach to STDIN, STDOUT or STDERR
如果在執行run命令時沒有指定-a,那麼docker預設會掛載所有標準資料流,包括輸入輸出和錯誤。你可以特別指定掛載哪個標準流。
$ docker run -a stdin -a stdout -i -t ubuntu:14.04
/bin/bash
(只掛載標準輸入輸出)
--add-host
--add-host=[]
Add a custom host-to-IP mapping (host:ip)
新增host-ip到容器的hosts檔案
$ docker run -it --add-host db:192.168.1.1 ubuntu:14.04
/bin/bash
root@70887853379d:/# cat /etc/hosts
172.17.0.2
70887853379d
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
192.168.1.1 db
--blkio-weight
--blkio-weight=0
Block IO (relative weight), between 10 and 1000
相對於CPU和記憶體的配額控制,docker對磁碟IO的控制相對不成熟,大多數都必須在有宿主機裝置的情況下使用。主要包括以下引數:
- device-read-bps:限制此裝置上的讀速度(bytes per second),單位可以是kb、mb或者gb.
- -device-read-iops:通過每秒讀IO次數來限制指定裝置的讀速度。
- –device-write-bps :限制此裝置上的寫速度(bytes per second),單位可以是kb、mb或者gb。
- –device-write-iops:通過每秒寫IO次數來限制指定裝置的寫速度。
- –blkio-weight:容器預設磁碟IO的加權值,有效值範圍為10-100。
- –blkio-weight-device: 針對特定裝置的IO加權控制。其格式為DEVICE_NAME:WEIGHT
儲存配額控制的相關引數,可以參考Red Hat文件中blkio這一章,瞭解它們的詳細作用。
磁碟IO配額控制示例
blkio-weight
要使–blkio-weight生效,需要保證IO的排程演算法為CFQ。可以使用下面的方式檢視:
root@ubuntu:~# cat /sys/block/sda/queue/scheduler
noop [deadline] cfq
使用下面的命令建立兩個–blkio-weight值不同的容器:
$ docker run -ti –rm –blkio-weight 100 ubuntu:stress
$ docker run -ti –rm –blkio-weight 1000 ubuntu:stress
在容器中同時執行下面的dd命令,進行測試:
time dd if=/dev/zero of=test.out bs=1M count=1024 oflag=direct
device-write-bps
使用下面的命令建立容器,並執行命令驗證寫速度的限制。
$ docker run -tid –name disk1 –device-write-bps /dev/sda:1mb ubuntu:stress
容器空間大小限制
在docker使用devicemapper作為儲存驅動時,預設每個容器和映象的最大大小為10G。如果需要調整,可以在daemon啟動引數中,使用dm.basesize來指定,但需要注意的是,修改這個值,不僅僅需要重啟docker daemon服務,還會導致宿主機上的所有本地映象和容器都被清理掉。
使用aufs或者overlay等其他儲存驅動時,沒有這個限制。
--cidfile=
--cidfile=
Write the container ID to the file
將container ID儲存到cid_file, 儲存的格式為長UUID
$ docker run -it --cidfile=cid_file ubuntu:14.04
/bin/bash
#cat cid_file
5fcf835f2688844d1370e6775247c35c9d36d47061c4fc73e328f9ebf920b402
--cpu-shares
--cpu-shares=0 CPU shares (relative weight)
預設情況下,使用-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微秒。
--cpu-period, --cpu-quota
--cpu-period=0
Limit CPU CFS (Completely
Fair
Scheduler) period
--cpu-quota=0
Limit CPU CFS (Completely
Fair
Scheduler) quota
--cpu-period和--cpu-quota,這兩個引數是相互配合的,--cpu-period和--cpu-quota的這種配置叫 Ceiling Enforcement Tunable Parameters,--cpu-shares的這種配置叫Relative Shares Tunable Parameters。--cpu-period是用來指定容器對CPU的使用要在多長時間內做一次重新分配,而--cpu-quota是用來指定在這個週期內,最多可以有多少時間用來跑這個容器。跟--cpu-shares不同的是這種配置是指定一個絕對值,而且沒有彈性在裡面,容器對CPU資源的使用絕對不會超過配置的值。
比如說A容器配置的--cpu-period=100000 --cpu-quota=50000,那麼A容器就可以最多使用50%個CPU資源,如果配置的--cpu-quota=200000,那就可以使用200%個CPU資源。
那麼有什麼樣的應用場景呢?簡單舉個例子,加入對外提供A和B兩個服務,但是A的優先順序比B要高,假如只用--cpu-shares來配置,B服務佔用資源太高時是會對A有一定的影響的,但是如果通過--cpu-period和--cpu-quota來配置,就能起到絕對的控制,做到無論B怎麼樣,都不會影響到A。
cpu-period和cpu-quota的單位為微秒(μs)。cpu-period的最小值為1000微秒,最大值為1秒(10^6 μs),預設值為0.1秒(100000 μs)。cpu-quota的值預設為-1,表示不做控制。
--cpuset-cpus, --cpuset-mems
--cpuset-cpus=
CPUs
in which to allow execution (0-3,
0,1)
--cpuset-mems=
MEMs
in which to allow execution (0-3,
0,1)
對多核CPU的伺服器,docker還可以控制容器執行限定使用哪些cpu核心和記憶體節點,即使用–cpuset-cpus和–cpuset-mems引數。對具有NUMA拓撲(具有多CPU、多記憶體節點)的伺服器尤其有用,可以對需要高效能運算的容器進行效能最優的配置。如果伺服器只有一個記憶體節點,則–cpuset-mems的配置基本上不會有明顯效果。
使用示例:
命令docker run -tid –name cpu1 –cpuset-cpus 0-2 ubuntu,表示建立的容器只能用0、1、2這三個核心。最終生成的cgroup的cpu核心配置如下:
# cat /sys/fs/cgroup/cpuset/docker/<容器的完整長ID>/cpuset.cpus
0-2
通過docker exec <容器ID> taskset -c -p 1(容器內部第一個程序編號一般為1),可以看到容器中程序與CPU核心的繫結關係,可以認為達到了繫結CPU核心的目的。
-d, --detach
-d,
--detach=false Run container in background and print container ID
如果在docker run 後面追加-d=true或者-d,則containter將會執行在後臺模式(Detached mode)。此時所有I/O資料只能通過網路資源或者共享卷組來進行互動。因為container不再監聽你執行docker run的這個終端命令列視窗。但你可以通過執行docker attach 來重新掛載這個container裡面。需要注意的時,如果你選擇執行-d使container進入後臺模式,那麼將無法配合"--rm"引數。
--device=
--device=[]
Add a host device to the container
--disable-content-trust
--disable-content-trust=true Skip image verification
跳過映象驗證。
--dns
--dns=[]
Set custom DNS servers
自定義DNS.
$ docker run -it --dns=8.8.8.8
--rm ubuntu:14.04
/bin/bash
root@b7a6f0e63e65:/# cat /etc/resolv.conf
nameserver 8.8.8.8
--dns-opt
--dns-opt=[]
Set DNS options
--dns-search
--dns-search=[]
Set custom DNS search domains
-e, --env
-e,
--env=[]
Set environment variables
自這義環境變數。
--entrypoint
--entrypoint=
Overwrite the default ENTRYPOINT of the image
字面意思是進入點,而它的功能也恰如其意。
An ENTRYPOINT allows you to configure a container that will run as an executable.它可以讓你的容器功能表現得像一個可執行程式一樣。
示例一:
使用下面的ENTRYPOINT構造映象:
ENTRYPOINT ["/bin/echo"]
那麼docker build出來的映象以後的容器功能就像一個/bin/echo程式:
比如我build出來的映象名稱叫imageecho,那麼我可以這樣用它:
docker run -it imageecho “this is a test”
這裡就會輸出”this is a test”這串字元,而這個imageecho映象對應的容器表現出來的功能就像一個echo程式一樣。 你新增的引數“this is a test”會新增到ENTRYPOINT後面,就成了這樣 /bin/echo “this is a test” 。
示例二:
ENTRYPOINT ["/bin/cat"]
構造出來的映象你可以這樣執行(假設名為st):
docker run -it st /etc/fstab
這樣相當: /bin/cat /etc/fstab 這個命令的作用。執行之後就輸出/etc/fstab裡的內容。
--env-file
--env-file=[]
Read
in a file of environment variables
讀取設定環境變數的檔案.
--expose
--expose=[]
Expose a port or a range of ports
告訴Docker服務端容器暴露的埠號,供互聯絡統使用。
$ docker run -it --expose=22
--rm ubuntu:14.04
/bin/bash
--group-add
--group-add=[]
Add additional groups to join
-h, --hostname
-h,
--hostname=
Container host name
設定容器主機名。
$ docker run -it --hostname=web --rm ubuntu:14.04
/bin/bash
進入容器後
root@web:/#
-i, --interactive=false
-i,
--interactive=false Keep STDIN open even if not attached
保持標準輸入,常同-t一起使用來申請一個控制檯進行資料互動。
--ipc
--ipc= IPC namespace to use
IPC(POSIX/SysV IPC)名稱空間提供了相互隔離的命名共享記憶體,訊號燈變數和訊息佇列。
共享記憶體可以提高程序資料互動速度。共享記憶體一般用在database和高效能應用(C/OpenMPI, C++/using boost libraries)上或者金融服務上。如果需要容器裡面部署上述型別的應用,那麼就應該在多個容器直接採取共享記憶體了。
--kernel-memory
--kernel-memory=
Kernel memory limit
核心記憶體,不會被交換到swap上。一般情況下,不建議修改,可以直接參考docker的官方文件。
-l, --label
-l,
--label=[]
Set meta data on a container
--label-file=[]
Read
in a line delimited file of labels
--link
--link=[]
Add link to another container
用於連線兩個容器。
示例:連線兩個容器
啟動容器1:web
$ docker run --name web -d -p 22
-p 80
-it webserver:v1
啟動容器2:ap1連線到web,並命名為apache
$ docker run --name ap1 --link=web:apache -d -p 22
-p 80
-it webserver:v1
--log-driver
--log-driver=
Logging driver for container
--log-opt=[]
Log driver options
Docker增加了對json-file型(預設)log driver的rotate功能,我們可通過max-size和max-file兩個–log-opt來配置。比如:我們啟動一個nginx容器,採用 json-file日誌引擎,每個log檔案限制最大為1k,輪轉的日誌個數為5個:
docker run -d --log-driver=json-file --log-opt max-size=1k
--log-opt max-file=5
--name webserver -p 9988:80 nginx
有了rotate,我們就不必擔心某個container的日誌暴漲而將同host的其他container拖死了。
--mac-address
--mac-address=
Container MAC address
(e.g. 92:d0:c6:0a:29:33)
設定容器的mac地址。
-m, --memory
-m,
--memory=
Memory limit
設定容器使用的最大記憶體上限。預設單位為byte,可以使用K、G、M等帶單位的字串。
預設情況下,容器可以使用主機上的所有空閒記憶體。
設定容器的記憶體上限,參考命令如下所示:
docker run -tid —name mem1 —memory 128m ubuntu:14.04
/bin/bash
預設情況下,除了–memory指定的記憶體大小以外,docker還為容器分配了同樣大小的swap分割槽,也就是說,上面的命令創建出的容器實際上最多可以使用256MB記憶體,而不是128MB記憶體。如果需要自定義swap分割槽大小,則可以通過聯合使用–memory–swap引數來實現控制。
對上面的命令建立的容器,可以檢視到在cgroups的配置檔案中,檢視到容器的記憶體大小為128MB (128×1024×1024=134217728B),記憶體和swap加起來大小為256MB (256×1024×1024=268435456B)。
#cat /sys/fs/cgroup/memory/docker/<容器的完整ID>/memory.limit_in_bytes
134217728
#cat /sys/fs/cgroup/memory/docker/<容器的完整ID>/memory.memsw.limit_in_bytes
268435456
注意:執行上述命令時,命令列可能會輸出下面的警告:
WARNING: Your kernel does not support swap limit capabilities, memory limited without swap.
這是因為主機上預設不啟用cgroup來控制swap分割槽,可以參考docker官方的相應文件,修改grub啟動引數。
--memory-reservation
--memory-reservation=
Memory soft limit
啟用彈性的記憶體共享,當宿主機資源充足時,允許容器儘量多地使用記憶體,當檢測到記憶體競爭或者低記憶體時,強制將容器的記憶體降低到memory-reservation所指定的記憶體大小。按照官方說法,不設定此選項時,有可能出現某些容器長時間佔用大量記憶體,導致效能上的損失。
--memory-swap
--memory-swap=
Total memory (memory + swap),
'-1' to disable swap
等於記憶體和swap分割槽大小的總和,設定為-1時,表示swap分割槽的大小是無限的。預設單位為byte,可以使用K、G、M等帶單位的字串。如果–memory-swap的設定值小於–memory的值,則使用預設值,為–memory-swap值的兩倍。
--memory-swappiness
--memory-swappiness=-1
Tuning container memory swappiness (0 to 100)
控制程序將實體記憶體交換到swap分割槽的傾向,預設係數為60。係數越小,就越傾向於使用實體記憶體。值範圍為0-100。當值為100時,表示儘量使用swap分割槽;當值為0時,表示禁用容器 swap 功能(這點不同於宿主機,宿主機 swappiness 設定為 0 也不保證 swap 不會被使用)。
--name
--name=
Assign a name to the container
為容器指定一個名字。
$ docker run -it --name=web ubuntu:14.04
/bin/bash
--net
--net=default Set the Network
for the container
以下是網路設定中常用的引數:
- none 關閉container內的網路連線:
將網路模式設定為none時,這個container將不允許訪問任何外部router。這個container內部只會有一個loopback介面,而且不存在任何可以訪問外部網路的router。 - bridge 通過veth介面來連線contianer 預設選項:
Docker預設是將container設定為bridge模式。此時在host上面講存在一個docker0的網路介面,同時會針對container建立一對veth介面。其中一個veth介面是在host充當網絡卡橋接作用,另外一個veth介面存在於container的名稱空間中,並且指向container的loopback。Docker會自動給這個container分配一個IP,並且將container內的資料通過橋接轉發到外部。 - host 允許container使用host的網路堆疊資訊:
當網路模式設定為host時,這個container將完全共享host的網路堆疊。host所有的網路介面將完全對container開放。container的主機名也會存在於host的hostname中。這時,container所有對外暴露的port和對其它container的link,將完全失效。 - Container:
當網路模式設定為Container時,這個container將完全複用另外一個container的網路堆疊。同時使用時這個container的名稱必須要符合下面的格式:--net container:.
比如當前有一個綁定了本地地址localhost的redis container。如果另外一個container需要複用這個網路堆疊,則需要如下操作:
$ docker run -d --name redis example/redis --bind 127.0.0.1
# use the redis container's network stack to access localhost
$ sudo docker run --rm -ti --net container:redis example/redis-cli -h 127.0.0.1
--oom-kill-disable
--oom-kill-disable=false Disable OOM Killer
-P, --publish-all
-P,
--publish-all=false Publish all exposed ports to random ports
對外對映所有埠。
-p, --publish
-p,
--publish=[]
Publish a container's port(s) to the host
對外對映指定埠,如不指定對映後的埠將隨機指定。
$ docker run –d -p 10022:22
-p 10080:80
-it webserver:v1
使用docker run來啟動我們建立的容器。-d讓容器以後臺方式執行。使用多個-p來對映多個埠,將容器的22埠對映為本地的10022,80對映為10080。
--pid
--pid= PID namespace to use
設定容器的PID模式。兩種:
host: use the host's PID namespace inside the container.
Note: the host mode gives the container full access to local PID and is therefore considered insecure.
--privileged
--privileged=false Give extended privileges to this container
預設情況下container是不能訪問任何其他裝置的。但是通過"privileged",container就擁有了訪問任何其他裝置的許可權。
當操作者執行docker run --privileged時,Docker將擁有訪問host所有裝置的許可權
$ docker run -it --rm --privileged ubuntu:14.04
/bin/bash
--read-only
--read-only=false Mount the container's root filesystem as read only
啟用後,容器的檔案系統將為只讀。
$ docker run -it --rm --read-only ubuntu:14.04
/bin/bash
root@d793e24f0af1:/# touch a
touch: cannot touch 'a':
Read-only file system
- no,預設策略,在容器退出時不重啟容器
- on-failure,在容器非正常退出時(退出狀態非0),才會重啟容器
- on-failure:3,在容器非正常退出時重啟容器,最多重啟3次
- always,在容器退出時總是重啟容器,當作業系統或docker服務重啟時,該容器總能隨系統啟動
- unless-stopped,在容器退出時總是重啟容器,但是不考慮在Docker守護程序啟動時就已經停止了的容器
示例:
$ docker run -it --restart=always ubuntu:14.04
/bin/bash
--rm
--rm=false Automatically remove the container when it exits
當容器退出時,清除所有該容器的資訊。
--security-opt
--security-opt=[]
Security
Options
安全選項。
--sig-proxy
--sig-proxy=true|false
Proxy received signals to the process (non-TTY mode only). SIGCHLD, SIGSTOP, and SIGKILL are not proxied.
The default is true.
--stop-signal
--stop-signal=SIGTERM Signal to stop a container, SIGTERM by default
-t, --tty
-t,
--tty=false Allocate a pseudo-TTY
分配一個模擬終端,常和-i一塊使用.
-u, --user
-u,
--user=
Username or UID (format:
<name|uid>[:<group|gid>])
Sets the username or UID used and optionally the groupname or GID for the specified command.
The followings examples are all valid:
--user [user | user:group | uid | uid:gid | user:gid | uid:group ]
Without this argument the command will be run as root in the container.
--ulimit
--ulimit=[]
Ulimit options
--default-ulimit,docker daemon的啟動引數,能夠指定預設container ulimit配置。如果此引數沒配置,則預設從docker daemon繼承;
--ulimit,docker run的引數,能夠覆蓋docker daemon指定的ulimit預設值。如果此引數沒配置,則預設從default-ulimit繼承;
$ docker run -it -d --ulimit nofile=20480:40960 ubuntu:14.04
/bin/bash
-v, --volume
-v,
--volume=[]
Bind mount a volume
可以使用帶有 -v 引數的 docker run 命令給容器新增一個數據卷.
1.新增資料卷/data1,會自動建立目錄
$ docker run -it --name web -v /data1 ubuntu:14.04
/bin/bash
root@fac11d44de3e:/# df -h
/dev/disk/by-uuid/1894172f-589b-4e8b-b763-7126991c7fbb
29G
2.6G
25G
10%
/data1
root@fac11d44de3e:/# cd /data1
2.將宿主機的目錄新增到容器
將宿主機的/data_web載入為容器/data目錄
$ docker run -it --name web -v /data_web:/data ubuntu:14.04
/bin/bash
--volumes-from
--volumes-from=[]
Mount volumes from the specified container(s)
從其他容器掛載目錄。
1.建立dbdata容器,並含有/data資料卷
$ docker run -it -v /data --name dbdata ubuntu:14.04
/bin/bash
2.建立webserver1掛載dbdata的資料卷
$ docker run -it --volumes-from dbdata --name webserver1 ubuntu:14.04
/bin/bash
-w, --workdir
-w,
--workdir=
Working directory inside the container
設定容器的工作目錄。
$ docker run -it --workdir="/data" ubuntu:14.04
/bin/bash
root@7868da4d2846:/data#
未完待續......