什麼是容器資料卷
思考一個問題,我們為什麼要使用 Docker?
主要是為了可以將應用和環境進行打包成映象,一鍵部署。
再思考一個問題,容器之間是相互隔離的,如果我們在容器中部署類似 mysql 這樣的元件,如果把該容器刪除掉,那麼 mysql 的資料也會被刪掉了,資料丟失了,我們們刪庫跑路真刺激
事實上,我們可不能讓這麼有風險的事情存在,因此有了卷技術
卷技術是容器之間可以共享資料的技術,Docker 容器中產生資料,將資料同步到本地
例如我們們將 Docker mysql 容器中的 /usr/mysql 目錄掛載到宿主機的/home/mysql 目錄
使用卷技術,我們就可以讓資料得以持久化
實際上操作起來就是掛載目錄,將 Docker 容器裡面的目錄,掛載到宿主機上的某個目錄,這就可以將資料持久化和同步了, Docker 容器間的資料共享仍然是這樣做的
我們們如何使用資料卷?
啟動容器的時候,直接使用 -v
命令就可以進行資料卷的掛載
docker run -it -v 宿主機目錄:容器目錄 映象名
我們來嘗試啟動一個 nginx,並將宿主機的 /home/test
目錄和 nginx 的/home
目錄掛載起來
#docker run -d -v /home/test:/home nginx
此時我們在宿主機的/home/test
目錄下建一個 test.txt
並且寫入一些字串,再檢視容器的/home
目錄 是否有 test.txt
# 宿主機
root@iZuf66y3tuzn4wp3h02t7pZ:/home/test# echo xiaomotong >> test.txt
# 容器
root@c8405d03a9a1:/home# ls
test.txt
root@c8405d03a9a1:/home# cat test.txt
xiaomotong
我們在容器的/home
目錄下建立一個test2.txt 檔案,同樣寫入一些字串,再檢視 宿主機的 /home/test 目錄是否有 test2.txt
# 容器
root@c8405d03a9a1:/home# echo xiaozhu >> test2.txt
# 宿主機
root@iZuf66y3tuzn4wp3h02t7pZ:/home/test# ls
test2.txt test.txt
root@iZuf66y3tuzn4wp3h02t7pZ:/home/test# cat test2.txt
xiaozhu
檢視上述效果,果然是掛載 ok,資料確實同步了,哪怕是我們把 docker 容器刪除掉,資料也不會丟失
docker inspect 容器ID ,檢視一下我們建立的容器的掛載情況
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c8405d03a9a1 nginx "/docker-entrypoint.…" 9 minutes ago Up 9 minutes 80/tcp nginx2
# docker inspect c8405d03a9a1
[
...
"Mounts": [
{
"Type": "bind",
"Source": "/home/test",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...
]
使用容器資料卷的便利之處:
以後我們只需要修改宿主機裡面的目錄和檔案,即可和容器中的指定目錄保持同步
mysql 實戰一波
我們們再來一個實戰,我們一起來看看資料卷如何使用
下載 5.7 版本的 mysql docker 映象,也可以下載其他版本,這個沒有關係
# docker pull mysql:5.7
5.7: Pulling from library/mysql # 5.7版本
33847f680f63: Already exists # 本層級已經之前已經下載過了
5cb67864e624: Pull complete
1a2b594783f5: Pull complete
b30e406dd925: Pull complete
48901e306e4c: Pull complete
603d2b7147fd: Pull complete
802aa684c1c4: Pull complete
5b5a19178915: Pull complete
f9ce7411c6e4: Pull complete
f51f6977d9b2: Pull complete
aeb6b16ce012: Pull complete
Digest: sha256:be70d18aedc37927293e7947c8de41ae6490ecd4c79df1db40d1b5b5af7d9596
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7 # 真實的mysql 映象地址
啟動映象,直接使用 -v 來掛載目錄
使用方式
docker run -it -v 主機目錄:容器的目錄
開始啟動映象
我們們可以參考 dockerhub 上的文件
# docker run -d -p 8888:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql1 mysql:5.7
23c31b285804cd95130e36ad40d3c07239fe744845ca464b9c80e42c84848bfb
# 解釋一下上述命令
-d 後臺執行
-p 宿主機埠:容器埠 埠對映
-v 宿主機目錄:容器目錄 掛載卷
-e 設定環境變數
--name 設定啟動容器的名字
我們們可以通過window 的 workbench 來遠端連線一下 mysql
我的是雲伺服器,因此輸入雲伺服器的地址,埠填入 8888 埠
預設使用者名稱是 root , 密碼是 123456
測試連線 ok ,我們可以來進入資料庫
我們們在 workbench 中新建一個資料庫
看看這個資料庫是否會在我們的宿主機上面有同步
檢視我們掛載宿主機的目錄 /home/mysql/data
root@iZuf66y3tuzn4wp3h02t7pZ:/home/mysql/data#ls
auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys
ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem test
果然是有的,再次 nice,這就達到了資料持久化的效果,這就是我們們從認識資料捲到使用資料卷的一個簡單流程,我們們可以慢慢的深入下去
具名掛載和匿名掛載
以啟動一個 nginx 為例子:
具名掛載:
# docker run -d --name nginx3 -v JM:/etc/nginx:rw nginx
匿名掛載:
# docker run -d --name nginx3 -v /etc/nginx:rw nginx
上述的 rw
也可以寫成ro
- rw
可讀可寫
- ro
只讀,只能宿主機才能寫
檢視資料掛載卷
root@iZuf66y3tuzn4wp3h02t7pZ:/home/mysql# docker volume ls
DRIVER VOLUME NAME
local JM # 具名掛載 ,下面的為匿名掛載
local bd2b9ea00eb7d95bb69bdd39a63769ce906a0bb17fae2e29b726f9b92cbcb008
local d67ba49109dfd654173b8d05f8602b99751066483a357c654b63ba46ec72d5c0
檢視掛載具體目錄
l# docker volume inspect JM
[
{
"CreatedAt": "2021-08-04T23:48:05+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/JM/_data",
"Name": "JM",
"Options": null,
"Scope": "local"
}
]
檢視該目錄下的掛載檔案,是否是和 nginx 容器中的 /etc/nginx
目錄下內容一致
root@iZuf66y3tuzn4wp3h02t7pZ:/var/lib/docker/volumes/JM/_data# ll
total 36
drwxr-xr-x 3 root root 4096 Aug 4 23:48 ./
drwx-----x 3 root root 4096 Aug 4 23:48 ../
drwxr-xr-x 2 root root 4096 Aug 4 23:48 conf.d/
-rw-r--r-- 1 root root 1007 Jul 6 22:59 fastcgi_params
-rw-r--r-- 1 root root 5290 Jul 6 22:59 mime.types
lrwxrwxrwx 1 root root 22 Jul 6 23:11 modules -> /usr/lib/nginx/modules
-rw-r--r-- 1 root root 648 Jul 6 23:11 nginx.conf
-rw-r--r-- 1 root root 636 Jul 6 22:59 scgi_params
-rw-r--r-- 1 root root 664 Jul 6 22:59 uwsgi_params
果然一毛一樣,nice
再來看看 docker 預設的掛載目錄 /var/lib/docker/volumes
,我們可以看到每一個匿名掛載,和具名掛載的目錄和資料都存放於此
root@iZuf66y3tuzn4wp3h02t7pZ:/var/lib/docker/volumes# ll
total 44
drwx-----x 5 root root 4096 Aug 4 23:48 ./
drwx--x--x 13 root root 4096 Aug 3 22:58 ../
brw------- 1 root root 252, 1 Aug 3 22:58 backingFsBlockDev
drwx-----x 3 root root 4096 Aug 1 21:36 bd2b9ea00eb7d95bb69bdd39a63769ce906a0bb17fae2e29b726f9b92cbcb008/
drwx-----x 3 root root 4096 Aug 3 23:32 d67ba49109dfd654173b8d05f8602b99751066483a357c654b63ba46ec72d5c0/
drwx-----x 3 root root 4096 Aug 4 23:48 JM/
-rw------- 1 root root 32768 Aug 4 23:48 metadata.db
我們來小結一下
- 指定掛載
-v 宿主機的絕對路徑:容器路徑
- 具名掛載
-v 卷名:容器路徑
- 匿名掛載
-v 容器路徑
參考資料:
歡迎點贊,關注,收藏
朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力
好了,本次就到這裡
技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。
我是小魔童哪吒,歡迎點贊關注收藏,下次見~
本作品採用《CC 協議》,轉載必須註明作者和本文連結