Docker之數據持久化

在瞭解Docker數據持久化以前,須要對Docker的存儲類型有一個簡單的瞭解,執行如下命令便可看出:html

[root@docker01 ~]# docker info     //查看Docker的詳細信息
Containers: 1                      //一共有幾個容器
 Running: 1                        //正在運行的有幾個容器
 Paused: 0                         //掛起、暫停的有幾個容器
 Stopped: 0                        //中止的有幾個容器
Images: 2                          //有幾個鏡像
Server Version: 18.09.0            //docker的版本信息
Storage Driver: overlay2           //存儲驅動類型爲overlay2
 Backing Filesystem: xfs           //支持的文件系統:xfs
 Supports d_type: true
 Native Overlay Diff: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local                                    //本地存儲    
 Network: bridge host macvlan null overlay       //支持的網絡類型
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
 seccomp
  Profile: default
Kernel Version: 3.10.0-514.el7.x86_64        //內核信息
Operating System: CentOS Linux 7 (Core)     //操做系統
OSType: linux                              //操做系統類型
Architecture: x86_64
CPUs: 4                                   //CPU個數
Total Memory: 3.686GiB                   //內存容量
Name: docker01
ID: X6ON:W73P:YWXD:NV7U:3C2J:RXH3:GNPO:SYIP:FF53:CNFN:HSN3:EZG2
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Registry Mirrors:      //採用的加速器信息
 https://weimtsj8.mirror.aliyuncs.com/
Live Restore Enabled: false
Product License: Community Engine

在docker中實現數據持久化有兩種方式:Bind mount和Docker Manager Volume。linux

Bind mount和Docker Manager Volume的區別:nginx

Bind mount數據持久化的方式,若是是掛載本地的一個目錄,則容器內對應的目錄下的內容會被本地的目錄覆蓋掉,而Docker Manager Volume這種方式則不會,無論哪一種方式的持久化,在容器被銷燬後,本地的數據都不會丟失。
使用「-v」選項掛載時,Bind mount明確指定了要掛載docker host本地的某個目錄到容器中,而Docker Manager Volume則只指定了要對容器內的某個目錄進行掛載,而掛載的是docker host本地的哪一個目錄,則是由docker來管理的。web

一、Bind mount——數據卷容器:--volumes-from方式實現數據持久化

如下數據卷容器掛載的方式就是Bind mount實現方式。docker

實現的大概思路以下:apache

1.運行一個容器做爲數據卷容器,掛載本地目錄到容器內的本地目錄,無需所掛載的源目錄或目標掛載點是否存在,docker會自動建立相應的目錄的,也無需考慮使用哪一個鏡像來運行這個容器,任意鏡像均可以;
2.以後不管運行多少容器,均可以使用--volumes-from選項來指定第一個運行的容器進行數據持久化;
3.實現的效果爲:掛載數據卷容器實現數據持久化的容器,會自動將數據卷容器掛載的本地目錄掛載到該容器自己(自己的掛載點與數據卷容器的掛載點自動保持一致),也僅僅只會掛載數據卷容器實現了數據持久化的目錄到本身自己,而不是數據卷容器的所有目錄。json

上面實現的效果可能我表達的不夠好,舉個例子 :
有A、B、C這三個容器,其中A做爲數據卷容器,掛載了本地的/data/web01和/data/web02這兩個目錄到容器內的/usr/share/nginx/html/和/data這兩個目錄。
容器B和容器C在運行之初,經過--volumes-from選項來指定容器A的名稱或ID,那麼最終實現的效果就是,A、B、C這三個容器內都會存在/usr/share/nginx/html及/data這兩個目錄,而且是實現了數據持久化的,對應的本地目錄都是/data/web01和/data/web02。vim

持久化存儲:本質上是DockerHost文件系統中的目錄或文件,可以直接被Mount到容器的文件系統中。在運行容器時,能夠經過-v 實現。瀏覽器

Bind mount的特色:網絡

Data Volume是目錄或文件,不能是沒有格式化的磁盤(塊設備);
容器能夠讀寫volume中的數據;
隨源文件變化而變化;
volume數據能夠永久保存,即便使用它的容器已經被銷燬;

示例:

[root@localhost ~]# cd /tmp/
[root@localhost tmp]# mkdir /html
[root@localhost tmp]# echo "huan ying ni zjz" >> /html/index.html   //建立測試頁面
[root@localhost tmp]# docker run -itd --name testweb -p 80:80 -v /html:/usr/share/nginx/html 
nginx:latest
//運行容器並使用「-v」選項指定掛載目錄,前面爲docker host的目錄,「:」後面爲容器中的目錄
[root@localhost tmp]# curl 127.0.0.1  //能夠看到掛載已經生效
huan ying ni zjz
[root@localhost tmp]# echo "hello" >> /html/index.html 
[root@localhost tmp]# curl 127.0.0.1  
//這種方式能夠看出當源文件發生變化時,目標文件也會隨之發生變化
huan ying ni zjz
hello
[root@localhost tmp]# docker inspect testweb  //查看容器的詳細信息

在這裏插入圖片描述

注意:

DockerHost上須要被掛着的源文件或目錄,必須是已經存在,不然,當作的一個目錄掛着到容器中;

默認掛載到容器內的文件,容器是有讀寫權限。能夠在運行容器「-v」選項後邊加「:ro」 選項來限制容器的寫入權限;

能夠掛載單獨的文件到容器內部,使用場景:若是不想對整個目錄進行覆蓋,而只但願添加某個文件,就可使用掛載單個文件;

二、Docker Manager Volume實現數據持久化

示例:

[root@docker ~]# docker run -itd --name test1 -v /usr/share/nginx/html nginx:latest
//這種方式「-v」選項後,只需添加容器中的目錄便可
[root@docker ~]# docker inspect test1

在這裏插入圖片描述

[root@docker~]#ls /var/lib/docker/volumes/46d00301afb2b9c8d5279475d50d9242470af37969fa52338e916de1e35a6e93/_data/
50x.html  index.html
//能夠看出宿主機上的目錄就是容器中掛載的目錄

這種方式特色:

會隨着源文件的變化而變化,跟Bind mount效果是同樣的!
刪除容器的操做,默認不會對dockerhost主機上的原文件進行刪除,若是想要在刪除容器是將原文件刪除,能夠在刪除容器時添加「-v」選項,(通常狀況下不建議使用,由於文件有可能被其餘容器就使用);

3.Volume container(容器與容器的數據共享)

Volume container:給其餘容器提供volume存儲卷的容器。而且它能夠提供bind mount,也能夠提供docker manager volume。

[root@docker ~]#  docker create --name vc_data  -v /html:/usr/share/nginx/html busybox:latest
//建立一個容器(無須運行)
[root@docker ~]# docker run -itd --name test3 -P --volumes-from vc_data nginx:latest
//使用「--volumes-from」來掛載vc_data容器中的數據間到新的容器test3
[root@docker ~]# docker ps             //查看其映射的端口
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                   NAMES
0c0429f3e8c0        nginx:latest        "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:32768->80/tcp   test3
[root@docker ~]# curl 127.0.0.1:32768        //測試效果
huan ying ni zjz
hello

注意:以上方式在源目錄刪除後,容器中的數據也會發生丟失現象!

能夠採用編寫dockerfile文件的方式,將目錄或文件寫到鏡像中,而後根據鏡像生成容器,纔可保證原數據丟失,容器中的數據不會發生變化!

因爲這種方式隨機性、靈活性太差,這裏就很少作介紹了這樣就能夠經過數據卷容器實現容器之間的數據共享。

經過以上機制,即便容器在運行過程當中出現故障,用戶也不用擔憂數據發生丟失。若是發生意外,只需快速從新建立容器便可!

注意:生產環境中最注重的就是存儲的可靠性,以及存儲的可動態擴展性,必定要在作數據卷時考慮到這一點,在這方面比較出色的還要數GFS文件系統了,我上面只是作了簡單的配置,若在生產環境中,必定要好好考慮,就好比上面作的鏡像卷容器,就能夠在宿主機本地掛載GFS文件系統,而後建立鏡像卷容器時,將掛載GFS的目錄映射到容器中的鏡像卷,這樣纔是一個合格的鏡像卷容器。

Bind Mount 和 Docker Manager Volume的特色;

在這裏插入圖片描述

4.容器的跨主機數據共享

docket1 docker2 docker3
httpd httpd nfs

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

docker3的操做

[root@nfs ~]# 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.service  #啓動
[root@nfs ~]# systemctl enable nfs-server.service #開機自啓
[root@nfs ~]# showmount -e  #驗證
Export list for nfs:
/datashare *
[root@nfs ~]# cd /datashare/   
[root@nfs datashare]# touch 123.txt    #建立測試文件
[root@nfs datashare]# echo  "12312321312" > 123.txt 
[root@nfs datashare]# cat 123.txt 
12312321312
[root@nfs datashare]# echo "hell world" > index.html

docker1上的操做

#也需安裝nfs
[root@docker1 ~]# showmount -e 192.168.10.54   #驗證
Export list for 192.168.10.54:
/datashare *
[root@docker1 ~]# mkdir /htdocs #建立目錄
[root@docker1 htdocs]#  mount -t nfs 192.168.10.54:/datashare /htdocs  #將/htdocs目錄掛載到192.168.10.54:/datashare 下
[root@docker1 ~]# cd /htdocs/
[root@docker1 htdocs]# pwd
/htdocs
[root@docker1 htdocs]# ls
123.txt  index.html
[root@docker1 htdocs]# cat 123.txt 
12312321312
[root@docker1 ~]# docker run -itd --name web1 -P -v /htdocs:/usr/local/apache2/htdocs httpd:latest
[root@docker1 ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
ed9710a468a2        httpd:latest        "httpd-foreground"   43 seconds ago      Up 41 seconds       0.0.0.0:32768->80/tcp   web1

在這裏插入圖片描述

docker2上的操做和docker1操做同樣

#也需安裝nfs
[root@docker2 ~]# showmount -e 192.168.10.54   #驗證
Export list for 192.168.10.54:
/datashare *
[root@docker2 ~]# mkdir /htdocs
[root@docker2 htdocs]#  mount -t nfs 192.168.10.54:/datashare /htdocs 
[root@docker2 ~]# cd /htdocs/
[root@docker2 htdocs]# pwd
/htdocs
[root@docker2 htdocs]# ls
123.txt  index.html
[root@docker2 htdocs]# cat 123.txt 
12312321312
[root@docker2 htdocs]#  docker run -itd --name web2 -P -v /htdocs:/usr/local/apache2/htdocs httpd:latest
[root@docker2 htdocs]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                   NAMES
2a5ddae0894d        httpd:latest        "httpd-foreground"   7 seconds ago       Up 5 seconds        0.0.0.0:32769->80/tcp   web2

在這裏插入圖片描述
此時,用瀏覽器訪問,兩個WEB服務的主界面是同樣。但若是,NFS服務 器上的源文件丟失,則兩個web服務都會異常

想辦法將源數據寫入鏡像內,在基於鏡像作一個vc_data容器,因此咱們 在docker01和docker02上先手動建立鏡像
docker1上操做

[root@docker1 htdocs]# vim Dockerfile
FROM busybox 
ADD index.html /usr/local/apache2/htdocs/index.html 
VOLUME /usr/local/apache2/htdocs
[root@docker1 htdocs]#  docker build -t back_data . 
[root@docker1 htdocs]#  docker create --name back_container1 back_data:latest
[root@docker1 htdocs]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
back_data           latest              bfc2314995b5        24 seconds ago      1.22MB
[root@docker1 htdocs]# docker run -itd --name web3 -P --volumes-from back_container1 httpd:latest
[root@docker1 htdocs]# docker inspect web3

在這裏插入圖片描述
**總結:<br/>1)解決容器跨主機數據共享的方案: NFS<br/>2)容器與容器的數據共享: 基於某個容器而來(--volumes-from選 項),意味着這些容器和vc容器的數據存儲是同樣的。**

相關文章
相關標籤/搜索