溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

發(fā)布時間:2020-07-21 05:17:01 來源:網(wǎng)絡 閱讀:487 作者:mb5cd21e691f31a 欄目:云計算

一、前言

當我們使用Docker創(chuàng)建一個mysql的container, 數(shù)據(jù)是存儲在container內的.
如果有一天不小心執(zhí)行了docker rm $(docker ps -aq)刪除所有container. 那么mysql里的數(shù)據(jù)也會被刪掉, 這是不安全的.
我們需要將數(shù)據(jù)持久化, 存儲在container外部. 即使刪除container也不會刪除原有的數(shù)據(jù).

二、容器的缺陷

容器中的數(shù)據(jù)可以存儲在容器層。但是將數(shù)據(jù)存放在容器層存在以下問題:
1.數(shù)據(jù)不是持久化。意思是如果容器刪除了,這些數(shù)據(jù)也就沒了
2.主機上的其它進程不方便訪問這些數(shù)據(jù)
3.對這些數(shù)據(jù)的I/O會經(jīng)過存儲驅動,然后到達主機,引入了一層間接層,因此性能會有所下降

三、data volume有兩種掛載方式:

1)bind mount(用戶管理):將宿主機上的某個目錄或文件(不可以是沒有格式化的磁盤文件),掛載到容器中,默認在容器內對此目錄是有讀寫權限的,如果只需要向容器內添加文件,不希望覆蓋目錄,需要注意源文件必須存在,否則會被當做一個目錄bind mount給容器。
2)docker manager volume(docker自動管理):不需要指定源文件,只需要指定mount point(掛載點)。把容器里面的目錄映射到了本地。
這種方式相比bind mount 缺點是無法限制對容器里邊目錄或文件的權限。

使用第二種掛載方式,-v 掛載時,不指定源文件位置,則默認掛載的路徑是:

[root@sqm-docker01 _data]# pwd
/var/lib/docker/volumes/dd173640edd5b0205bb02f3c4139647be12528b38289b9f93f18123a6b1266a8/_data
#當有目錄掛載時,默認在/var/lib/docker/volumes/下會生成一串hash值,hash值下有一個_data的目錄,容器內映射的文件就在此路徑下。

四、Storage Driver

數(shù)據(jù)存儲方式

Centos7版本的docker,Storage Driver(數(shù)據(jù)存儲方式)為:overlay2 ,Backing Filesystem(文件系統(tǒng)類型): xfs

可使用 “docker inspect 容器名稱” 來查看數(shù)據(jù)存儲方式

五、Data Volume

(Bind mount)

持久化存儲:本質上是DockerHost文件系統(tǒng)中的目錄或文件,能夠直接被Mount到容器的文件系統(tǒng)中。在運行容器時,可通過-v實現(xiàn)。

特點:
**1. Data Volume是目錄或文件,不能是沒有格式化的磁盤(塊設備)。

  1. 容器可以讀寫volume中的數(shù)據(jù)。
  2. Volume數(shù)據(jù)可以永久保存,即使使用它的容器已經(jīng)被銷毀。**

小實驗:

運行一個nginx服務,做數(shù)據(jù)持久化

(1)Data Volume是目錄或文件,不能是沒有格式化的磁盤(塊設備)。

[root@docker01 ~]# mkdir html
//創(chuàng)建測試目錄
[root@docker01 ~]# cd html/
[root@docker01 html]# echo "This is a testfile in dockerHost." > index.html
//創(chuàng)建測試網(wǎng)頁
[root@docker01 ~]# docker run -itd --name testweb -v /root/html/:/usr/share/nginx/html nginx:latest
//運行一個nginx容器,并掛載目錄
[root@docker01 ~]# docker inspect testweb

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# curl 172.17.0.3
Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

注意:dockerhost上需要被掛載的源文件或目錄,必須是已經(jīng)存在,否則,會被當作一個目錄掛載到容器中。

(2)容器可以讀寫volume中的數(shù)據(jù)。

[root@docker01 ~]# docker exec  -it testweb  /bin/bash
root@ef12d312a94e:/# cd /usr/share/nginx/html/
root@ef12d312a94e:/usr/share/nginx/html# echo "update" > index.html
//容器中更新網(wǎng)頁
root@ef12d312a94e:/usr/share/nginx/html# exit
[root@docker01 ~]# cat html/index.html
//可以看到宿主目錄的掛載目錄也更新了

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

(3)Volume數(shù)據(jù)可以永久保存,即使,使用它的容器已經(jīng)被銷毀,也可以通過宿主機的掛在目錄重新啟動一個容器掛載這個目錄進行訪問。

[root@docker01 ~]# docker ps -a -q |xargs docker rm -f
//刪除所有容器
Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# cat html/index.html
//容器刪除之后,宿主機的測試網(wǎng)頁也在

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# docker run  -itd --name t1  -P -v  /root/html/:/usr/share/nginx/html nginx:latest
//基于測試網(wǎng)頁創(chuàng)建一個容器
[root@docker01 ~]# docker ps

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# curl 127.0.0.1:32768
//訪問一下

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# echo "update-new" > html/index.html
//再次更新測試網(wǎng)頁
[root@docker01 ~]# curl 127.0.0.1:32768
//在宿主機更新測試網(wǎng)頁,剛剛創(chuàng)建的容器的測試網(wǎng)頁也會更新

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

(5)默認掛載到容器內的文件,容器是有讀寫權限。可以在運行容器是-v 后邊加“:ro”限制容器的寫入權限

[root@docker01 ~]# docker run  -itd --name t2 -P  -v  /root/html/:/usr/share/nginx/html:ro  nginx:latest
//創(chuàng)建容器設置指讀權限
[root@docker01 ~]# docker exec -it t2 /bin/bash
//進入容器
root@4739c0f5d970:/# cd /usr/share/nginx/html
root@4739c0f5d970:/usr/share/nginx/html# echo 1234 > index.html
//修改測試網(wǎng)頁(失敗,因為是只讀的)

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# echo 654321 > html/index.html 
//宿主機可以更改
[root@docker01 ~]# curl 127.0.0.1:32768

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

(6)并且還可以掛載單獨的文件到容器內部,一般他的使用場景是:如果不想對整個目錄進行覆蓋,而只希望添加某個文件,就可以使用掛載單個文件。
<1>測試1

 [root@docker01 ~]# docker run -itd --name v6 -P -v /root/html/index.html:/usr/share/nginx/html/index.html nginx:latest
[root@docker01 ~]# docker ps

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# curl 127.0.0.1:32770
Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

<1>測試2

[root@docker01 ~]#  echo test > test.html
[root@docker01 ~]# docker run -itd --name t8 -P -v /root/test.html:/usr/share/nginx/html/test.html nginx:latest

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# curl 127.0.0.1:32772/test.html

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

六,Docker Manager Volume

會自動在宿主機生成目錄,所以在掛載目錄的時候只用寫容器中的目錄。
特性和上邊的bind mount基本一樣

[root@docker01 ~]# docker run -itd --name t1 -P  -v /usr/share/nginx/html nginx:latest
[root@docker01 ~]# docker ps

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# docker inspect t1
Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 _data]# cd /var/lib/docker/volumes/17c50a065a6b10ccd01ca1ce8091fdf6282dc9dcb77a0f6695906257ecc03a63/_data
[root@docker01 _data]# echo "this is a testfile" > index.html
[root@docker01 _data]# docker ps

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 _data]# curl 127.0.0.1:32777

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 _data]# docker volume ls
Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 _data]# docker rm t1 -f
[root@docker01 _data]# cat index.html

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

1.刪除容器的操作,默認不會對dockerhost上的源文件操作,如果想要在刪除容器時把源文件也刪除,可以在刪除容器時添加-v選項(一般不推薦使用這種方式,因為文件有可能被其他容器使用)

[root@docker01 _data]# docker run -itd --name t2 -P  -v /usr/share/nginx/html nginx:latest
[root@docker01 ~]# docker inspect t2

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# cd /var/lib/docker/volumes/2781dbfdc673fc7d149dc4f6217ef277fe72e05ba2e20fcebb617afe97eccb30/_data
[root@docker01 _data]# docker rm -v t2 -f
t2
[root@docker01 _data]# ls

七,容器與容器的數(shù)據(jù)共享

Volume container:給其他容器提供volume存儲卷的容器。并且它可以提供bind mount,也可以提供docker manager volume。

創(chuàng)建一個vc_data容器

[root@docker01 ~]# docker create --name vc_data  -v ~/html:/usr/share/nginx/html  -v /other/useful/tools busybox
[root@docker01 ~]# docker inspect vc_data

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# docker run -itd --name t3 -P  --volumes-from vc_data nginx:latest
[root@docker01 ~]# docker ps

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

[root@docker01 ~]# curl 127.0.0.1:32779
Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

八,容器的跨主機數(shù)據(jù)共享

實驗環(huán)境

docker01 docker02
httpd nfs

要求:docker01和docker02的主目錄,是一樣的。

準備工作

[root@localhost ~]# hostnamectl set-hostname nfs
[root@localhost ~]# hostnamectl set-hostname docker01
[root@localhost ~]# hostnamectl set-hostname docker02

nfs操作

[root@localhost ~]# yum -y install nfs-utils
//下載nfs服務

[root@nfs ~]# mkdir /datashare
//創(chuàng)建共享目錄

[root@nfs ~]# vim /etc/exports
//設置權限如下
/datashare *(rw,sync,no_root_squash)

開啟各項服務

[root@nfs ~]# systemctl start rpcbind
[root@nfs ~]# systemctl enable rpcbind
[root@nfs ~]# systemctl start nfs-server
[root@nfs ~]# systemctl enable nfs-server

docker01和docker02測試nfs

[root@docker01 htdocs]# showmount -e 192.168.1.20
[root@docker02 htdocs]# showmount -e 192.168.1.20

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享
docker01的操作

[root@docker02 ~]# mkdir /xxx
[root@docker01 ~]# mount  -t nfs 192.168.1.10:/datashare /xxx
//掛載nfs上的共享目錄
[root@docker01 ~]# mount | tail -1
//查看是否掛載

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享
nfs創(chuàng)建測試文件

[root@nfs ~]# cd datashare/
[root@nfs datashare]# vim index.html
<div id="datetime">
    <script>
        setInterval("document.getElementById('datetime').innerHTML=new Date().toLocaleString();", 1000);
    </script>
</div>
xgp666

docker01查看一下
Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享
docker02的操作與docker01上一樣
這里先不考慮將代碼寫入鏡像,先以這種方式,分別在docker01和docker02部署httpd服務

[root@docker01 ~]# docker run -itd --name bdqn-web1 -P -v /xxx/:/usr/local/apache2/htdocs httpd:latest 
[root@docker02 ~]# docker run -itd --name bdqn-web2 -P -v /xxx/:/usr/local/apache2/htdocs httpd:latest
[root@docker01 ~]# docker ps 
//查看端口
0.0.0.0:32775->80/tcp   bdqn-web
[root@docker02 ~]# docker ps
//查看端口
0.0.0.0:32769->80/tcp   bdqn-web2

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

此時,用瀏覽器訪問,兩個WEB服務的主界面是一樣。但如果,NFS服務器上的源文件丟失,
則兩個web服務都會異常。

想辦法將元數(shù)據(jù)寫入鏡像內,在基于鏡像創(chuàng)建一個vc_data容器,這里因為沒有接觸到docker-compose和docker-swarm等docker編排工具,所以需手動創(chuàng)建鏡像!

nfs操作

[root@nfs datashare]# echo xgp666 > index.html 
//更改測試文件

docker02操作

[root@docker02 ~]# cd /xxx/
[root@docker02 xxx]# vim Dockerfile
//編寫Dockerfile
[root@docker02 xxx]# cat Dockerfile 
FROM busybox
ADD index.html /usr/local/apache2/htdocs/index.html
VOLUME /usr/local/apache2/htdocs

創(chuàng)建鏡像并運行一個容器

[root@docker02 xxx]# docker build -t back_data .
//基于Dockerfile創(chuàng)建鏡像
[root@docker02 xxx]# docker create --name back_container1  back_data:latest 
//基于剛剛創(chuàng)建的鏡像創(chuàng)建容器

運行容器,并導出鏡像

[root@docker02 xxx]# docker run -itd --name bdqn-web3 -P  --volumes-from  back_container1 httpd:latest 
//運行一臺容器
[root@docker02 xxx]# docker save > back_data.tar back_data:latest
//導出鏡像,因為是在共享目錄所以docker01也可以看到

docker01

[root@docker01 xxx]# docker load -i back_data.tar 
//去共享目錄,導入鏡像
[root@docker01 xxx]# docker  create --name back_container2  back_data:latest
//基于剛剛創(chuàng)建的鏡像運行容器
[root@docker01 xxx]# docker run  -itd --name bdqn-web4 -P  --volumes-from  back_container2 httpd:latest
//運行一臺容器

瀏覽器訪問

[root@docker01 ~]# docker ps 
//查看端口
 0.0.0.0:32776->80/tcp   bdqn-web4
[root@docker02 ~]# docker ps
//查看端口
0.0.0.0:32770->80/tcp   bdqn-web3

Docker數(shù)據(jù)持久化和容器與容器的數(shù)據(jù)共享

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI