Docker容器-精講版

Java

如何讓容器長期運行

容器的生命周期依賴於啟動時執行的命令,只要該命令不結束,容器也就不會退出。

@通過docker attach可以attach到容器啟動命令的終端

注意:可以通過ctrl+p然後ctrl+q組合鍵退出attach終端

@通過docker exec進入到相同的容器

docker exec -it docker_name bash

attach vs exec

1.attach 直接進入容器啟動命令的終端,不會啟動新的進程

2.exec 則是在容器中打開新的終端,並且可以啟動新的進程

3.如果想直接在終端中查看啟動命令的輸出,用attach;其他情況使用exec

如果查看啟動命令的輸出也可以用docker logs -f <container>

Advertisements

容器的運行:

按用途容器大致可分為兩類:服務類容器和工具類容器『

常用的操作比如:run,stop,restart,pause,rm

常用命令:

docker stop

docker start

docker restart

docker kill

docker run --restart=always

docker pause(不佔用cpu資源)

docker rm

docker rm -v $(docker ps -aq)

容器資源限制:

一個docker host上會運行若干容器,每個容器都需要cpu,內存和io資源。對於kvm,vmware等虛擬化技術,用戶可以控制分配多少cpu,內存資源給每個虛擬機。對於容器,Docker也提供類似的機制避免某個容器因佔用太多資源而影響其他容器乃至整個host的性能。

Advertisements

內存限制:

與操作系統類似,容器可以使用的內存包括兩部分:物理內存和swap。Docker通過下面兩個參數來控制容器的使用量。

@-m或者--memory :設置內存的使用配額,例如:100M,2G

@--memory-swap:設置內存+swap的使用限制

實例:

docker run -it -m 200M --memory-swap=400M --name vm9 docker.io/progrium/stress --vm 1 --vm-bytes 300M

其含義是允許該容器最多使用200M內存和200M的swap。默認情況下,上面兩組參數為-1,即對容器的內存和swap的使用沒有限制。

--vm 1 :啟動1個內存工作協程

--vm-bytes 300M :每個線程分配300M內存

如果讓工作線程分配的內存超過400M,則會stress線程報錯,容器退出。

如果在啟動容器時只指定-m,不指定--memory-swap,那麼--memory-swap默認為-m的兩倍

比如:

docker run -it -m 200M centos

解釋為容器最多使用200M物理內存和200M swap

cpu限制:

默認情況下,所有容器可以平等的使用host cpu資源並且沒有限制。

Docker可以通過-c或者--cpu-shares設置容器使用cpu權重,如果不指定,默認值為1024.

與內存配額不同,通過-c設置的cpu shares並不是cpu資源的絕對數量,而是一個相對的權重值。某個容器最終能分配到的cpu資源取決於它的cpu share中所有cpushare總和的比例。

說白了,就是通過cpu share可以設置容器使用cpu的優先順序。

需要注意的是,這種按權重分配cpu只會發生在cpu資源緊張的情況下。

實驗對比:(實驗機為2核cpu)

1.docker run -it --name vm13 -c 2048 docker.io/progrium/stress --cpu 2

2.docker run -it --name vm14 -c 1024 docker.io/progrium/stress --cpu 2

top查看結果:

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

9102 root 20 0 7308 96 0 R 64.5 0.0 2:01.25 /usr/bin/stress --verbose --cpu 2

9103 root 20 0 7308 96 0 R 64.5 0.0 1:59.50 /usr/bin/stress --verbose --cpu 2

9245 root 20 0 7308 96 0 R 35.2 0.0 0:37.38 /usr/bin/stress --verbose --cpu 2

9246 root 20 0 7308 96 0 R 35.2 0.0 0:37.79 /usr/bin/stress --verbose --cpu 2

如果停止掉權重大的容器壓測實驗,則2號實驗也能滿額cpu。

Java

Block IO限制:

Block IO是另一種限制容器使用的資源。Block IO 指的是磁碟的讀寫,docker也可以通過設置權重,限制bps和iops的方式控制容器的讀寫磁碟的帶寬。

註:目前Block IO限額只對direct io(不使用文件緩存)有效

Block IO權重

默認情況下,所有容器能平等的讀寫磁碟,可以通過設置--blkio-weight參數來改變容器block IO的優先順序。

--blkio-weight 與--cpu-weight類似,設置的是相對權重值,默認為500。

限制 bps 和 iops:

bps 是 byte per second,每秒讀寫的數據量。

iops 是 io per second,每秒 IO 的次數。

可通過以下參數控制容器的 bps 和 iops:

--device-read-bps,限制讀某個設備的 bps。

--device-write-bps,限制寫某個設備的 bps。

--device-read-iops,限制讀某個設備的 iops。

--device-write-iops,限制寫某個設備的 iops。

下面這個例子限制容器寫 /dev/sda 的速率為 30 MB/s

docker run -it --device-write-bps /dev/sda:30MB centos

限制資源的底層技術:

cgroup和namespace是最重要的兩種技術。cgroup實現資源限制,namespace實現資源隔離。

cgroup:

cgroup全程control cgroup。linux操作系統通過設置進程使用cpu,內存和IO資源的限額,前面配置--cpu--shares,-m,--device-write-bps實際上是在配置cgroup。

cgroup可以在/sys/fs/cgroup/中找到它。

註釋:docker version 1.12.6 目錄為/sys/fs/cgroup/xxx/system.slice

namespace:

每個容器中,我們都可以看到文件系統,網卡等資源。linux實現這種方式的技術是namespace,namespace實現了容器間資源的隔離。

linux使用了六種namespace,分別對應:mount,UTS,IPC,PID,NETWORK和USER.

Mount namespace

Mount namespace 讓容器看上去擁有整個文件系統。

容器有自己的 / 目錄,可以執行 mount 和 umount 命令。當然我們知道這些操作只在當前容器中生效,不會影響到 host 和其他容器。

UTS namespace

簡單的說,UTS namespace 讓容器有自己的 hostname。 默認情況下,容器的 hostname 是它的短ID,可以通過 -h 或 --hostname 參數設置。

IPC namespace

IPC namespace 讓容器擁有自己的共享內存和信號量(semaphore)來實現進程間通信,而不會與 host 和其他容器的 IPC 混在一起。

PID namespace

我們前面提到過,容器在 host 中以進程的形式運行。通過 ps axf 可以查看容器進程。

Network namespace

Network namespace 讓容器擁有自己獨立的網卡、IP、路由等資源。我們會在後面網路章節詳細討論。

User namespace

User namespace 讓容器能夠管理自己的用戶,host 不能看到容器中創建的用戶。

Java

Advertisements

你可能會喜歡