Docker Volumes指南

    1.概述

    Docker容器用於在隔離的環境中運行應用程序。默認情況下,容器停止時,容器內的所有更改都將丟失。如果我們想在兩次運行之間保留數據,那麼Docker捲和綁定掛載會有所幫助。

    在本教程中,我們將學習Docker Volumes以及如何管理它們並將其連接到容器。

    2.什麼是Docker Volume卷?

    2.1。 Docker文件系統

    docker容器運行鏡像中定義的軟件堆棧。鏡像由一組在稱為聯合文件系統的文件系統上工作的只讀層組成。當我們啟動一個新容器時,Docker在映像層的頂部添加了一個可讀寫層,從而使該容器可以像在標準Linux文件系統上一樣運行。

    因此,容器內的任何文件更改都會在讀寫層中創建一個工作副本。但是,當容器停止或刪除時,該讀寫層會丟失

    docker

    我們可以通過運行先寫入然後讀取文件的命令來進行嘗試:

    $ docker run bash:latest \
    
     bash -c "echo hello > file.txt && cat file.txt"

    結果是:

    hello

    但是,如果我們僅使用命令運行相同的鏡像以輸出文件的內容:

    $ docker run bash:latest bash -c "cat file.txt"
    
     cat: can't open 'file.txt': No such file or directory

    容器的第二次運行在乾淨的文件系統上運行,因此找不到該文件。

    2.2 Bind Mounts

    Docker綁定掛載是從容器到主機上目錄的高性能連接。它允許主機與容器共享其自己的文件系統,可以將其設置為只讀或讀寫。

    這使我們可以使用容器來運行我們不想在主機上安裝的工具,但仍可以使用主機的文件。例如,如果我們想為特定腳本使用bash的自定義版本,則可以在安裝到當前工作目錄的bash容器中執行該腳本:

    $ docker run -v $(pwd):/var/opt/project bash:latest \
    
     bash -c "echo Hello > /var/opt/project/file.txt"

    v選項可用於所有形式的掛載,並在這種情況下指定主機上的源– $(pwd)輸出中的工作目錄–容器中的目標掛載點– /var/opt/project

    運行此命令後,我們將在主機的工作目錄中找到file.txt 。這是在Docker容器調用之間提供持久性文件的一種簡單方法,儘管在容器代表主機工作時最有用。

    一個很好的用例是在Docker中執行各種版本的語言構建工具,以避免在開發人員機器上發生衝突的安裝。

    我們應該注意,Windows bash shell有時需要$(pwd -W)可以以bash shell的形式提供工作目錄傳遞給Docker。

    2.3。 Docker卷

    綁定安裝使用主機文件系統,但是**Docker卷是Docker固有的**。數據保存在連接到主機的存儲中的某個位置(通常是本地文件系統)。卷本身的生命週期長於容器的生命週期,因此可以持續到不再需要為止。卷可以在容器之間共享。

    在某些情況下,卷的形式不能由主機直接使用。

    3.管理卷

    Docker允許我們通過docker volume命令集管理卷。我們可以給卷指定一個明確的名稱(命名卷),或者允許Docker生成一個隨機的捲(匿名卷)。

    3.1。創建卷

    我們可以通過使用create子命令並傳遞一個名稱作為參數來創建一個卷:

    $ docker volume create data_volume
    
     data_volume

    如果未指定名稱,則Docker會生成一個隨機名稱:

    $ docker volume create
    
     d7fb659f9b2f6c6fd7b2c796a47441fa77c8580a080e50fb0b1582c8f602ae2f

    3.2。查看所有卷

    ls子命令顯示了Docker已知的所有捲:

    $ docker volume ls
    
     DRIVER
     VOLUME NAME
    
     local
     data_volume
    
     local d7fb659f9b2f6c6fd7b2c796a47441fa77c8580a080e50fb0b1582c8f602ae2f

    我們可以使用-f–filter標誌並傳遞key=value參數進行過濾,以實現更高的精度:

    $ docker volume ls -f name=data
    
     DRIVER
     VOLUME NAME
    
     local
     data_volume

    3.3。檢查卷

    要顯示一個或多個卷上的詳細信息,我們使用inspect子命令:

    $ docker volume inspect ca808e6fd82590dd0858f8f2486d3fa5bdf7523ac61d525319742e892ef56f59
    
     [
    
     {
    
     "CreatedAt": "2020-11-13T17:04:17Z",
    
     "Driver": "local",
    
     "Labels": null,
    
     "Mountpoint": "/var/lib/docker/volumes/ca808e6fd82590dd0858f8f2486d3fa5bdf7523ac61d525319742e892ef56f59/_data",
    
     "Name": "ca808e6fd82590dd0858f8f2486d3fa5bdf7523ac61d525319742e892ef56f59",
    
     "Options": null,
    
     "Scope": "local"
    
     }
    
     ]

    我們應該注意,該卷的Driver描述了Docker主機如何定位該卷。例如,卷可以通過nfs放在遠程存儲中。在此示例中,該卷位於本地存儲中。

    3.4。刪除卷

    要分別刪除一個或多個卷,我們可以使用rm子命令:

    $ docker volume rm data_volume
    
     data_volume

    3.5。刪除卷及其數據

    我們可以使用prune子命令刪除所有未使用的捲:

    $ 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:
    
     data_volume

    4.啟動具有捲的容器

    4.1。使用-v

    正如我們在前面的示例中看到的,我們可以使用-v選項通過綁定安裝啟動一個容器:

    $ docker run -v $(pwd):/var/opt/project bash:latest \
    
     bash -c "ls /var/opt/project"

    此語法還支持裝入卷:

    $ docker run -v data-volume:/var/opt/project bash:latest \
    
     bash -c "ls /var/opt/project"

    由於我們的捲是空的,因此從掛載點開始沒有列出任何內容。但是,如果我們要在一次容器調用期間寫入卷:

    $ docker run -v data-volume:/var/opt/project bash:latest \
    
     bash -c "echo Baeldung > /var/opt/project/Baeldung.txt"

    然後,我們隨後使用裝有該卷的容器,將可以訪問文件:

    $ docker run -v data-volume:/var/opt/project bash -c "ls /var/opt/project"
    
     Baeldung.txt
    

    -v選項包含三個組成部分,以冒號分隔:

    • 源目錄或卷名
    • 容器內的安裝點
    • (可選) ro如果安裝是只讀的)

    4.2。使用–mount選項

    我們可能更喜歡使用更易解釋的–mount選項來指定我們要掛載的捲:

    $ docker run --mount \
    
     'type=volume,src=data-volume,\
    
     dst=/var/opt/project,volume-driver=local,\
    
     readonly' \
    
     bash -c "ls /var/opt/project"

    –mount的輸入是一串鍵值對,以逗號分隔。我們在這裡設置:

    • type –作為volume以指示卷裝入
    • src –卷的名稱,但是如果我們一直在進行綁定安裝,則它可能是源目錄
    • dst –作為容器中的目標安裝點
    • volume-driver –在這種情況下是local驅動程序
    • readonly -使此掛載為只讀;我們可以選擇rw進行讀/寫

    我們應該注意,如果上面的命令尚不存在,它也會創建一個卷。

    4.3。使用–volumes-from共享卷

    我們應該注意,將捲附加到容器會在容器和卷之間建立長期連接。即使容器已經退出,該關係仍然存在。這使我們可以使用已退出的容器作為模板,以將同一組卷安裝到新的捲上。

    假設我們在具有data-volume裝載的容器中運行了echo腳本。稍後,我們可以列出我們使用過的所有容器:

    $ docker ps -a
    
     CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    
     4920602f8048 bash "docker-entrypoint.s…" 7 minutes ago Exited (0) 7 minutes ago exciting_payne

    通過複製此容器使用的捲,可以運行下一個容器:

    $ docker run --volumes-from 4920 \
    
     bash:latest \
    
     bash -c "ls /var/opt/project"
    
     Baeldung.txt
    

    實際上, –volumes-from通常用於鏈接正在運行的容器之間的捲。 Jenkins使用它在作為Docker容器運行的代理之間共享數據。

    5.結論

    在本文中,我們了解了Docker通常如何創建帶有新文件系統的容器,但是綁定安裝和卷如何允許在容器生命週期之外長期存儲數據。

    我們看到瞭如何列出和管理Docker卷,以及如何通過命令行將捲連接到正在運行的容器。