您好,登錄后才能下訂單哦!
當我們使用Docker創建一個mysql的container, 數據是存儲在container內的.
如果有一天不小心執行了docker rm $(docker ps -aq)刪除所有container. 那么mysql里的數據也會被刪掉, 這是不安全的.
我們需要將數據持久化, 存儲在container外部. 即使刪除container也不會刪除原有的數據.
容器中的數據可以存儲在容器層。但是將數據存放在容器層存在以下問題:
1.數據不是持久化。意思是如果容器刪除了,這些數據也就沒了
2.主機上的其它進程不方便訪問這些數據
3.對這些數據的I/O會經過存儲驅動,然后到達主機,引入了一層間接層,因此性能會有所下降
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的目錄,容器內映射的文件就在此路徑下。
數據存儲方式
Centos7版本的docker,Storage Driver(數據存儲方式)為:overlay2 ,Backing Filesystem(文件系統類型): xfs
可使用 “docker inspect 容器名稱” 來查看數據存儲方式
持久化存儲:本質上是DockerHost文件系統中的目錄或文件,能夠直接被Mount到容器的文件系統中。在運行容器時,可通過-v實現。
特點:
**1. Data Volume是目錄或文件,不能是沒有格式化的磁盤(塊設備)。
運行一個nginx服務,做數據持久化
(1)Data Volume是目錄或文件,不能是沒有格式化的磁盤(塊設備)。
[root@docker01 ~]# mkdir html
//創建測試目錄
[root@docker01 ~]# cd html/
[root@docker01 html]# echo "This is a testfile in dockerHost." > index.html
//創建測試網頁
[root@docker01 ~]# docker run -itd --name testweb -v /root/html/:/usr/share/nginx/html nginx:latest
//運行一個nginx容器,并掛載目錄
[root@docker01 ~]# docker inspect testweb
[root@docker01 ~]# curl 172.17.0.3
注意:dockerhost上需要被掛載的源文件或目錄,必須是已經存在,否則,會被當作一個目錄掛載到容器中。
(2)容器可以讀寫volume中的數據。
[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
//容器中更新網頁
root@ef12d312a94e:/usr/share/nginx/html# exit
[root@docker01 ~]# cat html/index.html
//可以看到宿主目錄的掛載目錄也更新了
(3)Volume數據可以永久保存,即使,使用它的容器已經被銷毀,也可以通過宿主機的掛在目錄重新啟動一個容器掛載這個目錄進行訪問。
[root@docker01 ~]# docker ps -a -q |xargs docker rm -f
//刪除所有容器
[root@docker01 ~]# cat html/index.html
//容器刪除之后,宿主機的測試網頁也在
[root@docker01 ~]# docker run -itd --name t1 -P -v /root/html/:/usr/share/nginx/html nginx:latest
//基于測試網頁創建一個容器
[root@docker01 ~]# docker ps
[root@docker01 ~]# curl 127.0.0.1:32768
//訪問一下
[root@docker01 ~]# echo "update-new" > html/index.html
//再次更新測試網頁
[root@docker01 ~]# curl 127.0.0.1:32768
//在宿主機更新測試網頁,剛剛創建的容器的測試網頁也會更新
(5)默認掛載到容器內的文件,容器是有讀寫權限。可以在運行容器是-v 后邊加“:ro”限制容器的寫入權限
[root@docker01 ~]# docker run -itd --name t2 -P -v /root/html/:/usr/share/nginx/html:ro nginx:latest
//創建容器設置指讀權限
[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
//修改測試網頁(失敗,因為是只讀的)
[root@docker01 ~]# echo 654321 > html/index.html
//宿主機可以更改
[root@docker01 ~]# curl 127.0.0.1:32768
(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
[root@docker01 ~]# curl 127.0.0.1:32770
<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
[root@docker01 ~]# curl 127.0.0.1:32772/test.html
會自動在宿主機生成目錄,所以在掛載目錄的時候只用寫容器中的目錄。
特性和上邊的bind mount基本一樣
[root@docker01 ~]# docker run -itd --name t1 -P -v /usr/share/nginx/html nginx:latest
[root@docker01 ~]# docker ps
[root@docker01 ~]# docker inspect t1
[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
[root@docker01 _data]# curl 127.0.0.1:32777
[root@docker01 _data]# docker volume ls
[root@docker01 _data]# docker rm t1 -f
[root@docker01 _data]# cat index.html
1.刪除容器的操作,默認不會對dockerhost上的源文件操作,如果想要在刪除容器時把源文件也刪除,可以在刪除容器時添加-v選項(一般不推薦使用這種方式,因為文件有可能被其他容器使用)
[root@docker01 _data]# docker run -itd --name t2 -P -v /usr/share/nginx/html nginx:latest
[root@docker01 ~]# docker inspect t2
[root@docker01 ~]# cd /var/lib/docker/volumes/2781dbfdc673fc7d149dc4f6217ef277fe72e05ba2e20fcebb617afe97eccb30/_data
[root@docker01 _data]# docker rm -v t2 -f
t2
[root@docker01 _data]# ls
Volume container:給其他容器提供volume存儲卷的容器。并且它可以提供bind mount,也可以提供docker manager volume。
創建一個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
[root@docker01 ~]# docker run -itd --name t3 -P --volumes-from vc_data nginx:latest
[root@docker01 ~]# docker ps
[root@docker01 ~]# curl 127.0.0.1:32779
實驗環境
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
//創建共享目錄
[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
docker01的操作
[root@docker02 ~]# mkdir /xxx
[root@docker01 ~]# mount -t nfs 192.168.1.10:/datashare /xxx
//掛載nfs上的共享目錄
[root@docker01 ~]# mount | tail -1
//查看是否掛載
nfs創建測試文件
[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查看一下
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
此時,用瀏覽器訪問,兩個WEB服務的主界面是一樣。但如果,NFS服務器上的源文件丟失,
則兩個web服務都會異常。
想辦法將元數據寫入鏡像內,在基于鏡像創建一個vc_data容器,這里因為沒有接觸到docker-compose和docker-swarm等docker編排工具,所以需手動創建鏡像!
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
創建鏡像并運行一個容器
[root@docker02 xxx]# docker build -t back_data .
//基于Dockerfile創建鏡像
[root@docker02 xxx]# docker create --name back_container1 back_data:latest
//基于剛剛創建的鏡像創建容器
運行容器,并導出鏡像
[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
//基于剛剛創建的鏡像運行容器
[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
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。