天天看點

VOLUME 定義匿名卷 —— docker build

VOLUME 定義匿名卷

格式為:

  • ​VOLUME ["<路徑1>", "<路徑2>"...]​

  • ​VOLUME <路徑>​

之前我們說過,容器運作時應該盡量保持容器存儲層不發生寫操作,對于資料庫類需要儲存動态資料的應用,其資料庫檔案應該儲存于卷(volume)中,後面的章節我們會進一步介紹 Docker 卷的概念。

為了防止運作時使用者忘記将動态檔案所儲存目錄挂載為卷,在 ​

​Dockerfile​

​ 中,我們可以事先指定某些目錄挂載為匿名卷,這樣在運作時如果使用者不指定挂載,其應用也可以正常運作,不會向容器存儲層寫入大量資料。

VOLUME /data
      

這裡的 ​

​/data​

​ 目錄就會在運作時自動挂載為匿名卷,任何向 ​

​/data​

​ 中寫入的資訊都不會記錄進容器存儲層,進而保證了容器存儲層的無狀态化。當然,運作時可以覆寫這個挂載設定。

比如:

docker run -d -v mydata:/data xxxx
      

在這行指令中,就使用了 ​

​mydata​

​ 這個命名卷挂載到了 ​

​/data​

​ 這個位置,替代了 ​

​Dockerfile​

​ 中定義的匿名卷的挂載配置。

Docker 資料管理

VOLUME 定義匿名卷 —— docker build

這一章介紹如何在 Docker 内部以及容器之間管理資料,在容器中管理資料主要有兩種方式:

  • 資料卷(Volumes)
  • 挂載主機目錄 (Bind mounts)

資料卷

​資料卷​

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

  • 資料卷

     可以在容器之間共享和重用
  • 對 

    資料卷

     的修改會立馬生效
  • 資料卷

     的更新,不會影響鏡像
  • 資料卷

     預設會一直存在,即使容器被删除
注意:​

​資料卷​

​ 的使用,類似于 Linux 下對目錄或檔案進行 mount,鏡像中的被指定為挂載點的目錄中的檔案會隐藏掉,能顯示看的是挂載的 ​

​資料卷​

​。

建立一個資料卷

$ docker volume create my-vol
      

檢視所有的 ​

​資料卷​

$ docker volume ls

local               my-vol
      

在主機裡使用以下指令可以檢視指定 ​

​資料卷​

​ 的資訊

$ docker volume inspect my-vol
[
    {
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]
      

  

啟動一個挂載資料卷的容器

在用 ​

​docker run​

​ 指令的時候,使用 ​

​--mount​

​ 标記來将 ​

​資料卷​

​ 挂載到容器裡。

在一次 ​

​docker run​

​ 中可以挂載多個 ​

​資料卷​

下面建立一個名為 ​

​web​

​ 的容器,并加載一個 ​

​資料卷​

​ 到容器的 ​

​/webapp​

​ 目錄。

$ docker run -d -P \
    --name web \
    # -v my-vol:/wepapp \
    --mount source=my-vol,target=/webapp \
    training/webapp \
    python app.py
      

檢視資料卷的具體資訊

在主機裡使用以下指令可以檢視 ​

​web​

​ 容器的資訊

$ docker inspect web
      

​資料卷​

​ 資訊在 "Mounts" Key 下面

"Mounts": [
    {
        "Type": "volume",
        "Name": "my-vol",
        "Source": "/var/lib/docker/volumes/my-vol/_data",
        "Destination": "/app",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""
    }
],
      

删除資料卷

$ docker volume rm my-vol
      

​資料卷​

​ 是被設計用來持久化資料的,它的生命周期獨立于容器,Docker 不會在容器被删除後自動删除 

​資料卷​

​,并且也不存在垃圾回收這樣的機制來處理沒有任何容器引用的 ​

​資料卷​

如果需要在删除容器的同時移除資料卷。可以在删除容器的時候使用 ​

​docker rm -v​

​ 這個指令。

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

$ docker volume prune
      

挂載一個主機目錄作為資料卷

使用 ​

​--mount​

​ 标記可以指定挂載一個本地主機的目錄到容器中去。

$ 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 會報錯。

Docker 挂載主機目錄的預設權限是 ​

​讀寫​

​,使用者也可以通過增加 ​

​readonly​

​ 指定為 ​

​隻讀​

$ docker run -d -P \
    --name web \
    # -v /src/webapp:/opt/webapp:ro \
    --mount type=bind,source=/src/webapp,target=/opt/webapp,readonly \
    training/webapp \
    python app.py
      

加了 ​

​readonly​

​ 之後,就挂載為 ​

​隻讀​

​ 了。如果你在容器内 ​

​/opt/webapp​

​ 目錄建立檔案,會顯示如下錯誤

/opt/webapp # touch new.txt
touch: new.txt: Read-only file system
      

​web​

$ docker inspect web      

​挂載主機目錄​

​ 的配置資訊在 "Mounts" Key 下面

"Mounts": [
    {
        "Type": "bind",
        "Source": "/src/webapp",
        "Destination": "/opt/webapp",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],
      

挂載一個本地主機檔案作為資料卷

​--mount​

​ 标記也可以從主機挂載單個檔案到容器中

$ docker run --rm -it \
   # -v $HOME/.bash_history:/root/.bash_history \
   --mount type=bind,source=$HOME/.bash_history,target=/root/.bash_history \
   ubuntu:18.04 \
   bash

root@2affd44b4667:/# history
1  ls
2  diskutil list
      

 這樣就可以記錄在容器輸入過的指令了。 

繼續閱讀