容器是鏡像的一個運行實例,鏡像是靜態的只讀文件,而容器帶有運行時需要的可寫文件層。如果認為虛擬機是模擬運行的一整套操作系統(包括內核、應用運行態環境和其他系統環境)和跑在上面的應用,那么Docker容器就是獨立運行的一個(或一組)應用,以及它們必需的運行環境。
一、創建容器
1. 新建容器
使用docker create命令新建一個容器,-t選項讓Docker分配一個偽終端並綁定到容器的標准輸入上,-i則讓容器的標准輸入保持打開。
$ docker create -it ubuntu:latest
使用docker create命令新建的容器處於停止狀態,可以使用docker start命令來啟動它。
2. 啟動容器
使用docker start命令來啟動一個已經創建的容器
$ docker start af
通過docker ps命令查看一個運行中的容器,ps -a 查看所有容器
3. 新建並啟動容器
docker run 等價於先執行docker create命令,再執行docker start命令
$ docker run ubuntu:18.04 /bin/echo 'Hello World'
當利用docker run來創建並啟動容器時,Docker在后台運行的標准操作包括:
1)檢查本地是否存在指定的鏡像,不存在就從公有倉庫下載;
2)利用鏡像創建一個容器,並啟動該容器
3)分配一個文件系統給容器,並在只讀的鏡像層外面掛載一層可讀寫層;
4)從宿主主機配置的網橋接口中橋接一個虛擬接口到容器中;
5)從網橋的地址池配置一個IP地址給容器;
6)執行用戶指定的應用程序;
7)執行完畢后容器被自動終止;
命令執行后出錯,會默認返回錯誤碼,默認情況下,常見錯誤代碼包括:
1) 125:Docker daemon執行出錯,例如指定了不支持的Docker命令參數;
2) 126:所指定命令無法執行,例如權限出錯
3) 127:容器內命令無法找到。
4. 守護態運行
添加-d參數來實現守護態形式運行,容器啟動后會返回一個唯一的id,可以通過docker ps來查看容器信息。
$ docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"
要獲取容器的輸也信息,可以使用docker logs命令(ce5為容器id前綴):
$ docker logs ce5
二、終止容器
可以使用docker stop來終止一個運行中的容器,該命令格式為docker stop [-t|--time[=10]] [CONTAINER...]
首先向容器發送SIGTERM信號,等待一段超過時間(默認為10秒)后,再發送SIGKILL信號來終止容器(ce5為容器id前綴):
$ docker stop ce5
docker kill命令會直接發送SIGKILL信號來強行終止容器
此外,當Docker容器中指定的應用終結時,容器也會自動終止。對於只啟動了一個終端的容器,用戶通過exit命令或ctrl+d來退出終端時,所創建的容器立刻終止,處於stopped狀態。docker restart命令會將一個運行態的容器先終止,然后再重新啟動它。
三、進入容器
在使用-d參數時,容器啟動后會進入后台,用戶無法看到容器中的信息,也無法進行操作。如果需要進入容器進行操作,有多種辦法,包括使用官方的attach或exec命令,以及第三方的nsenter工具等。
1. attach命令
attach命令是Docker自帶的命令,命令格式為:
docker attach [--detach-keys[=[]]] [--no-stdin] [--sig-proxy[=true]] CONTAINER
支持三個主要選項:
1) --detach-keys=[=[]]:指定退出attach模式的快捷鍵序列,默認是CTRL-p CTRL-q;
2) --no-stdin=true|false:是否關閉標准輸入,默認是保持打開;
3) --sig-proxy=true|false:是否代理收到的系統信號給應用進程,默認為true;
當多個窗口同時用attach命令連到同一個容器的時候,所有窗口都會同步顯示。當某個窗口因命令阻塞時,其他窗口也無法執行操作了。
2. exec命令
exec命令可以在窗口內直接執行任意命令。
docker exec [-d|--detach] [--detach-keys[=[]]] [-i|--interactive] [--privileged] [-t|--tty] [-u|--user[=USER]] CONTAINER COMMAND [ARG...]
比較重要的參數有
1) -i,--interactive=true|false:打開標准輸入接受用戶輸入命令,默認為false;
2)--privileged=true|false:是否給執行命令以高權限,默認為false;
3)-t, --tty=true|false:分配偽終端,默認為false;
4)-u, --user="":執行命令的用戶名或ID;
$ docker exec -it 243c32535da7 /bin/bash
3. nsenter工具
在util-linux軟件包版本2.23+中包含nsenter工具。如果系統中的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連接到容器,還需要找到容器進程的PID,可以通過下面的命令獲取:
PID = $(docker inspect --format "{{.State.Pid}}" <container>)
通過這個PID,就可以連接到這個容器:
$ nsenter --target $PID --mount --uts --ipc --net --pid
四、刪除容器
使用docker rm命令為刪除處於終止或退出狀態的容器,命令格式為
docker rm [-f|--force] [-l|--link] [-v|--volumes] CONTAINER [CONTAINER...]
主要支持的選項包括
1) -f, --force=false:是否強行終止並刪除一個運行中的容器
2) -l, --link=false:刪除容器的連接,但保留容器
3) -v, --volumes=false:刪除容器掛載的數據卷。
五、導入和導出容器
1. 導出容器
導出容器是指導出一個已經創建的容器到一個文件,不管此時這個容器是否處於運行狀態,可以使用docker export命令,格式為
docker export [-o|--output[=""]] CONTAINER。其中,可以通過-o選項來指定導出的tar文件名,也可以直接通過重定向來實現
$ docker export -o hello1.tar a4d
$ docker export a4d > hello2.tar
2. 導入容器
導出的文件可以通過docker import命令導入變成鏡像
docker import [-c|--change[=[]]] [-m|-message[=MESAGE]] file|URL - [REPOSITORY[:TAG]]
用戶可以通過-c,--change=[]選項在導和的同時執行對容器進行修改的Dockerfile指令。
即可以使用docker load命令來導入鏡像存儲文件到本地鏡像庫,也可以使用docker import命令來導入一個容器快照到本地鏡像庫
兩者的區別在於容器快照文件將丟棄所有的歷史記錄和元數據信息(即僅保存容器當時的快照狀態),而鏡像存儲文件將保存完整記錄,體積也更大。此外,從容器快照文件導入時可以重新指定標簽等元數據信息。