1. 程式人生 > >Docker系列之五:Volume 卷的使用——以Redis為例

Docker系列之五:Volume 卷的使用——以Redis為例

簡介

卷在Docker裡非常重要,在系統之三中提到過,Docker利用聯合載入技術在root檔案系統層上載入更多的只讀檔案系統,這裡簡稱聯合檔案系統(Union File System),卷是在一個或者多個容器內被選定的目錄,可以繞過這個聯合檔案系統為Docker提供持久資料或者共享資料,這意味著對卷的修改會直接生效,並繞過映象,卷可以在容器之間共享,即使容器停止,卷裡的內容依舊存在。

以nginx為例

建立一個檔案, index.html

[email protected]:/home/cong/DockerDemo# cat index.html
<h1>Hello world</h1>

執行如下命令


[email protected]:/home/cong/DockerDemo# docker run -itd -p 5005:80 -v $PWD:/usr/share/nginx/html nginx
7b56643e727d89f9cf4191a7850c8aab6816d13480a2afa0515a63aa51a65378

[email protected]:/home/cong/DockerDemo# curl localhost:5005
<h1>Hello world</h1>

[email protected]:/home/cong/DockerDemo# docker exec -it 7b56 bash

[email protected]
:/# cd /usr/share/nginx/html [email protected]:/usr/share/nginx/html# ls index.html

可以看到我們將/home/cong/DockerDemo資料夾裡面的內容掛載到容器裡的/usr/share/nginx/html中了。

然後我們進入容器裡面,修改index.html的內容如下:

[email protected]:/home/cong/DockerDemo# docker exec -it 7b56 bash

[email protected]:/usr/share/nginx/html# cat index.html
<h1>Hello world</h1>
<h2>my greet</h2>

輸入exit退出容器後,檢視本機的index.html檔案

[email protected]:/home/cong/DockerDemo# cat index.html
<h1>Hello world</h1>
<h2>my greet</h2>

可以看出,當修改了容器裡面的index.html後,本機的index.html也同步被修改了。這就很好的解決了一個問題,當容器銷燬後,修改的內容被儲存在本機了。這對於將資料庫放入容器中非常有用。

  1. -v 選項通過指定一個目錄與容器裡的目錄對應起來,這兩個目錄使用: 分隔。如果容器裡目錄不存在,Docker會自動建立一個。
  2. 可以在目錄後面加上rw或才ro來指定容器內目錄的讀寫狀態。如下程式碼:
    [email protected]:/home/cong/DockerDemo# docker run -itd -p 5005:80 -v $PWD:/usr/share/nginx/html:ro nginx
    290e3eaa20816eb526213c731807a60bf8291e554f730bd5e4d0c98b2018e823
    [email protected]:/home/cong/DockerDemo# docker exec -it 290e bash
    [email protected]:/# cd /usr/share/nginx/html
    [email protected]:/usr/share/nginx/html# ls
    index.html
    
    [email protected]:/usr/share/nginx/html# apt-get update && apt-get install vim -y && apt-get install sudo
    
    [email protected]:/usr/share/nginx/html# sudo chmod 777 index.html
    chmod: changing permissions of 'index.html': Read-only file system
    

    可以看出,容器裡面的index.html檔案為只讀檔案,強行改許可權也不行。 

以Redis為例子

上面我們已基本掌握了volume的用法了,在本機上安裝好redis客戶端,執行 redis映象,測試成功,如下:

[email protected]:/home/cong/DockerDemo# apt-get install redis-tools -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
redis-tools is already the newest version (2:3.0.6-1).
0 upgraded, 0 newly installed, 0 to remove and 268 not upgraded.


[email protected]:/home/cong/DockerDemo# docker run -itd -p 6379:6379 redis
c56171cd4309148b0ca606208be33b2488e2bc3a7e93fee7dc1230003bb3f66f

[email protected]:/home/cong/DockerDemo# docker port dreamy_kare 6379
0.0.0.0:6379

[email protected]:/home/cong/DockerDemo# redis-cli -h localhost -p 6379
localhost:6379> set foo 1
OK
localhost:6379> get foo
"1"

localhost:6379> config get dir
1) "dir"
2) "/data"

[email protected]:/home/cong/DockerDemo# docker exec -it c561 bash

[email protected]:/data# ls
dump.rdb

接下來我們要將redis儲存資料的檔案使用卷給掛載出來,這樣即使這個容器銷燬了,資料依然儲存在本機中。進入容器裡面,發現dump.rdb檔案在/data這個路徑中。

[email protected]:/home/cong/DockerDemo# docker run -itd -p 6379:6379 -v $PWD:/data redis
1b25aef5f610668a210e5bfb92c0cd9bf3cf05260e8d3376a676d509463fe4f2

[email protected]:/home/cong/DockerDemo# docker exec -it 1b25 bash
[email protected]:/data# ls
index.html
[email protected]:/data# exit
exit

[email protected]:/home/cong/DockerDemo# redis-cli -h localhost -p 6379
localhost:6379> config get dir
1) "dir"
2) "/data"
localhost:6379> get foo 1
(error) ERR wrong number of arguments for 'get' command
localhost:6379> set foo 1
OK
localhost:6379> get foo
"1"
localhost:6379> exit

#等待一會兒後,才能看到dump.rdb檔案
[email protected]:/home/cong/DockerDemo# docker exec -it 1b25 bash
[email protected]:/data# ls
dump.rdb  index.html
[email protected]:/home/cong/DockerDemo# ls
dump.rdb  index.html

開啟另一個redis容器, 再將本地dump.rdb掛載進去

[email protected]:/home/cong/DockerDemo# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
1b25aef5f610        redis               "docker-entrypoint.s…"   12 minutes ago      Up 12 minutes       0.0.0.0:6379->6379/tcp   kind_curran
[email protected]:/home/cong/DockerDemo# docker run -itd -p 6380:6379 -v $PWD:/data redis
70ea150288c3bc382be82fac4b79ebc857c2818064ac66a808a9653a0dbbcd8d

[email protected]:/home/cong/DockerDemo# redis-cli -h localhost -p 6380
localhost:6380> get foo
"1"
localhost:6380> exit

[email protected]:/home/cong/DockerDemo# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
70ea150288c3        redis               "docker-entrypoint.s…"   26 seconds ago      Up 25 seconds       0.0.0.0:6380->6379/tcp   optimistic_curran
1b25aef5f610        redis               "docker-entrypoint.s…"   13 minutes ago      Up 13 minutes       0.0.0.0:6379->6379/tcp   kind_curran

直接去獲取foo,字串為1.  由此可以看出,redis的資料被持久化儲存在本機當前路徑下的dump.rdb檔案中。

相關連結