docker volume

Volume概念

眾所周知,Docker Image可以理解成多個只讀文件疊加而成,因此Docker Image是只讀的。

當(dāng)我們將其運行起來,就相當(dāng)于在只讀的Image外包裹了一層讀寫層變成了容器。

當(dāng)你刪除容器之后,使用這個鏡像重新創(chuàng)建一個容器,此時的鏡像的只讀層還和原來的一樣,但是你在讀寫層的修改全部都會丟失。

那么問題就來了,如果想要持久化在讀寫層的數(shù)據(jù),該怎么利用docker做到呢?

docker使用volume實現(xiàn)數(shù)據(jù)的持久化,不僅如此volume還能幫助容器和容器之間,容器和host之間共享數(shù)據(jù)。

Volume如何在mac上持久化數(shù)據(jù)

如果想要持久化數(shù)據(jù),就必須將讀寫層的數(shù)據(jù)暫存在host machine,因此當(dāng)你使用:

  • docker run .... -v /data
  • docker volume create --name **

以上兩種指令都可以幫助你創(chuàng)建一個Volume,其實是在host machine上創(chuàng)建一個directory。

常在mac上用docker的人應(yīng)該知道,和Linux不同,在mac上用docker會在mac上啟動一個虛擬機運行docker,因此volume創(chuàng)建的directory并不在你的machine上,而是在虛擬機中。

那么如何知道我的volume創(chuàng)建在host machine的什么位置呢?

  • docker volume ls可以看到當(dāng)前所有的volume
    image.png

你可以看到上圖中有volume有一些是自己命名的有一些是一串?dāng)?shù)字:
- 自己命名的是使用docker volume create --name **創(chuàng)建的,比如haha 是使用docker volume create --name haha
- 數(shù)字Volume是在創(chuàng)建container的同時創(chuàng)建的

  • docker volume inspect [volume name] 即可獲取這個volume在docker 虛擬機中的位置,根據(jù)上圖可以看到haha在虛擬機中的地址是/var/lib/docker/volumes/haha/_data

那么如何登錄到docker虛擬機中呢?

  • 執(zhí)行:screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
    • 注意:當(dāng)你的docker version是18.06.0-ce-mac70 (26399)采用上面的指令,如果不是這個version請使用screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
  • 然后你會看到一個新的命令行,請按下enter,此時你就在docker虛擬機中了。
  • 此時cd /var/lib/docker/volumes/haha/_data就是haha這個volume的

使用Volume有什么優(yōu)勢呢

  • Volume可以在容器之間以及容器和主機之間共享和重用
  • Volume在某一掛載的位置被修改,所以使用該volume的地方都會同時更新
  • Volume的大小不會被加到容器本身上
  • Volume會一直存在,直到?jīng)]有任何容器使用它,才能使用命令docker volume rm [volumes名字]刪除

主機和容器之間的數(shù)據(jù)共享

  • docker run -v /home/adrian/data:/data [image]
    -v A:B A是在主機上的地址,B是在容器中的地址,這兩個地址如果不存在都會創(chuàng)建,一旦容器運行,AB的會完全同步。

容器和容器之間的數(shù)據(jù)共享

使用--volumes-from, docker run -it -h NEWCONTAINER --volumes-from container-test debian /bin/bash 意思是,將container-test這個container中的volume掛載到當(dāng)前將要運行起來的容器中。前提是container-test中的volumes必須被創(chuàng)建過,但是container-test可以是被stop的,原因是volume只能被手動刪除,不是隨著容器停止而被刪除

數(shù)據(jù)容器

準(zhǔn)備一個容器專門用來做數(shù)據(jù)容器,比如docker run -d -v /dbdata --name dbdata postgres echo Data-only container for postgres運行postgres這個容器然后給他配置一個volume,其他容器都可以--volumes-from到這個volume,數(shù)據(jù)容器可以不在運行狀態(tài)甚至可以被刪除,只要volume創(chuàng)建了即可。

docker-compose 配置Volumes

雖然有很多方式創(chuàng)建volume但是感覺最方便的還是用docker-compose

version: "3.2"
services:
  web:
    image: alpine
    volumes:
      - ~/test:/data

docker-compose可以很方便的實現(xiàn)容器和容器間,容器和主機間數(shù)據(jù)共享。

  • 容器和主機: 在services定義(web)中使用volumes將主機的test掛載到容器的/data

  • 容器和容器:可以通過在和service平級的volumes中定義volumes

    version: "3.2"
    services:
      web:
        image: alpine
        volumes:
          - mydata:/data
      web1:
        image: alpine
        volumes:
          - mydata:/data
    volumes:
      mydata:
      dbdata:
    

    執(zhí)行之后rundocker volume ls可以看到創(chuàng)建了兩個以project name開頭的volume

    image.png

就是你創(chuàng)建的,然后volumes: - mydata:/data 就是將你創(chuàng)建的volume掛載到容器中,此時web和web1共享pezhang_mydata volume

  • 不同docker compose文件中container的數(shù)據(jù)共享和上面的方法一樣但是需要external

      version: "3.2"
      services:
        web:
          image: alpine
          volumes:
            - mydata:/data
        web1:
          image: alpine
          volumes:
            - mydata:/data
      volumes:
        mydata:
          external: true
    

    但是前提你必須要有mydata這個volume 如果沒有,可以使用docker volume create --name=mydata創(chuàng)建。當(dāng)你加上external docker不會幫你創(chuàng)建volume而是去找這個volume是否存在,如果找不到就會報錯。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容