Docker系列之五:Volume 卷的使用——以Redis為例
阿新 • • 發佈:2018-12-19
簡介
卷在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也同步被修改了。這就很好的解決了一個問題,當容器銷燬後,修改的內容被儲存在本機了。這對於將資料庫放入容器中非常有用。
- -v 選項通過指定一個目錄與容器裡的目錄對應起來,這兩個目錄使用: 分隔。如果容器裡目錄不存在,Docker會自動建立一個。
- 可以在目錄後面加上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檔案中。