1. 程式人生 > >Docker系列:04.數據共享與持久化

Docker系列:04.數據共享與持久化

生產 實例 system 管理 oot 操作 信息 server1 tom

04.數據共享與持久化

Docker的鏡像是分層設計的,底層是只讀的,通過鏡像其的容器添加了一層可讀寫的文件系統,用戶寫入的數據都保存在這一層當中,如果要將寫入的數據永久生效,需要將其提交為一個鏡像然後通過這個鏡像在啟動實例,然後就會給這個啟動的實例添加一層可讀寫的文件系統,以此類推,目前docker將數據存儲分為兩種方式,數據卷和數據容器卷,具體如下:

04.1、數據卷

數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:

  • 數據卷可以在容器之間共享和重用
  • 對數據卷的修改會立馬生效
  • 對數據卷的更新,不會影響鏡像
  • 數據卷默認會一直存在,即使容器被刪除

註意:數據卷 的使用,類似於 Linux 下對目錄或文件進行 mount,鏡像中的被指定為掛載點的目錄中的文件會隱藏掉,能顯示看的是掛載的 數據卷。

選擇-v還是-–mount參數

Docker 新用戶應該選擇 --mount 參數,經驗豐富的 Docker 使用者對 -v 或者 --volume 已經很熟悉了,但是推薦使用 --mount 參數。

04.1.1、啟動容器加載數據卷

  • 數據卷類似一個被掛載的目錄。啟動後的docker容器可以在這個目錄進行讀寫操作,類似於遠程掛載一個NFS共享
[root@docker-server1 ~]# docker run -d --name nginx-test1 -v /data nginx
[root@docker-server1 ~]# ./docker.sh nginx-test1
root@e67af30200e3:/# df -TH 
Filesystem                                                                                          Type   Size  Used Avail Use% Mounted on
/dev/mapper/docker-253:0-201458571-6f26313298b2d5adb230575fbaab10accb18eef2f03b12694ac6df45770c1508 xfs     11G  239M   11G   3% /
tmpfs                                                                                               tmpfs  2.0G     0  2.0G   0% /dev
tmpfs                                                                                               tmpfs  2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/mapper/centos-root                                                                             xfs     51G  4.7G   47G  10% /data #被掛載的磁盤
shm                    
  • 上面的data目錄還有47G的空間,那個這個數據目錄在物理機的位置在哪裏?
[root@docker-server1 ~]# docker inspect -f {{.Mounts}}  nginx-test1 #查看掛載信息
[{50c86b4bb97c2751f781866c5298b1455e804f7af340335dc637c67f76a1d32d /var/lib/docker/volumes/50c86b4bb97c2751f781866c5298b1455e804f7af340335dc637c67f76a1d32d/_data /data local  true }]
#或以下方式:
[root@docker-server1 ~]# docker inspect nginx-test1  #查看容器的所有信息
[root@docker-server1 ~]# docker inspect nginx-test1 |grep Source|awk -F ‘[:,]‘ ‘{print $2}‘ #過濾出掛載點
 "/var/lib/docker/volumes/50c86b4bb97c2751f781866c5298b1455e804f7af340335dc637c67f76a1d32d/_data"
  • 在物理機創建目錄驗證容器當中是否可以訪問並寫入數據
[root@docker-server1 _data]# pwd #在容器的目錄實際位置即物理機的數據目錄當中
/var/lib/docker/volumes/50c86b4bb97c2751f781866c5298b1455e804f7af340335dc637c67f76a1d32d/_data
[root@docker-server1 _data]# mkdir testdir
#在容器當中驗證:
root@e67af30200e3:/# ls /data/ 
testdir #目錄已經存在
root@e67af30200e3:/# echo "xxoo" >  /data/testdir/testfile #生成一個文件
root@e67af30200e3:/# ls /data/testdir/ #驗證文件存在
testfile
#在物理機中驗證文件是否存在
[root@docker-server1 _data]# cat testdir/testfile 
xxoo
  • 指定源目錄,推薦使用此方式,物理機可以將共享存儲掛載到本地,然後將本地掛載的目錄分配給容器使用,這樣容器掛掉之後也不影響數據的持久保存
[root@docker-server1 ~]# docker run -d --name  nginx-test2 -v 源目錄:目標  鏡像名
[root@docker-server1 ~]# docker run -d --name  nginx-test2 -v /data/testdir2/:/data nginx
ba02d63baff6637a15a6763e7c22a00f2ed56ab9c5438b352c4fbc9f691c1b13
  • 容器中驗證:
#進入到容器並創建目錄生成文件
[root@docker-server1 ~]# ./docker.sh  nginx-test2
root@ba02d63baff6:/# mkdir /data/testdir
root@ba02d63baff6:/# echo "ooxx" >  /data/testdir/testfile
#在物理機進行驗證
[root@docker-server1 ~]# ls /data/testdir2/testdir/
testfile
[root@docker-server1 ~]# cat /data/testdir2/testdir/testfile 
ooxx #文件已經存在

04.1.2、對掛載的目錄設置權限

[root@docker-server1 ~]# docker run -d --name  nginx-test2 -v /data/testdir2/:/data:rw  nginx #讀寫,默認就是讀寫掛載
[root@docker-server1 ~]# docker run -d --name  nginx-test3 -v /data/testdir2/:/data:ro  nginx #只讀
[root@docker-server1 ~]# ./docker.sh  nginx-test3
root@70909a57c1f8:/# mkdir  /data/testdir1    #進入到容器發現對該目錄沒有權限寫入     
mkdir: cannot create directory ‘/data/testdir1‘: Read-only file system

04.1.3、單獨掛載文件

單獨掛載一個文件,比如是一個tomcat或nginx的配置文件要求所有容器都使用同一個配置文件的場景

[root@docker-server1 ~]# docker run -d --name  nginx-test4  -v /usr/local/mysql/my.cnf:/etc/my.cnf:rw   nginx #讀寫的方式掛載一個文件
[root@docker-server1 ~]# docker run -d --name  nginx-test4  -v /usr/local/mysql/my.cnf:/etc/my.cnf:ro   nginx #只讀的方式掛載一個文件
0b0d92f81165704a72d641670f216c3fffa81a5a530229380d17c04d2a35ff35
[root@docker-server1 ~]# ./docker.sh  nginx-test4
root@0b0d92f81165:/# echo "xx" >> /etc/my.cnf  #測試是否無法寫入
-bash: /etc/my.cnf: Read-only file system

04.1.4、管理數據卷

創建一個數據卷

[zhanghe@MacBook-Pro registry ]$ docker volume create my-data
my-data

查看所有的 數據卷

[zhanghe@MacBook-Pro registry ]$ docker volume ls
DRIVER              VOLUME NAME
local               my-data

刪除數據卷

[zhanghe@MacBook-Pro registry ]$ docker volume rm my-data
my-data

數據卷 是被設計用來持久化數據的,它的生命周期獨立於容器,Docker 不會在容器被刪除後自動刪除 數據卷,並且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的 數據卷。如果需要在刪除容器的同時移除數據卷。可以在刪除容器的時候使用 docker rm -v 這個命令。

無主的數據卷可能會占據很多空間,要清理請使用以下命令

[zhanghe@MacBook-Pro registry ]$ docker volume prune

使用 --mount 標記可以指定掛載一個本地主機的目錄到容器中去。

[zhanghe@MacBook-Pro registry ]$ docker run -d -P     --name web     # -v /src/webapp:/opt/webapp     --mount type=bind,source=/src/webapp,target=/opt/webapp     training/webapp     python app.py

上面的命令加載主機的 /src/webapp 目錄到容器的 /opt/webapp目錄。這個功能在進行測試的時候十分方便,比如用戶可以放置一些程序到本地目錄中,來查看容器是否正常工作。本地目錄的路徑必須是絕對路徑,以前使用 -v 參數時如果本地目錄不存在 Docker 會自動為你創建一個文件夾,現在使用 --mount 參數時如果本地目錄不存在,Docker 會報錯。

04.2、數據卷容器

04.2.1、容器數據共享

最大的功能是可以讓數據在多個docker容器之間共享,即可以讓A容器訪問B容器的內容,而B也可以訪問A容器的內容

  • 啟動一個容器,並啟動另外一個容器掛載上一個容器的目錄
#先啟動一個容器,掛載物理機的一個目錄
[root@docker-server1 ~]# docker run -d --name  nginx-test1  -v /data/testdir2/:/data:rw  nginx
a108bd4a0fc09a3322e0cca07bbd4d0aa5d2249d399e860e2c7eaf0d63b8dd4e
#在啟動容器的時候可以使用--volumes-from參數訪問其他容器掛載的目錄
[root@docker-server1 ~]# docker run -d --name nginx-test3 --volumes-from nginx-test1 nginx
e506edcdfd71f64bd1ad67ce9be734184e54e408e758010a4f366d0b9de10536
  • 在容器一個創建目錄並在第二個容器驗證

啟動容器

[root@docker-server1 ~]# ./docker.sh  nginx-test1
root@a108bd4a0fc0:/# mkdir /data/testdir/test-volum
[root@docker-server1 ~]# ./docker.sh nginx-test3
root@e506edcdfd71:/# ls /data/testdir/           
test-volume  testfile #已經可以看到test-volume目錄了

關閉第一個容器,然後在第二個容器驗證數據是否可以訪問之前的目錄

[root@docker-server1 ~]# docker stop nginx-test1 #關閉容器1
nginx-test1
[root@docker-server1 ~]# ./docker.sh nginx-test3
root@e506edcdfd71:/# mkdir /data/testdir/test-volume1
#可以發現,即使將之前的容器關閉也不影響其他的容器訪問其目錄數據,因為容器是通過掛載訪問數據的 

數據卷容器可以作為共享的方式為其他容器提供文件共享,類似於NFS共享,可以在生產中啟動一個實例掛載本地的目錄,然後其他的容器分別掛載此容器的目錄,即可保證各容器之間的數據一致性。

04.2.2、批量管理容器

  • 批量關閉容器與刪除,威力巨大、效果顯著,慎用
[root@docker-server1 ~]# docker kill $(docker ps -a -q)
590d65e68d35
9a104c2f39ac
c6decbad5d08
[root@docker-server1 ~]# docker rm -f  $(docker ps -a -q)
9d811ed2c371
0b0d92f81165
70909a57c1f8

Docker系列:04.數據共享與持久化