1. 程式人生 > >Docker系列(五):Docker存儲管理

Docker系列(五):Docker存儲管理

options 不存在 0.0.0.0 物理機 eas 得到 重復 second backups

因Docker采用分層文件系統,對容器做的修改都發生在最上層(可寫層),這樣使得容器可以重復利用。然而,在容器停止時文件系統的最上層(可寫層)就消失了,這樣容器產生的數據也就無法保存。所以為了持久化存儲容器的數據,通常會掛載容器外的存儲來保存容器產生的數據,其主要的形式有如下兩種方式:
1)數據卷
2)數據(卷)容器

1、數據卷
概念:數據卷是經過特殊設計的目錄,可以繞過聯合文件系統(UFS),為一個或多個容器提供訪問。

設計目的:數據卷設計的目的,在於數據的永久化,它完全獨立於容器的生命周期,因此,Docker不會在容器刪除時刪除其掛載的數據卷,也不會存在類似的垃圾收集機制,對容器引用的數據卷進行處理。

特點:

  • 數據卷在容器啟動時初始化,如果容器使用的鏡像在掛載點包含了數據,這些數據會拷貝到新初始化的數據卷。
  • 數據卷可以在容器之間共享和重用
  • 可以對數據卷裏的內容直接進行修改
  • 數據卷的變化不會影響鏡像的更新
  • 卷會一直存在,即使掛載數據卷的容器已經被刪除

數據卷的管理:
docker volume COMMAND
create:創建一個數據卷
inspect:顯示一個或多個數據卷的詳細信息
ls:列出數據卷
prune:移除所有未使用的數據卷
rm:刪除一個或多個數據卷

# 創建volume卷
[root@centos7 ~]# docker volume create myvolume01
myvolume01
[root@centos7 ~]# docker volume create myvolume02
myvolume02
# 查看volume卷詳細信息
[root@centos7 ~]# docker volume inspect myvolume01
[
    {
        "Driver": "local",``
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myvolume01/_data",
        "Name": "myvolume01",
        "Options": {},
        "Scope": "local"
    }
]
# 列舉volume卷
[root@centos7 ~]# docker volume ls
DRIVER              VOLUME NAME
local               myvolume01
local               myvolume02
# 刪除volume卷
[root@centos7 ~]# docker volume rm myvolume01
myvolume01
[root@centos7 ~]# docker volume ls
DRIVER              VOLUME NAME
local               myvolume02
# 移除未使用的volume卷
[root@centos7 ~]# docker volume prune
WARNING! This will remove all volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
myvolume02

Total reclaimed space: 0 B
[root@centos7 ~]# docker volume ls
DRIVER              VOLUME NAME

2、數據卷容器
概念:命名的容器掛載數據卷,其他容器通過掛載這個容器實現數據共享,掛載數據卷的容器,就叫做數據卷容器。
數據卷容器的特點:
在新創建的容器中掛載數據卷容器後,刪除數據卷容器,此時依然能在新創建的容器中訪問數據卷。這是因為在創建新的容器時,掛載數據卷容器僅僅是通過數據卷容器將數據卷的信息傳遞給新的容器,並不會因為數據卷容器的刪除而影響數據卷的使用。
即便使用docker rm -v [DOCKER NAME] 指定在刪除容器的同時刪除數據卷容器,但如果掛載了該數據卷容器的容器處於使用狀態,此時該容器依然可以訪問數據卷。
數據卷容器的創建:
docker create -v [directory|file] [OPTIONS] IMAGE [COMMAND] [ARG...]

掛載數據卷容器的方法:
docker run --volumes-from [CONTAINER NAME]

Docker容器的數據共享
1)docker容器間共享數據
方法1:使用數據卷容器

#Docker宿主機上創建一個web目錄
[root@centos7 ~]# mkdir /tmp/websrvs
[root@centos7 ~]# echo "Docker Volume" >> /tmp/websrvs/index.html
#創建一個數據卷容器(因為容器停止後仍可以使用容器的卷,所以僅創建容器即可,可以不啟動容器)
[root@centos7 ~]# docker create --name centos01 -v /tmp/websrvs:/usr/share/nginx/html:ro centos
bdd70d50bab6c43ab731a1e9921c71121e45199aaf519411089c6a98e2053a69
#將容器卷掛載到另外一個容器中
[root@centos7 ~]# docker run -itd --name nginx01 -p 8080:80/tcp --volumes-from centos01 nginx
3c50fa50eb769a0db505d5084a638e7a89b6f5027c994c0aff34dd80b114d76f
#測試是否能正常訪問數據
[root@centos7 ~]# curl http://localhost:8080
Docker Volume
#進入容器內部查看數據
[root@centos7 ~]# docker exec -it nginx01 /bin/bash
root@3c50fa50eb76:/# mount -n |grep "\/usr\/share\/nginx\/html"
/dev/mapper/centos-root on /usr/share/nginx/html type ext4 (ro,relatime,data=ordered)
root@3c50fa50eb76:/# cat /usr/share/nginx/html/index.html 
Docker Volume

方法2:共享宿主機數據(目錄或文件)

#Docker宿主機上創建一個webroot目錄
[root@centos7 ~]# mkdir -p /tmp/webroot 
[root@centos7 ~]# echo "Docker volume on Guest" >> /tmp/webroot/index.html
#創建一個名為nginx02的容器,掛載webroot目錄
[root@centos7 ~]# docker run -itd -p 8081:80/tcp --name nginx02 -v /tmp/webroot:/usr/share/nginx/html nginx
08d99f6b920d2a65ad6bdba68c7c0a0602755a25e9d6f62cb25f2ce453f2c962
#創建一個名為nginx03的容器,掛載webroot目錄
[root@centos7 ~]# docker run -itd -p 8082:80/tcp --name nginx03 -v /tmp/webroot:/usr/share/nginx/html nginx
a05da8b02b5de95f75d1cd166fc21e0fd9bca7031ee79710e11d614b85a1b014
#測試訪問web鏈接,發現訪問到的數據是一致的
[root@centos7 ~]# curl http://localhost:8081
Docker volume on Guest
[root@centos7 ~]# curl http://localhost:8082
Docker volume on Guest
#使用docker exec命令進入docker容器內部,然後嘗試修改index.html文件內容
[root@centos7 ~]# docker exec -it nginx02 /bin/bash
root@08d99f6b920d:/# ls /usr/share/nginx/html/
index.html
root@08d99f6b920d:/# echo "Changed by nginx02." > /usr/share/nginx/html/index.html 
root@08d99f6b920d:/# cat /usr/share/nginx/html/index.html 
Changed by nginx02.
root@08d99f6b920d:/# exit
exit
#退出容器後再次訪問,發現兩個Url得到的數據都發生了改變
[root@centos7 ~]# curl http://localhost:8081
Changed by nginx02.
[root@centos7 ~]# curl http://localhost:8082
Changed by nginx02.

註意:
使用docker創建容器的-v選項
-v:物理機文件夾:容器的目錄(容器中目錄如果不存在,會自動創建,如果存在,會覆蓋掉),即將宿主機中的目錄掛載到鏡像中的目錄。
若需要掛載多個目錄,可多次采用-v。

2)Docker容器跟宿主機共享數據
方法1:docker cp 在一個容器和本地文件系統之間拷貝文件或目錄
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
-a, --archive:歸檔模式
-L, --follow-link:始終跟蹤SRC_PATH中的符號鏈接路徑
示例:

#拷貝本地文件到容器中
[root@centos7 ~]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
a05da8b02b5d        nginx               "nginx -g ‘daemon ..."   4 hours ago         Up 6 seconds        0.0.0.0:8082->80/tcp   nginx03
[root@centos7 ~]# echo "Content of test." >> test.html
[root@centos7 ~]# docker cp ./test.html nginx03:/usr/share/nginx/html/
[root@centos7 ~]# curl http://localhost:8082/test.html
Content of test.
#從容器中拷貝文件到本地
[root@centos7 ~]# ls /tmp/websrvs/
index.html
[root@centos7 ~]# docker cp -a nginx03:/usr/share/nginx/html/test.html /tmp/websrvs/
[root@centos7 ~]# ls -l /tmp/websrvs/
total 8
-rw-r--r-- 1 root root 14 Feb 18 14:17 index.html
-rw-r--r-- 1 root root 17 Feb 18 18:58 test.html
[root@centos7 ~]# cat /tmp/websrvs/test.html 
Content of test.
#測試-a和-L參數
[root@centos7 ~]# ll testfiles/
total 12
-rw------- 1 root root 1730 Feb 18 19:04 anaconda-ks.cfg
-rw-r--r-- 1 root root   38 Feb  9 02:15 Dockerfile
lrwxrwxrwx 1 root root   32 Feb 18 19:05 index.html -> /usr/share/nginx/html/index.html
-rw-r--r-- 1 root root   17 Feb 18 18:58 test.html
[root@centos7 ~]# cat testfiles/index.html    
[root@centos7 ~]# cat /usr/share/nginx/html/index.html 
#註意這裏testfiles目錄下的index.html是一個軟連接,鏈接到本地文件系統中/usr/share/nginx/html/index.html,而文件內容為空
[root@centos7 ~]# docker cp -aL testfiles nginx03:/usr/share/nginx/html/
[root@centos7 ~]# curl http://localhost:8082/testfiles/   
Changed by nginx02.
#這裏獲取的實際上是容器內/usr/share/nginx/html/testfiles/index.html的內容
[root@centos7 ~]# curl http://localhost:8082/
Changed by nginx02.
#這裏獲取的是容器內/usr/share/nginx/html/index.html的內容
#因為訪問兩個地址的結果一致,說明-L參數將符號鏈接完全拷貝過去,容器內的/usr/share/nginx/html/testfiles/index.html 仍然指向 /usr/local/nginx/html/index.html,而容器內的 /usr/local/nginx/html/index.html文件是有內容的,因而2次訪問的結果都是有內容返回的。

方法2:使用數據卷,將宿主機上的文件或目錄掛載到容器中

[root@centos7 ~]# docker run -itd --name nginx04 -p 8084:80/tcp -v testfiles:/usr/share/nginx/html nginx
8522678c26427f7e59388549a00cde4e8d462fad9322a337c990436fb9e9e43a
#在本地文件系統中修改,容器內能同步
[root@centos7 ~]# echo "Hello, Mr(s). Guest." >> testfiles/welcome.html
[root@centos7 ~]# curl http://localhost:8084/welcome.html
Hello, Mr(s). Guest.
#在容器中修改,本地也能同步
[root@centos7 ~]# docker exec -d nginx04 rm -f /usr/share/nginx/html/welcome.html
[root@centos7 ~]# ls testfiles/welcome.html
ls: cannot access testfiles/welcome.html: No such file or directory

容器的備份和還原
備份:
創建一個需要備份的容器:

[root@centos7 ~]# docker run -itd -p 8080:80/tcp -v /usr/share/nginx/html:/usr/share/nginx/html:ro --name websrv01 nginx
ab16bcdcda205c4f610a52bd47d22e32cb7ebbac6618a5027f90f301b973d53d

創建一個用來備份的容器:
[root@centos7 ~]# docker run --volumes-from websrv01 -v /opt:/backup --name backupsite01 centos tar zcf /backup/wwwroot.tar.gz /usr/share/nginx/html
生成文件:

[root@centos7 ~]# echo "Test file 1." >> /usr/share/nginx/html/test1.html
[root@centos7 ~]# echo "Test file 2." >> /usr/share/nginx/html/test2.html
[root@centos7 ~]# echo "Test file 3." >> /usr/share/nginx/html/test3.html

查看備份文件:

[root@centos7 ~]# tar -ztf /opt/wwwroot.tar.gz 
usr/share/nginx/html/
usr/share/nginx/html/index.html
usr/share/nginx/html/test2.html
usr/share/nginx/html/test3.html
usr/share/nginx/html/test1.html

還原:
到要還原的容器(websrv01)上刪除文件

[root@centos7 ~]# docker exec websrv01 rm -rf /usr/share/nginx/html/*
[root@centos7 ~]# curl http://localhost:8080/test1.html
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.8</center>
</body>
</html>
[root@centos7 ~]# curl http://localhost:8080/test2.html
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.15.8</center>
</body>
</html>

創建一個還原用的臨時容器,進行還原操作

[root@centos7 ~]# docker run --volumes-from websrv01 -v /opt:/backup centos tar zxf /backup/wwwroot.tar.gz -C /usr/share/nginx/html/

驗證還原結果

[root@centos7 ~]# curl http://localhost:8080/test1.html
Test file 1.
[root@centos7 ~]# curl http://localhost:8080/test2.html
Test file 2.
[root@centos7 ~]# curl http://localhost:8080/test3.html
Test file 3.

Docker系列(五):Docker存儲管理