理解 docker volume



1. docker volume 簡介

文章 介紹了 docker image,它由一系列只讀層構成,通過 docker image 可以提高鏡像構建,存儲和分發的效率,節省時間和存儲空間。然而 docker image 還是存在一些問題,如下:

  • 多個容器之間的數據無法共享。
  • 當刪除容器時,容器產生的數據將丟失。

基於這幾點 Docker 引入了 volume 機制。 volume 是存在於一個或多個容器中的特定文件或文件夾,這個目錄以獨立於聯合文件系統的形式在宿主機上存在。volume 機制的主要優點如下:

  • volume 能在不同容器間共享數據。
  • volume 的生存周期獨立於容器,刪除容器,volume 依然存在。
  • volume 中數據的操作不會影響到鏡像。

2. 創建 volume

創建 volume,將 volume attach 到容器中,刪除容器,查看 volume 的使用情況。

查看創建 volume 使用的驅動:

[root@k8s-master-node-1 centos]# docker info | grep -i volume
  Volume: local

創建 volume:

[root@k8s-master-node-1 centos]# docker volume create chunqiu
chunqiu
[root@k8s-master-node-1 centos]# docker volume inspect chunqiu
[
    {
        "CreatedAt": "2021-05-10T09:09:49Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/chunqiu/_data",
        "Name": "chunqiu",
        "Options": {},
        "Scope": "local"
    }
]

volume 在宿主機上的目錄 (Mountpoint) 是 /var/lib/docker/volumes/<volume_name>/_data。將 volume attach 到容器 ubuntu 上:

[root@k8s-master-node-1 centos]# docker run -it -v chunqiu:/data --name=ubuntu ubuntu /bin/bash
root@8c4611b025f6:/# ls /data/
root@8c4611b025f6:/#

使用 -v 選項將 volume attach 到容器內,並指定容器的目錄為 /data。寫文件到 data 目錄:

/* 容器內寫文件 */
root@8c4611b025f6:/# cd data/
root@8c4611b025f6:/data# touch chunqiu

[root@k8s-master-node-1 _data]# ls -l /var/lib/docker/volumes/chunqiu/_data/
total 0
-rw-r--r-- 1 root root 0 May 10 09:44 chunqiu

/* 容器外寫文件 */
[root@k8s-master-node-1 _data]# touch handsomeBoy

root@8c4611b025f6:/data# ls -l
total 0
-rw-r--r-- 1 root root 0 May 10 09:44 chunqiu
-rw-r--r-- 1 root root 0 May 10 09:49 handsomeBoy

容器和宿主機上目錄建立映射。刪除容器,查看 volume 是否存在:

[root@k8s-master-node-1 _data]# docker rm ubuntu
ubuntu

[root@k8s-master-node-1 _data]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 10 09:44 chunqiu
-rw-r--r-- 1 root root 0 May 10 09:49 handsomeBoy

刪除容器 volume 依然存在。

3. volume 與 image

探索 volume 與 image 的關系,volume 映射的文件/文件夾會反映在“讀寫層”,和靜態的 image 沒有關系。當 volume 映射的文件/文件夾和 image 同名時,image 中內容將被隱藏,從而保持 volume 和宿主機上文件/文件夾的一致性。

創建 volume 映射到容器內的 /home 目錄,查看 home 目錄下文件變化情況:

[root@k8s-master-node-1 _data]# docker run -it b9fd190d76e0 /bin/bash
root@c536d00399fa:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@c536d00399fa:/# ls home/
demo
root@c536d00399fa:/home# exit

[root@k8s-master-node-1 _data]# docker run -it -v chunqiu:/home b9fd190d76e0 /bin/bash
root@faebe07c5405:/# cd home/
root@faebe07c5405:/home# ls
chunqiu  handsomeBoy

home 目錄下的 demo 文件被隱藏,取而代之的是宿主機上 volume 的 MountPoint 下的文件。

思考:如果取代的是 /etc 目錄會怎么樣?

4. 容器間共享目錄

volume 能在不同容器間共享數據,新建一個容器使它和 ubuntu 共享 volume chunqiu:

[root@k8s-master-node-1 centos]# docker run -it --volumes-from ubuntu ubuntu /bin/bash
root@a66c276b1954:/# ls data/
chunqiu  handsomeBoy

5. docker commit

將容器 commit 為鏡像,容器內的 volume 數據會保存到鏡像中嗎?做個小實驗如下:

[root@k8s-master-node-1 centos]# docker commit ubuntu
sha256:e938f5251682f9b48ce344f1372d39b2ef6b7b4b6f8160afa38fe94492de158e
[root@k8s-master-node-1 centos]# docker image ls | grep e938
<none>                               <none>              e938f5251682        12 seconds ago      72.7MB

[root@k8s-master-node-1 centos]# docker run -it e938f5251682 /bin/bash
root@11f74c3587e1:/# ls
bin  boot  data  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@11f74c3587e1:/# ls data/
root@11f74c3587e1:/data#

可以看到,data 目錄下並沒有 volume 的文件,這是因為 docker commit 不會對掛載的 volume 進行保存。這也說明了為什么在 dockerfile 中這么寫找不到文件 file:

FROM ubuntu
RUN useradd foo
VOLUME /data
RUN touch /data/file
RUN chown -R foo:foo /data

6. docker volume 原理

docker 創建 volume 的過程實際上是在 mount namespace 添加做 mount 操作的過程,具體可看這里了解更多,這里就不做贅述啦~


免責聲明!

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



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