Docker筆記(八):數據管理

前面(哪一個前面我也忘了)有說過,若是咱們須要對數據進行持久化保存,不該使其存儲在容器中,由於容器中的數據會隨着容器的刪除而丟失,而因經過將數據存儲於宿主機文件系統的形式來持久化。在Docker容器中管理數據主要有數據卷、宿主機目錄掛載兩種方式。linux

1. 數據卷的方式

數據卷是一個特殊的文件目錄(或文件),具有以下特性:web

  1. 能夠在容器之間共享和重用docker

  2. 對數據卷的修改會立馬生效
  3. 數據卷的更新,不會影響到鏡像
  4. 數據卷默認會一直存在,不會隨容器的刪除而消亡

 

1.1 建立數據卷

可使用docker volume create 數據卷名稱的命令來建立一個數據卷,ubuntu

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume create volume1
volume1

 

1.2 查看數據卷

建立完後,這個數據卷具體對應宿主機哪一個文件目錄在上面是無法得知的,能夠經過 docker volume inspect 數據卷名稱來查看,安全

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume inspect volume1
[
    {
        "CreatedAt": "2019-08-12T19:43:47+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/volume1/_data",
        "Name": "volume1",
        "Options": {},
        "Scope": "local"
    }
]
能夠看到數據卷volume1對應的文件目錄是「/var/lib/docker/volumes/volume1/_data」。

docker inspect xxx這個命令挺有用的,不管是查看鏡像相關信息(docker image inspect 鏡像名/鏡像ID),仍是查看容器相關信息(docker container inspect 容器名/容器ID),均可以使用,其中的image,container,volume是能夠省略的,只要xxx部分不衝突就行。
能夠經過docker volume ls 命令來查看全部數據卷,ruby

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker volume ls
DRIVER              VOLUME NAME
local               volume1

 

1.3 使用數據卷bash

能夠在啓動容器時經過 -v 或 –mount 的方式將一個數據卷掛載到容器的某個目錄微信

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu1 -v volume1:/vol1 ubuntu:18.04
b060e793d44de2ca871da257b47598334658952943a13d1c478df5c3ae91a01c

按照 -v 數據卷名:容器目錄 的格式,也可使用 –mount 按照 --mount source=數據卷名,target=容器目錄 的格式,如咱們再啓動一個掛載相同數據卷的容器 ubuntu2,網絡

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount source=volume1,target=/vol2 ubuntu:18.04
b30971f8a4bbadee10774fce0b4568b5b7b1c9cde36f4bf84ac911a4cdaf6c8d

能夠在數據卷所在目錄中建立一個文件來看看效果,先建立文件 hello.txtapp

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# cd /var/lib/docker/volumes/volume1/_data
[root@iZwz9dbodbaqxj1gxhpnjxZ _data]# touch hello.txt
[root@iZwz9dbodbaqxj1gxhpnjxZ _data]# ls
hello.txt

而後經過docker exec來查看容器ubuntu1目錄/vol1,及容器ubuntu2目錄/vol2的內容

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu1 ls /vol1
hello.txt
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu2 ls /vol2
hello.txt

能夠看到經過掛載目錄 /vol1, /vol2 均可以訪問到數據卷volume1對應目錄下的內容。這就像linux的軟連接同樣,將容器目錄連接到了數據卷目錄。而且上述示例也說明,同一個數據卷是能夠在被多個容器共享的。

數據卷的共享也能夠經過 volumes-from 容器名稱/容器ID 參數來實現,如

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu3 --volumes-from ubuntu2 ubuntu:18.04
bb5c6d61a1e6eeb18ba8c889e471b2f3215f97efca79b311eeca5968b2700df8
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu3 ls /vol2
hello.txt

經過--volumes-from ubuntu2來直接使用ubuntu2掛載的容器配置。

 

1.4 刪除數據卷

數據卷不會隨着容器的刪除而自動刪除。若是一個數據卷還被某個容器使用,則不能刪除;若是一個數據卷只被一個容器使用,則可在刪除容器時經過指定 -v 參數同時刪除其掛載的數據卷;

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker rm -v ubuntu3
ubuntu3

能夠經過 docker volume rm 數據卷名稱 來刪除某個數據卷;

能夠經過 docker volume prune 清理掉全部未被任何容器使用的數據卷。

 

2. 宿主機目錄掛載方式

在容器啓動時,使用 -v 宿主機目錄:容器目錄 或 --mount type=bind,source=宿主機目錄,target=容器目錄的參數格式指定將宿主機目錄掛載到容器目錄上。宿主機目錄必須是絕對路徑。二者之間的區別是 -v 若是在宿主機目錄不存在時會自動建立目錄,而--mount不會。如,

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu1 -v /root/v1:/vol1 ubuntu:18.04
25c91911709eebc9290b47b483666f7b7be840df947117f7cad323583905b9f1
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount type=bind,source=/root/v2,target=/vol1 ubuntu:18.04
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /root/v2.
See 'docker run --help'.
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# mkdir /root/v2
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu2 --mount type=bind,source=/root/v2,target=/vol1 ubuntu:18.04
5a57285e9261d048dc71cf0476055a290f80538afff2cefd2a24f8b4468b5171

/root/v1,/root/v2都沒有事先建立,用 -v 不會報錯,會自動建立; --mount則會報錯,目錄必須先存在。docker不只支持目錄的掛載,也支持文件的掛載,如,

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run --rm -it -v $HOME/.bash_history:/root/.bash_history ubuntu:18.04 bash
root@3ae4ed4e687d:/# history
    1  ll webapps/
    2  ll confluence/images/

經過將宿主機當前用戶的歷史操做文件掛載到容器的root用戶下的歷史操做文件,可在容器中經過history命令查看到宿主機的操做歷史。可經過 docker inspect來查看容器的掛載狀況

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker inspect ubuntu1
--省略了其它信息--
"Mounts": [
            {
                "Type": "bind",
                "Source": "/root/v1",
                "Destination": "/vol1",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
--省略了其它信息--
可在「Mounts」部分看到掛載信息。

 

3. 只讀控制

有時候,爲了數據安全,咱們不容許容器對掛載目錄的內容進行修改,即對容器來講,掛載目錄是隻讀的,這能夠經過在掛載參數後面加限制實現。

[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker run -dit --name ubuntu3 -v /root/v1:/vol1:ro ubuntu:18.04
25eca348ed307afcbef92bc03f0a1304b31b52e6db1fa07772b5dbd1040ff7b6
[root@iZwz9dbodbaqxj1gxhpnjxZ ~]# docker exec -it ubuntu3 bash
root@25eca348ed30:/# touch /vol1/hello.txt
touch: cannot touch '/vol1/hello.txt': Read-only file system
是在後面加(read-only),則是形如的格式,可自行試驗。-vro--mount--mount type=bind,source=宿主機目錄,target=容器目錄,read only

加了read only的掛載咱們再經過docker inspect命令查看,可看到二者之間的差別 —— Mode與RW的值。

"Mounts": [
            {
                "Type": "bind",
                "Source": "/root/v1",
                "Destination": "/vol1",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            }
        ],

 

4. 總結

若是要對數據進行持久化管理或在容器之間共享數據,則須要將數據經過數據卷或宿主機目錄(或文件)掛載的方式來將數據存儲於宿主機上,使得數據的生命週期獨立於容器的生命週期。這相似於咱們不要把重要文件放在系統盤,而應放在其它數據盤同樣,由於系統盤會因爲重裝系統或系統故障致使文件丟失。本文對Docker的數據管理進行了整理,後續對Docker的網絡配置管理部分進行整理,歡迎持續關注。

 

 

相關閱讀

Docker筆記(一):什麼是Docker
Docker筆記(二):Docker管理的對象
Docker筆記(三):Docker安裝與配置
Docker筆記(四):Docker鏡像管理
Docker筆記(五):整一個本身的鏡像
Docker筆記(六):容器管理
Docker筆記(七):經常使用服務安裝——Nginx、MySql、Redis

 

本文發表於微信公衆號:「空山新雨的技術空間」

做者:空山新雨
歡迎關注,轉發,推薦,你的支持是我持續創做的動力

相關文章
相關標籤/搜索