容器是Docker的另一個核心概念。簡單來說帝嗡,容器是鏡像的一個運(yùn)行實(shí)例峡蟋。所不同的是坟桅,鏡像是靜態(tài)的只讀文件,而容器帶有運(yùn)行時需要的可寫文件層蕊蝗。如果認(rèn)為虛擬機(jī)是模擬運(yùn)行的一整套操作系統(tǒng)(包括內(nèi)核仅乓、應(yīng)用運(yùn)行態(tài)環(huán)境和其他系統(tǒng)環(huán)境)和跑在上面的應(yīng)用,那么Docker容器就是獨(dú)立運(yùn)行的一個(或一組)應(yīng)用蓬戚,以及它們必需的運(yùn)行環(huán)境夸楣。
創(chuàng)建容器
新建容器 docker create
可以使用docker create命令新建一個容器,例如:
$ docker create -it ubuntu:latest
af8f4f922dafee22c8fe6cd2ae11d16e25087d61f1b1fa55b36e94db7ef45178
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af8f4f922daf ubuntu:latest "/bin/bash" 17 seconds ago Created silly_euler
使用docker create命令新建的容器處于停止?fàn)顟B(tài)子漩,可以使用docker start命令來啟動它豫喧。
Create命令和后續(xù)的run命令支持的選項(xiàng)都十分復(fù)雜,主要包括如下幾大類:與容器運(yùn)行模式相關(guān)幢泼、與容器和環(huán)境配置相關(guān)紧显、與容器資源限制和安全保護(hù)相關(guān)。
啟動容器 docker start
使用docker start命令來啟動一個已經(jīng)創(chuàng)建的容器缕棵,例如啟動剛創(chuàng)建的ubuntu容器:
$ docker start af
af
此時孵班,通過docker ps命令可以查看一個運(yùn)行中的容器:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
af8f4f922daf ubuntu:latest "/bin/bash" 2 minutes ago Up 7 seconds silly_euler
新建并啟動容器 docker run
除了創(chuàng)建容器后通過start命令來啟動,也可以直接新建并啟動容器招驴。所需要的命令主要為docker run篙程,等價于先執(zhí)行docker create命令,再執(zhí)行docker start命令别厘。
例如虱饿,下面的命令輸出一個“Hello World”,之后容器自動終止:
$ docker run ubuntu /bin/echo 'Hello world'
Hello world
當(dāng)利用docker run來創(chuàng)建并啟動容器時触趴,Docker在后臺運(yùn)行的標(biāo)準(zhǔn)操作包括:
- 檢查本地是否存在指定的鏡像氮发,不存在就從公有倉庫下載;
- 利用鏡像創(chuàng)建一個容器雕蔽,并啟動該容器折柠;
- 分配一個文件系統(tǒng)給容器,并在只讀的鏡像層外面掛載一層可讀寫層批狐;
- 從宿主主機(jī)配置的網(wǎng)橋接口中橋接一個虛擬接口到容器中扇售;
- 從網(wǎng)橋的地址池配置一個IP地址給容器;
- 執(zhí)行用戶指定的應(yīng)用程序嚣艇;
- 執(zhí)行完畢后容器被自動終止承冰。
下面的命令啟動一個bash終端,允許用戶進(jìn)行交互:
$ docker run -it ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#
其中食零,-t選項(xiàng)讓Docker分配一個偽終端(pseudo-tty)并綁定到容器的標(biāo)準(zhǔn)輸入上困乒,-i則讓容器的標(biāo)準(zhǔn)輸入保持打開。更多的命令選項(xiàng)可以通過man docker -run命令來查看贰谣。
守護(hù)態(tài)運(yùn)行 docker run -d
更多的時候娜搂,需要讓Docker容器在后臺以守護(hù)態(tài)Daemonized)形式運(yùn)行迁霎。此時,可以通過添加- d參數(shù)來實(shí)現(xiàn)百宇。
例如下面的命令會在后臺運(yùn)行容器:
$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
ce554267d7a4c34eefc92c5517051dc37b918b588736d0823e4c846596b04d83
容器啟動后會返回一個唯一的id考廉,也可以通過 docker ps命令來查看容器信息。
此時携御,要獲取容器的輸出信息昌粤,可以如下使用docker logs命令:
$ docker logs ce5
hello world
hello world
hello world
. . .
終止容器 docker stop
可以使用docker stop來終止一個運(yùn)行中的容器。該命令的格式為docker stop [-t|--time[=10]][CONTAINER...]啄刹。
該首先向容器發(fā)送SIGTERM信號涮坐,等待一段超時時間(默認(rèn)為10秒)后,再發(fā)送SIGKILL信號來終止容器誓军。
docker kill命令會直接發(fā)送SIGKILL信號來強(qiáng)行終止容器袱讹。
進(jìn)入容器
在使用-d參數(shù)時,容器啟動后會進(jìn)入后臺谭企,用戶無法看到容器中的信息廓译,也無法進(jìn)行操作。
這個時候如果需要進(jìn)入容器進(jìn)行操作债查,有多種方法非区,包括使用官方的attach或exec命令,以及第三方的nsenter工具等盹廷。下面分別介紹一下征绸。
attach命令
$ docker run -itd ubuntu
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243c32535da7 ubuntu:latest "/bin/bash" 18 seconds ago Up 17 seconds
nostalgic_hypatia
$ docker attach nostalgic_hypatia
root@243c32535da7:/#
但是使用attach命令有時候并不方便。當(dāng)多個窗口同時用attach命令連到同一個容器的時候俄占,所有窗口都會同步顯示管怠。當(dāng)某個窗口因命令阻塞時,其他窗口也無法執(zhí)行操作了缸榄。
exec命令
Docker從1.3.0版本起提供了一個更加方便的exec命令渤弛,可以在容器內(nèi)直接執(zhí)行任意命令。該命令的基本格式為
比較重要的參數(shù)有:
- -i甚带,--interactive=true|false:打開標(biāo)準(zhǔn)輸入接受用戶輸入命令她肯,默認(rèn)為
false; - --privileged=true|false:是否給執(zhí)行命令以高權(quán)限鹰贵,默認(rèn)為false晴氨;
- -t,--tty=true|false:分配偽終端碉输,默認(rèn)為false籽前;
- -u,--user="":執(zhí)行命令的用戶名或ID。
例如進(jìn)入到剛創(chuàng)建的容器中枝哄,并啟動一個bash:
$ docker exec -it 243c32535da7 /bin/bash
root@243c32535da7:/#
nsenter工具
在util-linux軟件包版本2.23+中包含nsenter工具肄梨。如果系統(tǒng)中的util-linux包沒有該命令,可以按照下面的方法從源碼安裝:
$ cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util?linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;
$ ./configure --without-ncurses
$ make nsenter && cp nsenter /usr/local/bin
為了使用nsenter連接到容器膘格,還需要找到容器進(jìn)程的PID峭范,可以通過下面的命令獲炔扑伞:
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
通過這個PID瘪贱,就可以連接到這個容器:
$ nsenter --target $PID --mount --uts --ipc --net --pid
下面給出一個完整的例子,通過nsenter命令進(jìn)入容器:
$ docker run -idt ubuntu
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
243c32535da7 ubuntu:latest "/bin/bash" 18 seconds ago Up 17 seconds
nostalgic_hypatia
$ PID=$(docker-pid 243c32535da7)
10981
$ nsenter --target 10981 --mount --uts --ipc --net --pid
root@243c32535da7:/#
ip netns操作容器網(wǎng)絡(luò)
ip netns exec $PID ip link set eth0 up
ip netns exec $PID ip route add default via 172.17.0.1
刪除容器
可以使用docker rm命令來刪除處于終止或退出狀態(tài)的容器辆毡,命令格式為docker rm [-f|--force][-l|--link][-v| --volumes]CONTAINER[CONTAINER...]菜秦。
如果要直接刪除一個運(yùn)行中的容器,可以添加-f參數(shù)舶掖。Docker會先發(fā)送SIGKILL信號給容器球昨,終止其中的應(yīng)用,之后強(qiáng)行刪除眨攘,如下所示:
$ docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world;
sleep 1; done"
2aed76caf8292c7da6d24c3c7f3a81a135af942ed1707a79f85955217d4dd594
$ docker rm 2ae
Error response from daemon: You cannot remove a running container. Stop the
container before attempting removal or use -f
2016/07/03 09:02:24 Error: failed to remove one or more containers
$ docker rm -f 2ae
2ae