【1】Docker容器數據卷
先來看看Docker的理念:
- 將運用與運行的環境打包形成容器運行 ,運行可以伴隨着容器,但是我們對數據的要求希望是持久化的
- 容器之間希望有可能共享數據
Docker容器產生的數據,如果不通過docker commit生成新的鏡像,使得數據做爲鏡像的一部分保存下來,那麼當容器刪除後,數據自然也就沒有了。
爲了能保存數據在docker中我們使用數據卷,主要爲了容器的持久化與容器間繼承+共享數據(主機和容器數據共享)。
卷就是目錄或文件,存在於一個或多個容器中,由docker掛載到容器,但不屬於聯合文件系統,因此能夠繞過Union File System提供一些用於持續存儲或共享數據的特性。
卷的設計目的就是數據的持久化,完全獨立於容器的生存週期,因此Docker不會在容器刪除時刪除其掛載的數據卷。
特點:
1:數據卷可在容器之間共享或重用數據
2:卷中的更改可以直接生效
3:數據卷中的更改不會包含在鏡像的更新中
4:數據卷的生命週期一直持續到沒有容器使用它爲止
【2】命令添加數據卷
在容器內添加數據卷主要有兩種方式:直接V命令添加和DockerFile添加。
① 命令添加數據卷實例
命令如下:
docker run -it -v /宿主機絕對路徑目錄:/容器內目錄 鏡像名
#如docker run -it -v /宿主機目錄:/容器內目錄 centos /bin/bash
docker run -it -v /myDataVolume:/dataVolumeContainer centos /bin/bash
② 查看數據卷是否掛載成功
docker inspect 容器ID
③ 容器和宿主機之間數據共享
如下所示在容器內/dataVolumeContainer目錄創建文件:
容器內操作如下:
[root@a35e55bafcab dataVolumeContainer]# echo "i'm a container " > test.txt
[root@a35e55bafcab dataVolumeContainer]# ls
test.txt
[root@a35e55bafcab dataVolumeContainer]# cat test.txt
i'm a container
[root@a35e55bafcab dataVolumeContainer]#
宿主機操作如下:
[root@localhost ~]# cd /myDataVolume/
[root@localhost myDataVolume]# ll
total 4
-rw-r--r--. 1 root root 17 Feb 12 11:46 test.txt
[root@localhost myDataVolume]# cat test.txt
i'm a container
[root@localhost myDataVolume]# echo "host update" >> test.txt
[root@localhost myDataVolume]# cat test.txt
i'm a container
host update
④ 容器停止退出後,主機修改後數據同步
驗證步驟:
- 容器先停止退出
- 主機修改test.txt
- 容器重啓進入
- 查看主機修改的test.txt
主機操作:
[root@localhost myDataVolume]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost myDataVolume]# echo "host update again" >> test.txt
[root@localhost myDataVolume]# cat test.txt
i'm a container
host update
host update again
容器操作:
[root@localhost /]# docker start a35e55bafcab
a35e55bafcab
[root@localhost /]# docker exec -it a35e55bafcab /bin/bash
[root@a35e55bafcab /]# cd /dataVolumeContainer/
[root@a35e55bafcab dataVolumeContainer]# cat test.txt
i'm a container
host update
host update again //這裏標明容器看到了主機修改的內容
⑤ 設置目錄權限
##ro表示read only 即容器內的數據只允許讀
docker run -it -v /宿主機絕對路徑目錄:/容器內目錄:ro 鏡像名
【3】DockerFile添加數據卷
這裏以一個實例來說明。
① 根目錄下新建mydocker文件夾並進入
mkdir /mydocker
cd /mydocker
② 在Dockerfile中使用VOLUME指令來給鏡像添加一個或多個數據卷
格式如下:
VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]
出於可移植和分享的考慮,用-v
主機目錄:容器目錄
這種方法不能夠直接在Dockerfile中實現。由於宿主機目錄是依賴於特定宿主機的,並不能夠保證在所有的宿主機上都存在這樣的特定目錄。
構建File:
[root@localhost /]# cd /mydocker/
[root@localhost mydocker]# ll
total 0
[root@localhost mydocker]# vim DockerFile
文件內容如下:
# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,--------success1"
CMD /bin/bash
③ build後生成鏡像
命令如下:
docker build -f DockFile路徑 -t 鏡像名 .[這裏有個.不可少,標明在當前目錄下面]
實例如下(注意當前在/mydocker路徑下,命令最後面有個.
):
docker build -f /mydocker/DockerFile -t jane/centos .
使用docker images
檢測如下:
④ 創建新的容器並運行
docker run -it b3a32e0a2930 /bin/bash
⑤ 查看容器目錄對應的主機目錄
首先檢測運行的容器:
docker ps
使用命令查看容器內部情況:
docker inspect 9ae9239b6cf7
"Volumes": {
"/dataVolumeContainer1": "/var/lib/docker/volumes/8ebcee3e258a367b2869c326bc7c032b544e061830490ce866ef6a72299a6999/_data",
"/dataVolumeContainer2": "/var/lib/docker/volumes/396815bd66ac143ed2bff3f2ad8ac6439116d5fbbae53327c52b883eb6ec6d6a/_data"
},
"VolumesRW": {
"/dataVolumeContainer1": true,
"/dataVolumeContainer2": true
}
使用命令在容器內創建文件,然後在宿主機對應目錄查看:
【4】數據卷容器
命名的容器掛載數據卷,其它容器通過掛載這個(父容器)實現數據共享,掛載數據卷的容器,稱之爲數據卷容器。
① 查看此時鏡像與容器概況
② 先啓動一個父容器dc01
docker run -it --name dc01 jane/centos
檢測如下:
在dataVolumeContainer2/路徑下創建文件dc01.txt:
[root@41ad254d8e05 /]# cd dataVolumeContainer2/
[root@41ad254d8e05 dataVolumeContainer2]# touch dc01.txt
[root@41ad254d8e05 dataVolumeContainer2]# ls
dc01.txt
③ 創建容器dc02、dc03並繼承自dc01
docker run -it --name dc02 --volumes-from dc01 jane/centos
然後同樣在dataVolumeContainer2路徑下創建文件:
[root@a5f21105d3e7 /]# cd dataVolumeContainer2/
[root@a5f21105d3e7 dataVolumeContainer2]# ls
dc01.txt
[root@a5f21105d3e7 dataVolumeContainer2]# touch dc02.txt
[root@a5f21105d3e7 dataVolumeContainer2]# ls
dc01.txt dc02.txt
dc03操作如下:
[root@localhost myDataVolume]# docker run -it --name dc03 --volumes-from dc01 jane/centos
[root@132abc66899c /]# cd dataVolumeContainer2/
[root@132abc66899c dataVolumeContainer2]# ls
dc01.txt dc02.txt
[root@132abc66899c dataVolumeContainer2]# touch dc03.txt
[root@132abc66899c dataVolumeContainer2]# ls
dc01.txt dc02.txt dc03.txt
④ 返回查看容器dc01
檢測此時容器運行概況:
檢測容器dc01路徑dataVolumeContainer2概況:
⑤ 刪除dc01然後分別在dc02/dc03下查看dataVolumeContainer2路徑
#進入dc02
docker exec -it a5f21105d3e7 /bin/bash
#進入dc03
docker exec -it 132abc66899c /bin/bash
⑥ dc02新增數據然後刪除dc02再進入dc03查看
dc02下操作:
[root@a5f21105d3e7 /]# cd dataVolumeContainer2
[root@a5f21105d3e7 dataVolumeContainer2]# ls
dc01.txt dc02.txt dc03.txt
[root@a5f21105d3e7 dataVolumeContainer2]# touch dc02_update.txt
[root@a5f21105d3e7 dataVolumeContainer2]# ls
dc01.txt dc02.txt dc02_update.txt dc03.txt
[root@a5f21105d3e7 dataVolumeContainer2]# [root@localhost ~]#
[root@localhost ~]# docker rm -f a5f21105d3e7
a5f21105d3e7
dc03下操作:
[root@localhost ~]# docker exec -it 132abc66899c /bin/bash
[root@132abc66899c /]# cd dataVolumeContainer2
[root@132abc66899c dataVolumeContainer2]# ls
dc01.txt dc02.txt dc02_update.txt dc03.txt
可以發現儘管dc02與dc03無繼承關係,但是已經建立了共享關係,故而dc02刪除後,dc03仍然可以拿到dc02創建的文件。
結論:容器之間配置信息的傳遞,數據卷的生命週期一直持續到沒有容器使用它爲止。
問題:
- 如果兩個獨立的容器映射了同一個主機目錄會怎樣?
- 如果dc01 dc02 dc03三個沒有關係還會出現上面的實驗情況嗎?