簡體   English   中英

docker 數據量與掛載的主機目錄

[英]docker data volume vs mounted host directory

我們可以在 docker 中擁有一個數據量:

$ docker run -v /path/to/data/in/container --name test_container debian
$ docker inspect test_container
...
Mounts": [
    {
        "Name": "fac362...80535",
        "Source": "/var/lib/docker/volumes/fac362...80535/_data",
        "Destination": "/path/to/data/in/container",
        "Driver": "local",
        "Mode": "",
        "RW": true
    }
]
...

但是,如果數據卷位於/var/lib/docker/volumes/fac362...80535/_data ,它與使用-v /path/to/data/in/container:/home/user/a_good_place_to_have_data掛載的文件夾中的數據有什么不同-v /path/to/data/in/container:/home/user/a_good_place_to_have_data

盡管使用卷和綁定安裝感覺相同(唯一的變化是目錄的位置),但行為上存在差異。

卷與綁定安裝

  • 使用 Bind Mount,將主機上的文件或目錄掛載到容器中。 文件或目錄由其在主機上的完整或相對路徑引用。
  • 使用 Volume,會在主機上的Docker 存儲目錄中創建一個新目錄, Docker 管理該目錄的內容。

與綁定安裝相比,卷的優勢:

  • 與綁定安裝相比,卷更容易備份或遷移。
  • 您可以使用 Docker CLI 命令或 Docker API 管理卷。
  • 卷適用於 Linux 和 Windows 容器。
  • 卷可以在多個容器之間更安全地共享。
  • 卷驅動程序允許您在遠程主機或雲提供商上存儲卷、加密卷的內容或添加其他功能。
  • 新卷的內容可以由容器預先填充。

編輯(9.9.2019):
根據@Sebi2020 的評論,綁定掛載更容易備份。 Docker 不提供任何命令來備份卷。 您必須使用帶有綁定安裝的臨時容器來創建備份。

由 Docker 創建和管理。 您可以使用 docker volume create 命令顯式創建卷,或者 Docker 可以在容器或服務創建期間創建卷。

創建卷時,它存儲在 Docker 主機上的目錄中。 當您將卷掛載到容器中時,此目錄就是掛載到容器中的目錄。 類似於綁定掛載的工作方式,不同之處在於卷由 Docker 管理並且與主機的核心功能隔離。

一個給定的卷可以同時安裝到多個容器中。 當沒有正在運行的容器正在使用卷時,該卷仍然可供 Docker 使用,並且不會自動刪除。 您可以使用 docker volume prune 刪除未使用的卷。

掛載卷時,它可能是命名的或匿名的。 匿名卷在首次掛載到容器中時沒有明確的名稱,因此 Docker 為它們提供了一個隨機名稱,該名稱保證在給定的 Docker 主機中是唯一的。 除了名稱之外,命名卷和匿名卷的行為方式相同。

卷還支持使用卷驅動程序,這允許您將數據存儲在遠程主機或雲提供商上,以及其他可能性。

在此處輸入圖片說明

綁定坐騎

自 Docker 早期就可用。 與卷相比,綁定掛載的功能有限。 使用綁定掛載時,主機上的文件或目錄會掛載到容器中。 文件或目錄由其在主機上的完整路徑引用。 該文件或目錄不需要已經存在於 Docker 主機上。 如果它尚不存在,則按需創建。 綁定掛載非常高效,但它們依賴於主機的具有特定目錄結構的文件系統。 如果您正在開發新的 Docker 應用程序,請考慮改用命名卷。 您不能使用 Docker CLI 命令直接管理綁定掛載。

在此處輸入圖片說明

還有tmpfs mounts
tmpfs 掛載

tmpfs 掛載不會持久保存在磁盤上,無論是在 Docker 主機上還是在容器內。 在容器的生命周期內,容器可以使用它來存儲非持久狀態或敏感信息。 例如,在內部,swarm 服務使用 tmpfs 掛載將機密掛載到服務的容器中。
在此處輸入圖片說明

參考:
https://docs.docker.com/storage/

這與使用 -v /path/to/data/in/container:/home/user/a_good_place_to_have_data 掛載文件夾中的數據有什么不同嗎?

這是因為,如“ 將主機目錄掛載為數據卷”中所述

主機目錄本質上是依賴於主機的。 出於這個原因,您不能從 Dockerfile 掛載主機目錄,因為構建的圖像應該是可移植的。 主機目錄不會在所有潛在主機上都可用。

如果你有一些持久化數據想要在容器之間共享,或者想要從非持久化容器中使用,最好創建一個命名的數據卷容器,然后從中掛載數據。

您可以結合使用這兩種方法:

 docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

在這里,我們啟動了一個新容器並從dbdata容器掛載了卷。
然后我們將本地主機目錄掛載為/backup
最后,我們傳遞了一個命令,該命令使用tardbdata卷的內容備份到/backup目錄中的一個backup.tar文件中。 當命令完成並且容器停止時,我們將保留dbdata卷的備份。

是的,從幾個角度來看,這是完全不同的。 就像你在問題標題中寫的那樣,它是關於理解為什么我們需要數據卷與綁定安裝到主機。

第 1 部分 - 帶有示例的基本場景

讓我們來看看 2 個場景。

案例 1:Web 服務器
我們希望為我們的 Web 服務器提供一個可能經常更改的配置文件。
例如:根據當前環境暴露端口。
我們可以每次使用相關設置重建映像,或者為每個環境創建 2 個不同的映像。 這兩種解決方案都不是很有效。

使用Bind mounts Docker 將給定的源目錄掛載到容器內的某個位置。
(聯合文件系統內只讀層中的原始目錄/文件將被簡單地覆蓋)。

例如 - 將動態端口綁定到 nginx:

version: "3.7"
services:
  web:
    image: nginx:alpine
    volumes:
     - type: bind #<-----Notice the type
       source: ./mysite.template
       target: /etc/nginx/conf.d/mysite.template
    ports:
     - "9090:8080"
    environment:
     - PORT=8080
    command: /bin/sh -c "envsubst < /etc/nginx/conf.d/mysite.template > 
        /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

(*) 請注意,此示例也可以使用 Volumes 求解。

案例 2:數據庫
Docker 容器不存儲持久數據——一旦容器停止運行,任何將寫入容器聯合文件系統中的可寫層的數據都將丟失。

但是如果我們有一個數據庫在容器上運行,而容器停止了——這意味着所有數據都將丟失怎么辦?

來救援。
這些是由 Docker 為我們管理的命名文件系統樹。

例如 - 持久化 Postgres SQL 數據:

services:    
  db:
    image: postgres:latest
    volumes:
      - "dbdata:/var/lib/postgresql/data"
    volumes:
     - type: volume #<-----Notice the type
       source: dbdata
       target: /var/lib/postgresql/data
volumes:
  dbdata:

請注意,在這種情況下,對於命名卷,源是卷的名稱(對於匿名卷,此字段被省略)。

第 2 部分 - 比較

主機上管理和隔離的差異

綁定掛載存在於主機文件系統上並由主機維護者管理。
Docker 之外的應用程序/進程也可以修改它。

Volumes也可以在宿主機上實現,但是 Docker 會為我們管理它們,並且它們不能在 Docker 之外訪問。

卷是一個更廣泛的解決方案

盡管這兩種解決方案都幫助我們將數據生命周期與容器分開,但通過使用Volumes,您可以獲得比系統更多的功能和靈活性。

使用Volumes,我們可以有效地設計我們的數據並將其與系統的其他部分分離,方法是將其存儲在專用的遠程位置(例如,在雲中)並將其與外部服務(如備份、監控、加密和硬件管理)集成。

主機目錄和數據卷之間的區別在於,Docker 通過將其放入$DOCKER-DATA-DIR/volumes目錄並附加對它的引用(名稱或隨機生成的 id)來管理后者。 那就是你得到了一點便利。

主機目錄和數據卷都是主機上的目錄。 兩者都依賴於主機。 您不能在Dockerfile引用它們中的任何一個; 每次啟動新容器時, VOLUME指令都會創建一個新的無名(具有隨機生成的 ID)卷,並且不能引用現有卷。

* $DOCKER-DATA-DIR在這里是/var/lib/docker $DOCKER-DATA-DIR除非你改變了默認值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM