[Docker 系列]docker 學習六,資料卷容器

小魔童哪吒發表於2021-11-21

Dockerfile

Dockerfile 就是用來構建 docker 映象的構建檔案,關於 Dockerfile 詳細的我們在後面一期說到,此處先用用

他是一個命令指令碼,通過這個指令碼可以生成我們想要的映象,映象是分層的,一層一層的,指令碼也是一個一個的命令,每個命令就是一層

我們可以來看一個小小的例子

自己寫一個 Dockerfile 來構建自己的映象,我們以 ubuntu 為例子

寫一個簡單的 dockerfile1

# vim dockerfile1

FROM ubuntu

VOLUME ["volume1","volume2"]

CMD echo "====successfully===="

CMD /bin/bash

解釋一下:

  • FROM

來源基礎映象為 ubuntu

  • VOLUME

掛載,可以匿名掛載,也可以是具名掛載 ,預設會掛載到 docker 專門掛載的目錄

  • CMD

指定可以使用命令

構建我們自己的映象

# docker build -f dockerfile1 -t xiaomotong/ubuntu .
Sending build context to Docker daemon  1.346GB
Step 1/4 : FROM ubuntu
 ---> 1318b700e415
Step 2/4 : VOLUME ["volume1","volume2"]
 ---> Running in d7b475cacb22
Removing intermediate container d7b475cacb22
 ---> b8ac33cfbcfd
Step 3/4 : CMD echo "====successfully===="
 ---> Running in 35c98a625a9e
Removing intermediate container 35c98a625a9e
 ---> 67b6faf43370
Step 4/4 : CMD /bin/bash
 ---> Running in b2e1e0ad8d9b
Removing intermediate container b2e1e0ad8d9b
 ---> b26faaedefac
Successfully built b26faaedefac
Successfully tagged xiaomotong/ubuntu:latest

通過上述我們可以看到 docker 構建映象的時候是一層一層的,一個命令一個命令的執行的,一個命令就是一層

  • docker build

構建我們自己的映象

  • -f

指定 dockerfile 的檔案

  • -t

目標,即我們 docker 映象的名字

後面跟著生成映象的位置

通過我們構建的映象的建立並啟動容器

# docker images
REPOSITORY            TAG       IMAGE ID       CREATED         SIZE
xiaomotong/ubuntu     latest    b26faaedefac   6 minutes ago   72.8MB

# docker run -it b26faaedefac

執行完上述命令之後,我們可以看到容器裡面目錄如下:

從圖中我們可以看到volume1volume2,這就是我們剛才構建容器時候做的匿名掛載,那麼我們使用 docker inspect命令來看看這倆掛載卷具體是掛載到宿主機的哪個位置,並測試一個同步資料

# docker inspect b29995f4178d
...
 "Mounts": [
            {
                "Type": "volume",
                "Name": "a1fd1edec5784f1153a318003bba4279b86fd2dd71b401be5864ed9b868d7332",
                "Source": "/var/lib/docker/volumes/a1fd1edec5784f1153a318003bba4279b86fd2dd71b401be5864ed9b868d7332/_data",
                "Destination": "volume1",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            },
            {
                "Type": "volume",
                "Name": "975ae74c8716f5e85ccf784c716291cffda2158baf6b3f9e145ffc1ea353cb7b",
                "Source": "/var/lib/docker/volumes/975ae74c8716f5e85ccf784c716291cffda2158baf6b3f9e145ffc1ea353cb7b/_data",
                "Destination": "volume2",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...

通過 docker inspect可以看出 volume1volume2具體是掛載到宿主機的目錄為/var/lib/docker/volumes/a1fd1edec5784f1153a318003bba4279b86fd2dd71b401be5864ed9b868d7332/_data , 和var/lib/docker/volumes/975ae74c8716f5e85ccf784c716291cffda2158baf6b3f9e145ffc1ea353cb7b/_data

我們們在容器掛載中建立一個檔案,測試是否可以同步資料

在容器中的volume1中建立一個檔案 xiaomotong.txt,寫入字串 hello world

root@b29995f4178d:/# cd volume1
root@b29995f4178d:/volume1# echo hello world >> xiaomotong.txt
root@b29995f4178d:/volume1# ll
total 12
drwxr-xr-x 2 root root 4096 Aug  5 15:01 ./
drwxr-xr-x 1 root root 4096 Aug  5 14:54 ../
-rw-r--r-- 1 root root   12 Aug  5 15:01 xiaomotong.txt

檢視宿主機對應的掛載目錄,確認是否同步資料

root@iZuf66y3tuzn4wp3h02t7pZ:/var/lib/docker/volumes/a1fd1edec5784f1153a318003bba4279b86fd2dd71b401be5864ed9b868d7332/_data# ls
xiaomotong.txt
root@iZuf66y3tuzn4wp3h02t7pZ:/var/lib/docker/volumes/a1fd1edec5784f1153a318003bba4279b86fd2dd71b401be5864ed9b868d7332/_data# cat xiaomotong.txt
hello world

果然同步ok,nice

那麼我們有沒有想過,現在是容器和宿主機之間同步資料,可是容器和容器之間是如何同步資料的呢?

資料卷容器

資料卷容器,例如容器 1 通過指令 –volumes-from掛載到容器 2 上的某個目錄,那麼容器 2 就是父容器,這個時候就實現了兩個容器之間資料同步,容器 2 就是資料卷容器

來實戰一個小例子:

用剛才我們製作的映象,建立 2 容器,先建立 docker2 ,再建立 docker1,並且 docker1 掛載到 docker2 上,並在docker2 掛載的目錄,volume1裡面建立一個檔案,xiaomotong.txt,我們驗證 docker1 volume1裡面是否也有這個檔案

# docker images
REPOSITORY            TAG       IMAGE ID       CREATED          SIZE
xiaomotong/ubuntu     latest    b26faaedefac   38 minutes ago   72.8MB

# docker run -it --name docker2 b26faaedefac
# docker run -it --name docker1 --volumes-from docker2 b26faaedefac

b26faaedefac 是我們自己製作的映象的 ID

主要是使用 --volumes-from指令,我們就可以將兩個容器進行掛載

docker1

root@3ed3ca51118f:/volume1# ls
root@3ed3ca51118f:/volume1# touch xiaomotong.txt

docker2

root@e9e1a0c46331:/volume1# ls
xiaomotong.txt

果然,兩個容器互相同步資料了

上述的例子,不僅僅是兩個容器之間掛載,進行同步資料,多個容器掛載也是同樣的道理,例如再來一個容器 docker3 掛載到 docker2 上,也是一樣的效果

那麼他們都是如何同步資料的呢?

容器間同步資料的原理是通過拷貝的方式,例如在 docker2 上面的掛載上建立了一個檔案2,這個時候 docker1 掛載了 docker2,也就是說 docker2 是父容器,那麼 docker1 就會將檔案2 拷貝到自己對應的掛載中

反之,如果 docker1 在自己的掛載中建立了檔案1,那麼檔案1也會被 docker2 拷貝到自己的掛載中

若這個時候,我們刪除 docker2 ,那麼 docker1 掛載中的檔案會丟失嗎?

答案是不會的,因為他們是通過拷貝的方式,並不是共享一個副本

那麼我們回顧一下上一期我們建立 mysql 容器的時候,若我們建立多個,那麼我們是不是就很容易讓他們資料同步,且刪除其中一個容器,資料也不會丟失了

例如:

#docker run  -d -p 8888:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql1 mysql:5.7

#docker run  -d -p 8888:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql2 --volumes-from mysql1 mysql:5.7

我們們總結一下

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

哪怕我們不使用資料卷容器了,那麼持久化到本地宿主機的資料,也是不會被刪除掉的

參考資料:

docker docs

歡迎點贊,關注,收藏

朋友們,你的支援和鼓勵,是我堅持分享,提高質量的動力

好了,本次就到這裡

技術是開放的,我們的心態,更應是開放的。擁抱變化,向陽而生,努力向前行。

我是小魔童哪吒,歡迎點贊關注收藏,下次見~

本作品採用《CC 協議》,轉載必須註明作者和本文連結
關注微信公眾號:小魔童哪吒

相關文章