五、容器資料卷
容器資料卷
什麼是容器資料卷
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" } ]
測試容器和宿主機之間資料共享:可以發現,在容器中,建立的會在宿主機中看到!
測試容器停止退出後,主機修改資料是否會同步!
-
停止容器
-
在宿主機上修改檔案,增加些內容
-
啟動剛才停止的容器
-
然後檢視對應的檔案,發現數據依舊同步!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
得出結論:
容器之間配置資訊的傳遞,資料卷的生命週期一直持續到沒有容器使用它為止。
儲存在本機的檔案則會一直保留!