1. 程式人生 > 其它 >五、容器資料卷

五、容器資料卷

容器資料卷

什麼是容器資料卷

docker的理念回顧:

將應用和執行的環境打包形成容器執行,執行可以伴隨著容器,但是我們對於資料的要求,是希望能夠 持久化的!

就好比,你安裝一個MySQL,結果你把容器刪了,就相當於刪庫跑路了,這TM也太扯了吧!

所以我們希望容器之間有可能可以共享資料,Docker容器產生的資料,如果不通過docker commit 生成新的映象,使得資料作為映象的一部分儲存下來,那麼當容器刪除後,資料自然也就沒有了!這樣是行 不通的!

為了能儲存資料在Docker中我們就可以使用卷!讓資料掛載到我們本地!這樣資料就不會因為容器刪除而丟失了!

作用:

卷就是目錄或者檔案,存在一個或者多個容器中,由docker掛載到容器,但不屬於聯合檔案系統,因此能夠繞過 Union File System , 提供一些用於持續儲存或共享資料的特性:

卷的設計目的就是資料的持久化,完全獨立於容器的生存週期,因此Docker不會在容器刪除時刪除其掛載的資料卷。

特點:

1、資料卷可在容器之間共享或重用資料

2、卷中的更改可以直接生效

3、資料卷中的更改不會包含在映象的更新中

4、資料卷的生命週期一直持續到沒有容器使用它為止

所以:總結一句話: 就是容器的持久化,以及容器間的繼承和資料共享!

使用資料卷

方式一:容器中直接使用命令來新增

掛載

# 命令
docker run -it -v 宿主機絕對路徑目錄:容器內目錄 映象

#測試
[root@wenhanlocalhost ~]# docker run -it -v /home/ceshi:/home centos /bin/bash

#啟動起來時候我們可以通過docker inspect  容器id    檢視容器的詳細資訊
"Mounts": [掛載   -v   卷
{
"Type": "bind",
"Source": "/home/ceshi",   主機內地址
"Destination": "/home",docker 容器內的地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]

測試容器和宿主機之間資料共享:可以發現,在容器中,建立的會在宿主機中看到!

測試容器停止退出後,主機修改資料是否會同步!

  1. 停止容器

  2. 在宿主機上修改檔案,增加些內容

  3. 啟動剛才停止的容器

  4. 然後檢視對應的檔案,發現數據依舊同步!ok

實戰:安裝mysql

思考:mysql 資料持久化的問題!

# 1、搜尋映象
[root@kuangshen ~]# docker search mysql
NAME	DESCRIPTION
STARS
mysql	MySQL is a widely used, open-source
relation…	9488

# 2、拉取映象
[root@kuangshen ~]# docker pull mysql:5.7
5.7: Pulling from library/mysql
54fec2fa59d0: Already exists
bcc6c6145912: Pull complete
951c3d959c9d: Pull complete
05de4d0e206e: Pull complete
319f0394ef42: Pull complete
d9185034607b: Pull complete
013a9c64dadc: Pull complete
e745b3361626: Pull complete
03145d87b451: Pull complete
3991a6b182ee: Pull complete
62335de06f7d: Pull complete
Digest:
sha256:e821ca8cc7a44d354486f30c6a193ec6b70a4eed8c8362aeede4e9b8d74b8ebb
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7

# 3、啟動容器 -e 環境變數!
# 注意: mysql的資料應該不丟失!先體驗下 -v 掛載卷! 參考官方文件
[root@kuangshen home]# docker run -d -p 3310:3306 -v
/home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e
MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
4763fa5c68c4323688102f57938fb10996a0fb902d2812349286529f9378f16c

# 4、使用本地的sqlyog連線測試一下 3310

# 5、檢視本地的 /home/mysql 目錄
[root@kuangshen data]# pwd
/home/mysql/data
[root@kuangshen data]# ls
.. ... . test # 可以看到我們剛剛建立的mysql資料庫在本地儲存著

# 6、刪除mysql容器
[root@kuangshen data]# docker rm -f mysql01 # 刪除容器,然後發現遠端連線失敗!
mysql01
[root@kuangshen data]# ls
.. ... . test	# 可以看到我們剛剛建立的mysql資料庫在本地儲存著

通過Docker File 來新增(瞭解)

DockerFile 是用來構建Docker映象的構建檔案,是由一些列命令和引數構成的指令碼。我們在這裡,先體驗下,後面我們會詳細講解 DockerFile !

測試:

# 1、我們在宿主機 /home 目錄下新建一個 docker-test-volume資料夾
[root@kuangshen home]# mkdir docker-test-volume

# 說明:在編寫DockerFile檔案中使用 VOLUME 指令來給映象新增一個或多個數據卷
VOLUME["/dataVolumeContainer1","/dataVolumeContainer2","/dataVolumeContainer
3"]
# 出於可移植和分享的考慮,我們之前使用的 -v 主機目錄:容器目錄 這種方式不能夠直接在
DockerFile中實現。
# 由於宿主機目錄是依賴於特定宿主機的,並不能夠保證在所有宿主機上都存在這樣的特定目錄.

# 2、編寫DockerFile檔案
[root@kuangshen docker-test-volume]# pwd
/home/docker-test-volume
[root@kuangshen docker-test-volume]# vim dockerfile1
[root@kuangshen docker-test-volume]# cat dockerfile1
# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "-------end	"
CMD /bin/bash

# 3、build後生成映象,獲得一個新映象 kuangshen/centos
docker build -f /home/docker-test-volume/dockerfile1 -t kuangshen/centos . #
注意最後有個.
# 4、啟動容器
[root@kuangshen docker-test-volume]# docker run -it 0e97e1891a3d /bin/bash #
啟動容器

[root@f5824970eefc /]# ls -l
total 56
lrwxrwxrwx	1 root root	7 May 11 2019 bin -> usr/bin
drwxr-xr-x	2 root root 4096 May 11 11:55 dataVolumeContainer1	# 資料卷目錄
drwxr-xr-x	2 root root 4096 May 11 11:55 dataVolumeContainer2	# 資料卷目錄
drwxr-xr-x	5 root root 360 May 11 11:55 dev
drwxr-xr-x	1 root root 4096 May 11 11:55 etc
drwxr-xr-x	2 root root 4096 May 11 2019 home
.....

# 問題:通過上述步驟,容器內的卷目錄地址就已經知道了,但是對應的主機目錄地址在哪裡呢?

# 5、我們在資料卷中新建一個檔案
[root@f5824970eefc dataVolumeContainer1]# pwd
/dataVolumeContainer1
[root@f5824970eefc dataVolumeContainer1]# touch container.txt
[root@f5824970eefc dataVolumeContainer1]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 11 11:58 container.txt

# 6、檢視下這個容器的資訊
[root@kuangshen ~]# docker inspect 0e97e1891a3d
# 檢視輸出的Volumes
"Volumes": {
"/dataVolumeContainer1": {},
"/dataVolumeContainer2": {}
},

# 7、這個卷在主機對應的預設位置

注意:如果訪問出現了 cannot open directory: Permission denied

解決辦法:在掛載目錄後多加一個 --privileged=true引數即可

匿名和具名掛載

# 匿名掛載
-v 容器內路徑
docker run -d -P --name nginx01 -v /etc/nginx nginx

# 匿名掛載的缺點,就是不好維護,通常使用命令 docker volume維護
docker volume ls

# 具名掛載
-v 卷名:/容器內路徑
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx nginx

# 檢視掛載的路徑
[root@kuangshen ~]# docker volume inspect nginxconfig
[
{
"CreatedAt": "2020-05-13T17:23:00+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginxconfig/_data",
"Name": "nginxconfig",
"Options": null,
"Scope": "local"
}
]

# 怎麼判斷掛載的是卷名而不是本機目錄名?
不是/開始就是卷名,是/開始就是目錄名

# 改變檔案的讀寫許可權
# ro: readonly
# rw: readwrite
# 指定容器對我們掛載出來的內容的讀寫許可權
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx:rw nginx

資料卷容器

命名的容器掛載資料卷,其他容器通過掛載這個(父容器)實現資料共享,掛載資料卷的容器,稱之為 資料卷容器。

我們使用上一步的映象:kuangshen/centos 為模板,執行容器 docker01,docker02,docker03,他們都會具有容器卷

"/dataVolumeContainer1"
"/dataVolumeContainer2"

我們來測試下,容器間傳遞共享

1、先啟動一個父容器docker01,然後在dataVolumeContainer2新增檔案

退出不停止:ctrl+P+Q

2、建立docker02,docker03 讓他們繼承docker01 --volumes-from

[root@kuangshen docker-test-volume]# docker run -it --name docker02 --
volumes-from docker01 kuangshen/centos
[root@ea4c82779077 /]# cd /dataVolumeContainer2
[root@ea4c82779077 dataVolumeContainer2]# ls
docker01.txt
[root@95164598b306 dataVolumeContainer2]# touch docker02.txt
[root@95164598b306 dataVolumeContainer2]# ls
docker01.txt docker02.txt

[root@kuangshen docker-test-volume]# docker run -it --name docker03 --
volumes-from docker01 kuangshen/centos
[root@ea4c82779077 /]# cd /dataVolumeContainer2
[root@ea4c82779077 dataVolumeContainer2]# ls
docker01.txt docker02.txt
[root@95164598b306 dataVolumeContainer2]# touch docker03.txt
[root@95164598b306 dataVolumeContainer2]# ls
docker01.txt docker02.txt docker03.txt

3、回到docker01發現可以看到 02 和 03 新增的共享檔案

[root@kuangshen docker-test-volume]# docker attach docker01
[root@799b6ea5db7c dataVolumeContainer2]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt
-rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt
-rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt

4、刪除docker01,docker02 修改後docker03還能不能訪問

[root@kuangshen docker-test-volume]# docker rm -f docker01
docker01
[root@kuangshen docker-test-volume]# docker attach docker02
[root@ea4c82779077 dataVolumeContainer2]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt
-rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt
-rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt
[root@ea4c82779077 dataVolumeContainer2]# touch docker02-update.txt
[root@ea4c82779077 dataVolumeContainer2]# ls -a
. .. docker01.txt docker02.txt docker02-update.txt docker03.txt
[root@ea4c82779077 dataVolumeContainer2]# Ctrl+P+Q 退出容器
[root@kuangshen docker-test-volume]# docker attach docker03
[root@95164598b306 dataVolumeContainer2]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt
-rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt
-rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt
-rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt

5、刪除docker02 ,docker03還能不能訪問

[root@kuangshen docker-test-volume]# docker ps
CONTAINER ID	IMAGE
95164598b306	kuangshen/centos
ea4c82779077	kuangshen/centos
[root@kuangshen docker-test-volume]# docker rm -f docker02
docker02
[root@kuangshen docker-test-volume]# docker attach docker03
[root@95164598b306 dataVolumeContainer2]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt
-rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt
-rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt
-rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt
[root@95164598b306 dataVolumeContainer2]# touch docker03-update.txt

6、新建docker04繼承docker03,然後再刪除docker03,看下是否可以訪問!

[root@2119f4f23a92 /]# cd dataVolumeContainer2
[root@2119f4f23a92 dataVolumeContainer2]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt
-rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt
-rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt
-rw-r--r-- 1 root root 0 May 11 13:32 docker03-update.txt
-rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt

# 檢視當前執行的容器
[root@kuangshen docker-test-volume]# docker ps
CONTAINER ID	IMAGE	NAMES
2119f4f23a92	kuangshen/centos	docker04
95164598b306	kuangshen/centos	docker03

# 繼續刪除docker03
[root@kuangshen docker-test-volume]# docker rm -f docker03
docker03
[root@kuangshen docker-test-volume]# docker attach docker04
[root@2119f4f23a92 dataVolumeContainer2]# ls -l
total 0
-rw-r--r-- 1 root root 0 May 11 13:20 docker01.txt
-rw-r--r-- 1 root root 0 May 11 13:22 docker02.txt
-rw-r--r-- 1 root root 0 May 11 13:29 docker02-update.txt
-rw-r--r-- 1 root root 0 May 11 13:32 docker03-update.txt
-rw-r--r-- 1 root root 0 May 11 13:24 docker03.txt

得出結論:

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

儲存在本機的檔案則會一直保留!

完結,撒花!