1. 程式人生 > >Docker學習筆記:映象、容器、資料卷

Docker學習筆記:映象、容器、資料卷

## 核心概念 - 映象:一個只讀的模板,類似虛擬機器的映象。 - 容器:可以理解為映象的一個執行例項。執行時類似於沙箱,多個容器互相獨立。 - 倉庫:存放映象檔案的地方。 ## 映象 ### 命令表格 命令|解釋|選項 -|-|- docker pull NAME[:TAG\|@DIGEST]|拉取映象 docker push NAME[:TAG]|推送映象 docker images [REPOSITORY[:TAG]]|映象列表 docker rmi IMAGE [IMAGE...]|刪除映象,如果有容器正在使用映象,無法刪除。|-f:強制刪除。 docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]|打標籤,類似於多了一引用。source與target的image id是相同的。 docker inspect NAME\|ID [NAME\|ID...]|檢視映象/容器資訊 docker image prune|刪除未使用映象映象。|-a:刪除所有未使用的映象 ### 建立映象 - 基於已有容器建立:docker commit - 基於本地模板匯入:docker import(與export命令一起在容器部分介紹) - 基於Dockerfile建立:docker build(內容較多,後面單獨拿出來) #### docker commit 基於其他映象修改、安裝一些程式後,commit提交生成新的映象。 準備一個ubuntu映象 ``` -> [[email protected]] [~] docker pull ubuntu -> [[email protected]] [~] docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu latest 1d622ef86b13 2 weeks ago 73.9MB -> [[email protected]] [~] docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ``` 執行映象新增一個檔案 ``` -> [[email protected]] [~] docker run -it ubuntu /bin/bash root@af9221c0bb6e:/# touch a.txt root@af9221c0bb6e:/# exit exit ``` 檢視容器列表,檢視修改內容,生成新的映象myubuntu ``` -> [[email protected]] [~] docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af9221c0bb6e ubuntu "/bin/bash" 22 seconds ago Exited (0) 6 seconds ago fervent_wiles -> [[email protected]] [~] docker diff af9221c0bb6e A /a.txt C /root A /root/.bash_history -> [[email protected]] [~] docker commit af9221c0bb6e myubuntu sha256:9a8c0fa00cdadc308be6cf9e846602dd17a058699f2ba9a0bd52ad2a346265f4 -> [[email protected]] [~] docker images REPOSITORY TAG IMAGE ID CREATED SIZE myubuntu latest 9a8c0fa00cda 7 seconds ago 73.9MB ubuntu latest 1d622ef86b13 2 weeks ago 73.9MB ``` #### docker save/load docker save IMAGE [IMAGE...] save的存出目標是映象。通常用法 docker save -o myimport2.tar myimport 或者 docker save myimport > myimport2.tar ``` -> [[email protected]] [~] docker save -o myimport2.tar myimport -> [[email protected]] [~] ls import.txt myimport.tar myimport2.tar ``` 刪除myimport映象後載入 ``` -> [[email protected]] [~] docker load -i myimport2.tar 90441ead6bbb: Loading layer [==================================================>] 1.536kB/1.536kB Loaded image: myimport:latest ``` 載入後的映象與刪除之前的image id相同,這也是與import的區別所在。 ## 容器 ### 命令表格 命令|解釋|備註 -|-|- docker create IMAGE [COMMAND] [ARG...]|從映象建立一個容器,剛建立完的容器狀態是Created|引數極多,help。 docker start CONTAINER [CONTAINER...]|開始一個或多個容器|-i:讓容器的標準輸入保持開啟 docker container prune|移除所有已停止的容器,包括Created和Exited狀態的。 docker stop CONTAINER [CONTAINER...]|終止容器執行|-t:預設為10,表示等待最長多長時間後會被kill docker kill CONTAINER [CONTAINER...]|向容器傳送訊號|-s:預設是KILL docker attach CONTAINER|多個視窗同時attach到一個容器時,所有視窗會同步顯示。當某個視窗阻塞時,其他視窗也無法操作。 docker exec CONTAINER COMMAND [ARG...] |每個視窗都是獨立的|通常用法:docker exec -it c1 /bin/bash docker rm CONTAINER [CONTAINER...]|只能刪除終止和退出的容器,-f 強制刪除執行中的容器。Docker會先發送SIGKILL訊號給容器,終止其中應用,然後刪除容器。|-f:強制刪除執行中的容器 docker inspect NAME\|ID [NAME\|ID...]|此指令可以檢視映象資訊,也可以檢視容器資訊 docker cp CONTAINER:SRC_PATH DEST_PATH\|-
docker cp SRC_PATH\|- CONTAINER:DEST_PATH|在宿主機與容器之間拷貝檔案|docker cp c1:/a.txt ./
從c1容器拷貝/a.txt到宿主機當前目錄 docker port CONTAINER [PRIVATE_PORT[/PROTO]]|檢視容器埠對映情況 ### docker run 此命令根據映象建立一個容器,並執行。如果映象在本地不存在,會嘗試從倉庫拉取。 選項|解釋 -|- -t|讓Docker分配一個偽終端並繫結到容器的標準輸入上 -i|讓容器的標準輸入保持開啟 -d|以守護程序方式執行 --rm|再起結束後自動刪除 ``` -> [[email protected]] [~] docker run ubuntu echo 'Hello World' Hello World ->
[[email protected]] [~] docker run -it ubuntu /bin/bash root@8324e8546f47:/# ``` ### docker wait docker wait CONTAINER [CONTAINER...] 阻塞直到一個或多個容器停止執行,然後列印他們的exit codes 開啟兩個視窗分別執行一個容器,然後開啟第三個視窗執行 ``` // 視窗1執行容器c1 docker run -it --name c1 ubuntu /bin/bash // 視窗2執行容器c2 docker run -it --name c2 ubuntu /bin/bash // 視窗3執行docker wait docker wait c1 c2 // 視窗1執行 exit 1,視窗3無反應;再在視窗2執行 exit 2,視窗3輸出兩行分別是1、2。 ``` ### docker logs 獲取一個容器的日誌 -f:持續輸出;-t:輸出時間戳;--details:額外的詳細資訊 ``` // 視窗1 ->
[[email protected]] [~] docker run -it --name c1 ubuntu /bin/bash root@046d5a62374e:/# pwd / root@046d5a62374e:/# touch a.txt root@046d5a62374e:/# exit 123 exit // 視窗2 -> [[email protected]] [~] docker logs -tf c1 2020-05-13T16:55:10.398202931Z root@046d5a62374e:/# pwd 2020-05-13T16:55:10.398297213Z / 2020-05-13T16:55:38.712593120Z root@046d5a62374e:/# touch a.txt 2020-05-13T16:55:55.908622227Z root@046d5a62374e:/# exit 123 2020-05-13T16:55:55.909431626Z exit ``` ### docker pause/unpause 暫停容器:docker pause CONTAINER [CONTAINER...] 取消暫停:docker unpause CONTAINER [CONTAINER...] ``` // 視窗1 -> [[email protected]] [~] docker run -it --rm --name c1 ubuntu /bin/bash root@505f1b39efa0:/# // 視窗2 -> [[email protected]] [~] docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505f1b39efa0 ubuntu "/bin/bash" 11 seconds ago Up 11 seconds c1 -> [[email protected]] [~] docker pause c1 c1 -> [[email protected]] [~] docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505f1b39efa0 ubuntu "/bin/bash" 26 seconds ago Up 26 seconds (Paused) c1 -> [[email protected]] [~] docker unpause c1 c1 -> [[email protected]] [~] docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505f1b39efa0 ubuntu "/bin/bash" 39 seconds ago Up 39 seconds c1 ``` ### docker import/export import根據一個tar檔案建立一個映象,但這個tar檔案並不一定要是export匯出的,也可以自己生成。 #### docker import docker import file|URL|- [REPOSITORY[:TAG]] **對於同一個tar檔案,多次使用docker import生成的映象,其image id是不一樣的。** ``` -> [[email protected]] [~] touch import.txt -> [[email protected]] [~] tar -cvf myimport.tar import.txt a import.txt -> [[email protected]] [~] docker import myimport.tar myimport sha256:3572df2ff16b9508c780770c28eef250589d5c0bf4d77e1dfeb84d406e5b34d2 -> [[email protected]] [~] docker images REPOSITORY TAG IMAGE ID CREATED SIZE myimport latest 3572df2ff16b 5 seconds ago 0B ubuntu latest 1d622ef86b13 2 weeks ago 73.9MB ``` #### docker export docker export CONTAINER, export的匯出目標是容器,而不是映象。通常使用:docker export -o c11.tar c1 或者 docker export c1 > c11.tar ``` -> [[email protected]] [~] docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 68e152e8e6ee ubuntu "/bin/bash" 31 minutes ago Up 31 minutes c1 -> [[email protected]] [~] docker export -o c11.tar c1 -> [[email protected]] [~] docker export c1 > c12.tar -> [[email protected]] [~] ls c11.tar c12.tar ``` #### export與save的區別 操作目標不同:export是容器,save是映象。 匯出檔案內容不同:export匯出的是當時的檔案快照,save匯出的是帶有歷史記錄和元資料的完整映象。 #### import與load的區別 import匯入多次同一個tar檔案會得到多個image id不同的映象,而load只會得到一個。 ### docker top docker top CONTAINER [ps OPTIONS] 檢視執行中的容器內的程序資訊 ``` -> [[email protected]] [~] docker top c1 PID USER TIME COMMAND 2504 root 0:00 /bin/bash ``` ### docker stats docker stats [CONTAINER...] 檢視統計資訊,包括CPU、記憶體、儲存、網路等 ``` CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 0e5fa15b44a9 c1 0.00% 884KiB / 1.945GiB 0.04% 1.05kB / 0B 0B / 0B 1 ``` ### docker diff docker diff CONTAINER 檢視容器內檔案系統的變更 - A(Add):新增; - C(Change):更改; - D(Delete):刪除 ``` -> [[email protected]] [~] docker diff c1 A /a.txt C /.dockerenv D /tmp ``` ### docker update docker update CONTAINER [CONTAINER...] 更改容器執行時的一些配置,主要是資源限制份額,比如cpu、記憶體。具體引數help。 ## 資料管理 本章討論如何對容器內的資料持久化;如何在容器間共享資料。 ### 資料卷 資料卷是一個可供容器使用的特殊目錄,它將宿主機目錄直接對映到容器。類似Linux mount。它有以下特性: - 資料卷可以在容器間共享和重用 - 對資料卷的修改立刻生效 - 資料卷一直存在,直到沒有容器使用,可以安全解除安裝 #### 建立資料卷 docker volume create [VOLUME] 其他docker volume子命令有:ls、rm、prune、inspect。 ``` // 建立名為test的資料卷 -> [[email protected]] [~] docker volume create test test // 不指定名稱會分配一個 -> [[email protected]] [~] docker volume create b03ca993f283336bbc227e2a58e3683e175316222321074ec4b24f556fe3bdd2 // 檢視結果 -> [[email protected]] [~] docker volume ls DRIVER VOLUME NAME local b03ca993f283336bbc227e2a58e3683e175316222321074ec4b24f556fe3bdd2 local test ``` #### 繫結資料卷 使用docker run時,可以使用--mount選項使用資料卷,其支援三種類型: - volume:普通資料卷,對映到宿主機的/var/lib/docker/volumes - bind:繫結資料卷,對映到宿主機指定路徑下 - tmpfs:臨時資料卷,只存在於記憶體中 ##### type=bind 將宿主機hostdir對映到vtest容器的/root/cntrdir。下面兩條等價。 ``` docker run --rm --name vtest --mount type=bind,src=`pwd`/hostdir,dst=/root/cntrdir -it ubuntu docker run --rm --name vtest -v `pwd`/hostdir:/root/cntrdir -it ubuntu ``` docker掛載資料卷的預設許可權是讀寫(rw)。可以指定只讀(ro),容器內就無法對資料捲進行修改了,但宿主機不受影響。 ``` docker run --rm --name vtest -v `pwd`/hostdir:/root/cntrdir:ro -it ubuntu ``` ##### type=volume **如果src指定的卷不存在,則自動建立。如果不指定src,則建立一個名字隨機的卷,且其生命週期與容器相同,容器被銷燬時,卷也被銷燬。** 將普通資料卷v1掛載到容器vtest的/root/cntrv1 ``` docker run --rm --name vtest --mount type=volume,src=v1,dst=/root/cntrv1 -it ubuntu docker run --rm --name vtest -v v1:/root/cntrv1 -it ubuntu ``` ### mac上檢視資料卷內容 docker在Mac上是執行在LinuxKit VM中的,需要用screen命令進入檢視。 ``` // 先建立一個數據卷 -> [[email protected]] [~] docker volume create v1 // screen -> [[email protected]] [~] screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty // 進入虛擬機器 docker-desktop:~# cd /var/lib/docker/volumes/ docker-desktop:/var/lib/docker/volumes# ls metadata.db v1 ``` 看到資料卷目錄找到了! ### 資料卷容器 #### 建立及使用 資料卷容器的目的是專門給其他容器提供資料卷掛載。 **--volumes-from並不要求引數指定的資料卷容器處於執行狀態。** ``` // 建立兩個資料卷容器 db1 db2 db3,其中db1與db3對映在容器內的內容相同 -> [[email protected]] [~] docker run --name db1 -v /root/db1 -itd ubuntu -> [[email protected]] [~] docker run --name db2 -v /root/db2 -itd ubuntu -> [[email protected]] [~] docker run --name db3 -v /root/db1 -itd ubuntu // 使用--volumes-from 來掛載容器中的資料卷,可以多次使用此選項 -> [[email protected]] [~] docker run --name cntr1 --volumes-from db1 --volumes-from db2 -it ubuntu root@63c9ba535eec:/# ls /root/ db1 db2 // 可以從其他已掛載了資料卷容器的容器掛載資料卷。有點類似於繼承。 -> [[email protected]] [~] docker run --name cntr2 --volumes-from cntr1 -it ubuntu root@640c49fee4ad:/# ls /root/ db1 db2 // 如果掛載不同的資料卷容器,但是對映路徑相同,則實際上是使用後面的資料卷容器。 -> [[email protected]] [~] docker run --name cntr3 --volumes-from db1 --volumes-from db3 -it ubuntu root@7aba448230b8:/# ls /root/ db1 ``` 如果刪除了掛載的容器(db1,db2,cntr1),資料卷不會被自動刪除。如果要刪除,需要在刪除最後一個掛在這它的容器是執行 docker rm -v。 #### 備份 備份資料卷容器db1內的資料卷內容到本地當前目錄。 ``` docker run --volumes-from db1 -v `pwd`:/bak --name cntrbak ubuntu tar -cvf /bak/db1.tar /root/db1 ``` 使用--volumes-from db1 掛載一個容器資料卷;使用-v \`pwd\`:/bak對映宿主機當前目錄到容器cntrbak的 /bak 目錄;然後tar打包db1到 /bak/db1