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鏡像

-> [feifei@ffmac.local] [~] docker pull ubuntu
-> [feifei@ffmac.local] [~] docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              1d622ef86b13        2 weeks ago         73.9MB
-> [feifei@ffmac.local] [~] docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

運行鏡像添加一個文件

-> [feifei@ffmac.local] [~] docker run -it ubuntu /bin/bash
root@af9221c0bb6e:/# touch a.txt
root@af9221c0bb6e:/# exit
exit

查看容器列表,查看修改內容,生成新的鏡像myubuntu

-> [feifei@ffmac.local] [~] 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
-> [feifei@ffmac.local] [~] docker diff af9221c0bb6e
A /a.txt
C /root
A /root/.bash_history
-> [feifei@ffmac.local] [~] docker commit af9221c0bb6e myubuntu
sha256:9a8c0fa00cdadc308be6cf9e846602dd17a058699f2ba9a0bd52ad2a346265f4
-> [feifei@ffmac.local] [~] 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

-> [feifei@ffmac.local] [~] docker save -o myimport2.tar myimport
-> [feifei@ffmac.local] [~] ls
import.txt    myimport.tar  myimport2.tar

刪除myimport鏡像后載入

-> [feifei@ffmac.local] [~] 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

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
此命令根據鏡像創建一個容器,並運行。如果鏡像在本地不存在,會嘗試從倉庫拉取。

選項 解釋
-t 讓Docker分配一個偽終端並綁定到容器的標准輸入上
-i 讓容器的標准輸入保持打開
-d 以守護進程方式運行
--rm 再起結束后自動刪除
-> [feifei@ffmac.local] [~] docker run ubuntu echo 'Hello World'
Hello World
-> [feifei@ffmac.local] [~] 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
-> [feifei@ffmac.local] [~] docker run -it --name c1 ubuntu /bin/bash
root@046d5a62374e:/# pwd
/
root@046d5a62374e:/# touch a.txt
root@046d5a62374e:/# exit 123
exit

// 窗口2
-> [feifei@ffmac.local] [~] 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
-> [feifei@ffmac.local] [~] docker run -it --rm --name c1 ubuntu /bin/bash
root@505f1b39efa0:/#

// 窗口2
-> [feifei@ffmac.local] [~] docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
505f1b39efa0        ubuntu              "/bin/bash"         11 seconds ago      Up 11 seconds                           c1
-> [feifei@ffmac.local] [~] docker pause c1
c1
-> [feifei@ffmac.local] [~] docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
505f1b39efa0        ubuntu              "/bin/bash"         26 seconds ago      Up 26 seconds (Paused)                       c1
-> [feifei@ffmac.local] [~] docker unpause c1
c1
-> [feifei@ffmac.local] [~] 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是不一樣的。

-> [feifei@ffmac.local] [~] touch import.txt
-> [feifei@ffmac.local] [~] tar -cvf myimport.tar import.txt
a import.txt
-> [feifei@ffmac.local] [~] docker import myimport.tar myimport
sha256:3572df2ff16b9508c780770c28eef250589d5c0bf4d77e1dfeb84d406e5b34d2
-> [feifei@ffmac.local] [~] 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

-> [feifei@ffmac.local] [~] docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
68e152e8e6ee        ubuntu              "/bin/bash"         31 minutes ago      Up 31 minutes                           c1
-> [feifei@ffmac.local] [~] docker export -o c11.tar c1
-> [feifei@ffmac.local] [~] docker export c1 > c12.tar
-> [feifei@ffmac.local] [~] 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]
查看運行中的容器內的進程信息

-> [feifei@ffmac.local] [~] 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):刪除
-> [feifei@ffmac.local] [~] 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的數據卷
-> [feifei@ffmac.local] [~] docker volume create test
test
// 不指定名稱會分配一個
-> [feifei@ffmac.local] [~] docker volume create
b03ca993f283336bbc227e2a58e3683e175316222321074ec4b24f556fe3bdd2
// 查看結果
-> [feifei@ffmac.local] [~] 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命令進入查看。

// 先創建一個數據卷
-> [feifei@ffmac.local] [~] docker volume create v1

// screen
-> [feifei@ffmac.local] [~] 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映射在容器內的內容相同

-> [feifei@ffmac.local] [~] docker run --name db1 -v /root/db1 -itd ubuntu
-> [feifei@ffmac.local] [~] docker run --name db2 -v /root/db2 -itd ubuntu
-> [feifei@ffmac.local] [~] docker run --name db3 -v /root/db1 -itd ubuntu

使用--volumes-from 來掛載容器中的數據卷,可以多次使用此選項

-> [feifei@ffmac.local] [~] docker run --name cntr1 --volumes-from db1 --volumes-from db2 -it ubuntu
root@63c9ba535eec:/# ls /root/
db1  db2

可以從其他已掛載了數據卷容器的容器掛載數據卷。有點類似於繼承。

-> [feifei@ffmac.local] [~] docker run --name cntr2 --volumes-from cntr1 -it ubuntu
root@640c49fee4ad:/# ls /root/
db1  db2

如果掛載不同的數據卷容器,但是映射路徑相同,則實際上是使用后面的數據卷容器。

-> [feifei@ffmac.local] [~] 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.tar。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM