1. 程式人生 > 實用技巧 >六、docker的資料卷

六、docker的資料卷

一、docker資料卷的作用

正常情況下,刪除容器,容器中所有的檔案也會被刪除。

資料卷的作用:

1:持久化容器執行過程中產生的資料檔案

2:實現多個容器間的檔案共享。

在容器中管理資料主要有兩種方式

資料卷(Volumes)

掛載主機目錄 (Bind mounts)

二、docker 資料卷的操作

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

1、資料卷可以在容器之間共享和重用

2、對資料卷的修改會立馬生效

3、對資料卷的更新,不會影響映象

4、資料卷預設會一直存在,即使容器被刪除

注意:資料卷的使用,類似於 Linux 下對目錄或檔案進行 mount,映象中的被指定為掛載點的目錄中的檔案會隱藏掉,能顯示看的是掛載的資料卷。

docker資料卷的目錄操作

1、建立資料卷

docker volume creste 資料卷名稱
[root@inode3 ~]# docker volume create ywx
ywx

2、檢視所有的資料卷

docker volume ls
[root@inode3 ~]# docker volume ls
DRIVER              VOLUME NAME
local               ywx

3、檢視容器使用資料卷的詳細資訊

docker volume inspect volume-name
[root@inode3 ~]# docker volume inspect ywx
[
  {
    
"CreatedAt": "2020-03-07T17:43:06+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/ywx/_data", "Name": "ywx", "Options": {}, "Scope": "local" } ] #"Mountpoint": "/var/lib/docker/volumes/ywx/_data" 資料卷的所在路徑

4、使用資料卷

docker run --name web4 -d -p 84:80 --mount source=ywx,target=/usr/share/nginx/html nginx:latest
或者
docker run 
--name web4 -d -p 84:80 -v ywx:/usr/share/nginx/html nginx:latest #ywx為建立的資料卷

建立、檢視、使用docker資料卷的案例:

啟動一個nginx的web1容器,將資料卷ywx掛在到容器的/usr/share/nginx/html目錄中

方法一: -v選項

docker run -d -p 80:80 -v ywx:/usr/share/nginx/html --name web1 nginx:latest

[root@inode3 ~]# docker run -d -p 80:80 -v ywx:/usr/share/nginx/html --name web1 nginx:latest
10d439e628573c6278ad3a7be2b58b472bb3b8a2b78bf5f6b4de7f479d0cbf4a
[root@inode3 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
10d439e62857        nginx:latest        "nginx -g 'daemon of…"   4 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp   web1
檢視掛在的資料卷資訊
docker inspect web1
#檢視"Mounts"資訊
"Mounts": [
        {
            "Type": "volume",
            "Name": "ywx",
            "Source": "/var/lib/docker/volumes/ywx/_data",#資料卷的路徑資訊
            "Destination": "/usr/share/nginx/html",#掛載到容器中的路徑資訊
            "Driver": "local",
            "Mode": "z",
            "RW": true,
            "Propagation": ""
        }
    ],

在外面訪問web1容器

[root@inode3 ~]# curl 192.168.32.103
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
    width: 35em;
    margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

在/var/lib/docker/volumes/ywx/_data目錄中更改index.html的內容

echo "docker web1 index.html" > /var/lib/docker/volumes/ywx/_data/index.html

再次訪問web1容器

[root@inode3 ~]# curl 192.168.32.103
docker web1 index.html

發現訪問的頁面內容已經改變

方式二: --mount

另外啟動一個nginx的web2容器,將資料卷ywx掛在到容器的/usr/share/nginx/html目錄中

docker run -d -p 81:80 --name web2 \
--mount source=ywx,target=/usr/share/nginx/html \
nginx:latest

[root@inode3 ~]# docker run -d -p 81:80 --name web2 --mount source=ywx,target=/usr/share/nginx/html nginx:latest
a0b80e4555e61258b5758df7c9c4d3a4fe80e6fc0fc041a539c2b006c8771482

檢視容器web2中資料卷ywx的掛載資訊

[root@inode3 ~]# docker inspect web2
"Mounts": [
        {
            "Type": "volume",
            "Name": "ywx",
            "Source": "/var/lib/docker/volumes/ywx/_data",
            "Destination": "/usr/local/nginx/html",
            "Driver": "local",
            "Mode": "z",
            "RW": true,
            "Propagation": ""
        }
    ],

訪問容器web2

[root@inode3 ~]# curl 192.168.32.103:81
docker web1 index.html

訪問的頁面資訊與web1相同

-v和--mount選項在掛在資料卷時,如果資料卷不存在會先建立資料卷

 [root@inode3 ~]# docker volume ls
 DRIVER              VOLUME NAME
 local               ywx

 啟用一個容器web3掛在一個不存在的資料卷king
 [root@inode3 ~]# docker run --name web3 -d -p 83:80 -v king:/usr/share/nginx/html nginx:latest
 c92a82c5f0ad5c4f312f751f2355ecde3cc955dd11d98e7615b059c3ee2d397f
 [root@inode3 ~]# docker volume ls
 DRIVER              VOLUME NAME
 local               king
 local               ywx
 -v選項會自動建立資料卷king
 [root@inode3 ~]# docker volume ls
 DRIVER              VOLUME NAME
 local               king
 local               ywx
 啟用一個容器web4掛在一個不存在的資料卷seal
 [root@inode3 ~]# docker run --name web4 -d -p 84:80 --mount source=seal,target=/usr/share/nginx/html nginx:latest
 6262d51e0a7d08a62aac2b6b5db14c160f53f36c137cd211663f6002f4e6cd4e
 [root@inode3 ~]# docker volume ls
 DRIVER              VOLUME NAME
 local               king
 local               seal
 local               ywx

5、刪除資料卷

dockers volume rm volume-name
[root@inode3 ~]# docker volume ls
DRIVER              VOLUME NAME
local               king
local               seal
local               ywx

刪除資料卷king

資料卷 是被設計用來持久化資料的,它的生命週期獨立於容器,Docker 不會在容器被刪除後自動刪除 資料卷,並且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的資料卷。

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

docker volume prune

[root@inode3 ~]# docker volume rm seal
Error response from daemon: remove seal: volume is in use - [6262d51e0a7d08a62aac2b6b5db14c160f53f36c137cd211663f6002f4e6cd4e]
如果有容器在使用,刪除時會報錯

首先停止使用資料卷的容器
[root@inode3 ~]# docker stop 6262d51e0a7d08a62aac2b6b5db14c160f53f36c137cd211663f60
6262d51e0a7d08a62aac2b6b5db14c160f53f36c137cd211663f60
再刪除該容器
[root@inode3 ~]# docker rm -f 6262d51e0a7d08a62aac2b6b5db14c160f53f36c137cd211663f60
最後刪除資料卷
[root@inode3 ~]# docker volume rm seal
seal
[root@inode3 ~]# docker volume ls
DRIVER              VOLUME NAME
local               king
local               ywx
刪除沒有使用的資料卷king和seal
[root@inode3 ~]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
king
seal

Total reclaimed space: 1.106kB
[root@inode3 ~]# docker volume ls
DRIVER              VOLUME NAME
local               ywx

三、掛載主機目錄的操作

掛在主機目錄就是把宿主機的一個命令掛在到容器中去

使用-v引數來掛在宿主機下的/web目錄,把它掛在載nginx web1的容器中去

[root@inode3 ~]# docker run -d -p 81:80 --name web1 -v /web:/usr/share/nginx/html nginx:latest
c5ba05a6efc549daaae50e4d039869d279dce0c4c4c19b2104906e69a8e1bb2b
檢視掛載資訊
[root@inode3 ~]# docker inspect web1
"Mounts": [
        {
            "Type": "bind",
            "Source": "/web",#宿主機的目錄
            "Destination": "/usr/share/nginx/html",#掛在到容器中的目錄
            "Mode": "",
            "RW": true,
            "Propagation": "rprivate"
        }
    ],

訪問web1容器
[root@inode3 ~]# curl 192.168.32.103:81
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.17.8</center>
</body>
</html>
沒有頁面資訊,在宿主機的/web目錄中建立index.html頁面,再次訪問web1容器
echo "mount /web to web1-/usr/share/nginx/html" > /web/index.html
[root@inode3 ~]# echo "mount /web to web1-/usr/share/nginx/html" > /web/index.html
[root@inode3 ~]# curl 192.168.32.103:81
mount /web to web1-/usr/share/nginx/html
訪問成功

使用--mout引數來掛在宿主機下的/web目錄,把它掛在載nginx web2的容器中去

[root@inode3 ~]# docker run -d -p 82:80 --name web2 --mount type=bind,source=/web,target=/usr/share/nginx/html nginx:latest
    73143f0adc51c43c2b6584c675e17ec0778f1e27bc6d19fd1043e8a3b18c95f0

查案掛載資訊

[root@inode3 ~]# docker inspect web2
    "Mounts": [
            {
                "Type": "bind",
                "Source": "/web",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
    訪問容器web2
    [root@inode3 ~]# curl 192.168.32.103:82
    mount /web to web1-/usr/share/nginx/html

-v和--mount在掛載宿主機目錄時的區別

--mount在掛載不存在的目錄時,會報錯的
[root@inode3 ~]# ll /ywx
ls: cannot access /ywx: No such file or directory
[root@inode3 ~]# docker run -d -p 83:80 --name web3 --mount type=bind,source=/ywx,target=/usr/share/nginx/html nginx:latest
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /ywx.
See 'docker run --help'.

-v在掛載不存在的目錄時,會先建立目錄,再來掛載
[root@inode3 ~]# ll /ywx
ls: cannot access /ywx: No such file or directory
[root@inode3 ~]# docker run -d -p 83:80 --name web3 -v /ywx:/usr/share/nginx/html nginx:latest
9dbb1670c1d774a9161f7cc29b0b2873ae531635acec9989473ef02d191ef20e
[root@inode3 ~]# ll -d /ywx
drwxr-xr-x 2 root root 6 Mar  7 19:00 /ywx

掛載只讀目錄只能使用--mount引數

把宿主機的/tmp目錄以只讀的方式掛載到容器web1中的/usr/share/nginx/html,則在容器web1將不能對/usr/share/nginx/html進行修改
[root@inode3 ~]# docker run -d -p 81:80 --name web1 --mouth type=bind,source=/ywx,target=/usr/share/nginx/html,readonly nginx:latest

進入容器測試
[root@inode3 ~]# docker run -d -p 81:80 --name web1 --mount type=bind,source=/ywx,target=/usr/share/nginx/html,readonly nginx:latest
46198dc62481956d2bc918b8139b440ba0553be1668c14770f9c80f605b514ca
[root@inode3 ~]# docker exec -it web1 /bin/bash
root@46198dc62481:/# cd /usr/share/nginx/html/
root@46198dc62481:/usr/share/nginx/html# touch aa
touch: cannot touch 'aa': Read-only file system