容器資料卷

LanceYa發表於2021-07-12

什麼是容器資料卷

docker的理念回顧
將應用和環境打包成一個映象!
資料?如果資料都在容器中,那麼我們容器刪除,資料就會丟失!需求:資料可以持久化
例如MySQL:容器刪了,資料丟失!需求:MySQL資料可以儲存在本地!

容器之間可以有一個資料共享的技術!Docker容器中產生的資料,同步到本地!

這就是卷技術!目錄掛在,將我們容器內的目錄,掛載到Linux上!

容器資料卷

總結一句話:容器的持久化和同步操作!容器間也是可以資料共享的

使用資料卷

方式一:直接使用命令掛載 -v

$ docker run -it --name="容器名" -v 主機內目錄:容器內目錄 -p 主機埠:容器內埠 映象名

# 將容器中的/home目錄掛載到宿主機的~/File/centos_test目錄下,內部和外部的檔案都會互相自動同步
$ docker run -it -v ~/File/centos_test:/home centos /bin/bash

檢視一下容器的資訊

$ docker inspect 容器id

容器資料卷

測試檔案同步步驟和效果
容器資料卷

再次進行測試
1.停止容器
2.宿主機上修改檔案
3.啟動容器
4.容器內的資料依舊是同步的
容器資料卷

好處:我們之後修改只需要在本地修改即可,容器內會自動同步。

實戰測試:安裝MySQL

問題:MySQL的持久化問題!

# 獲取映象
$ docker pull mysql

# 執行容器,需要做資料掛載!安裝啟動mysql需要配置密碼的,這是要注意的點!
# 官方測試:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

# 啟動
# -d 後臺執行
# -p 埠對映
# -v 卷掛載
# -e 環境配置
# --name 容器名
$ docker run -d -p 3310:3306 -v ~/File/docker_mysql/conf:/etc/mysql/conf.d -v ~/File/docker_mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql

啟動成之後外部使用navicate測試,navicate連線到伺服器的3310,伺服器的3310和容器的3306對映,這個時候我們就可以連線上了!

容器資料卷
在本地建立一個資料庫

容器資料卷

容器資料卷

這是測試一下,將MySQL的容器刪除,發現掛載到本地的資料卷在本地還儲存著。

容器資料卷

具名掛載和匿名掛載

  • 匿名掛載
# -v 容器內路徑
$ docker run -d -p --name nginx -v /etc/nginx nginx
# 檢視所有卷的情況
$ docker volume ls
DRIVER              VOLUME NAME
local               a7ea06ddbf53d1e879f304470b4775abdf9e455d2fba0a589588a6f50ba22137
# 這裡發現,這種就是匿名掛載,我們在-v的時候,只寫了容器內的路徑,沒有寫容器外的路徑!
  • 具名掛載
# 通過 -v 卷名:容器內路徑
$ docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

$ docker volume ls

$ docker volume inspect 卷名

容器資料卷

所有docker容器內的卷,沒有指定目錄的情況下都是在/var/lib/docker/volumes/xxxx/_data

但是發現一個問題,mac中是沒有這個目錄的,可以通過 screen Library/Containers/com.docker.docker/Data/vms/0/tty(路徑後半部分可能會變)進入到 LinuxKit 虛擬機器內部,通過其他 linux 命令看到裡邊就是一個定製的 linux 系統,執行了dockerd, containerd 等後臺程式。注意可使用 Ctrl+A+D 快捷鍵退出 screen 視窗。
關於screen的更多具體命令可以看我關於screen的 Blog。

容器資料卷

進入之後可以看到實際的檔案是儲存在LinuxKit 虛擬機器內部,g.docker 在 mac os 或者 windows 上,都是基於特定的虛擬化技術執行linux 虛擬機器,並不共享宿主機核心。

容器資料卷

我們通過具名掛載可以方便的找到我們的一個卷,大多數情況下使用具名掛載

# 如何確定是具名掛載還是匿名掛載還是指定路徑掛載
-v 容器內路徑    # 匿名掛載
-v 卷名:容器內路徑    # 具名掛載
-v /宿主機路徑:容器內路徑    # 指定路徑掛載
  • 擴充

在後面加上ro或者是rw,改變讀寫許可權

# 一旦這個設定了容器許可權,容器對我們掛載出來的內容就限定了!
$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nignx:ro nginx

$ docker run -d -P --name nginx02 -v jumping-nginx:/etc/nignx:rw nginx

# 通過-v 容器內路徑:ro rw 改變讀寫許可權
# ro    readonly    只讀    只能通過宿主機操作,容器內無法改變
# rw    readwrite    可讀可寫

初識 Dockerfile

Dockerfile就是用來構建docker映象的構建檔案!命令指令碼。
通過這個指令碼可以生成映象,映象是一層一層的,指令碼是一個一個的命令,每個命令都是一層。

建立一個dockerfile
檔案中的內容,指令(大寫)引數

FROM centos

VOLUME ["volume01","volume02"]

CMD echo "-----end-----"
CMD /bin/bash

# 這裡的每個命令就是映象的一層
$ docker build -f ~/File/docker_test_volume/dockerfile1 -t hudu/centos:1.0 .

容器資料卷

啟動自己的映象測試

容器資料卷

這個卷一定和外部有一個同步的目錄!
1.通過命令檢視容器的具體資訊
2.看到掛載的卷在外部的具體的目錄

容器資料卷

容器資料卷

容器資料卷

容器資料卷
這種方式我們未來使用的十分多,因為我們通常會構建自己的映象!
假設構建映象時候沒有掛載卷,要手動映象掛載 -v 容器內路徑

資料卷容器

兩個MySQL同步資料

容器資料卷

啟動3個容器,通過我們剛才自己的寫映象啟動
Ctrl+P+Q,不關閉容器退出

$ docker run -it --name docker01 hudu/centos:1.0 /bin/bash

$ docker run -it --name docker02 --volumes-from docker01 hudu/centos:1.0

$ docker run -it --name docker03 --volumes-from docker01 hudu/centos:1.0

容器資料卷

容器資料卷

容器資料卷

測試:刪除docker01,檢視一下,docker02和docker03都還有這個檔案。

通過 docker inspect 容器id可以發現,其實他們都是對映到了宿主機的相同的目錄下。
容器資料卷

多個MySQL實現資料共享

$ run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql01 mysql

$ run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name=mysql02 --volumes-from mysql01 mysql

實現兩個容器資料共享同步

結論,容器之間可以配置資訊傳遞,資料卷容器的生命週期一直持續到沒有容器使用為止。

但是一旦持久化到了本地,本地的資料是不會刪除的。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章