使用docker目錄建立一個volume,並將該volume掛載到容器的/my_Cvol目錄下node
# docker volume create my_vo # docker run -itd --rm --mount source=my_vol,target=/my_Cvol busybox:latest /bin/sh
查看該volume,其源目錄實際在/var/lib/docker/volumes/my_vol/_data下git
# docker volume inspect my_vol [ { "CreatedAt": "2018-12-24T22:42:18+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/my_vol/_data", "Name": "my_vol", "Options": null, "Scope": "local" } ]
查看使用docker inspect容器相關信息,能夠看到volume的掛載信息,掛載到容器中的目錄是可讀寫的。這樣在容器的/my_Cvol目錄下的操做也會同步到host的/var/lib/docker/volumes/my_vol/_data目錄中。github
"Mounts": [ { "Type": "volume", "Name": "my_vol", "Source": "/var/lib/docker/volumes/my_vol/_data", "Destination": "/my_Cvol", "Driver": "local", "Mode": "z", "RW": true, "Propagation": "" }
查看host上/var/lib/docker/volumes/my_vol/_data的MAC屬性能夠看到它們變爲了容器的MAC屬性,這樣也防止了容器操做不屬於其權限範圍的文件docker
# ls -Z -rw-------. root root system_u:object_r:container_var_lib_t:s0 metadata.db drwxr-xr-x. root root system_u:object_r:container_var_lib_t:s0 my_vol
使用tmpfs主要用於存儲臨時數據,因爲tmpfs使用的是共享內存方式,因此其效率比較高。使用tmpfs時有以下2個選項用於指定tmpfs的大小和訪問權限:centos
tmpfs-size:指定tmpfs的大小安全
tmpfs-mode:指定mount的目錄權限bash
首先安裝docker插件app
# docker plugin install --grant-all-permissions vieux/sshfs
在node1節點上建立位於node2節點的卷,登錄的ssh密碼爲root,對端ip爲192.168.80.161ssh
# docker volume create --driver vieux/sshfs -o sshcmd=root@192.168.80.161:/home/sshvolume -o password=root sshvolume
在host上查看容器進程的掛載信息,能夠看到其實際使用了fuse.sshfs的方式掛載了來自的root@192.168.80.161:/home/sshvolume目錄性能
# cat /proc/19574/mountinfo |grep 176 502 399 0:49 / /sshvolume rw,nosuid,nodev,relatime master:176 - fuse.sshfs root@192.168.80.161:/home/sshvolume rw,user_id=0,group_id=0
node1上查看docker卷信息,能夠看到新增了drive爲vieux/sshfs:latest,名字爲sshvolume的卷
# docker volume ls DRIVER VOLUME NAME vieux/sshfs:latest sshvolume
在node1上建立一個容器,並將上一步的卷掛載到容器,在容器內部建立2個文件夾,登錄到node2的/home/sshvolume,能夠看到該目錄下有node1的容器建立的文件夾
docker run -itd --mount source=sshvolume,target=/sshvolume busybox:latest /bin/sh
docker storage driver
storage driver負責不一樣layer之間的交互,它容許在容器的讀寫層建立數據,讀寫層數據不會被持久化,且讀寫效率較低。如下圖所示,容器鏡像的layer是隻讀的,當建立一個容器時,會新增一個讀寫層,稱爲」container layer「,對容器的全部修改都在該layer上進行。當容器刪除後,該讀寫層也會被刪除。不一樣的storage driver實現不一樣,但全部的storage driver都使用了以下棧式鏡像結構以及CoW(copy-on-write)策略。這是對CoW的描述
而CoW技術可讓全部的容器共享image的文件系統,全部數據都從image中讀取,只有當要對文件進行寫操做時,才從image裏把要寫的文件複製到本身的文件系統進行修改。因此不管有多少個容器共享同一個image,所作的寫操做都是對從image中複製到本身的文件系統中的複本上進行,並不會修改image的源文件,且多個容器操做同一個文件,會在每一個容器的文件系統裏生成一個複本,每一個容器修改的都是本身的複本,相互隔離,相互不影響。使用CoW能夠有效的提升磁盤的利用率。
使用docker ps -s能夠查看鏡像大小,能夠看到"SIZE"有2個值,如container id爲5b22377a773d的容器中,38B表示容器讀寫層的數據總和;virtual表示只讀的鏡像層加上讀寫層的大小,不一樣的容器可能會共用部分或所有的鏡像層,所以計算容器佔用空間大小不能簡單地對virtual進行疊加
# docker ps -s CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE 5b22377a773d echo:v1 "/bin/sh" 2 hours ago Up 2 hours practical_darwin 38B (virtual 1.2MB) 803ee1eb5acf echo:v1 "sh -c /home/echo.sh" 2 hours ago Up 2 hours hungry_hertz 66B (virtual 1.2MB)
當在5b22377a773d中手動建立一個非空文件以後,能夠看到size變爲了95B
# docker ps -s CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE 5b22377a773d echo:v1 "/bin/sh" 2 hours ago Up 2 hours practical_darwin 95B (virtual 1.2MB) 803ee1eb5acf 6d495122f721 "sh -c /home/echo.sh" 2 hours ago Up 2 hours hungry_hertz 66B (virtual 1.2MB)
當使用docker pull拉取一個容器鏡像時,會在/var/lib/docker/<storage-driver>/layers/下面保存各個layer。
容器的讀寫層只保存修改過的變更,而未修改的文件或目錄等則不會被保存在讀寫層。當修改容器中已經存在的文件時,會執行CoW操做,此時在鏡像層中逐層搜索該文件,當找到該文件時,會將文件拷貝到容器的讀寫層(容器的鏡像只讀層可共享,但讀寫層不能夠共享,CoW技術能夠最大化減少容器佔用的磁盤,提升磁盤利用率)。當CoW的讀寫效率比較低,可能會影響IO效率,須要注意如下2點:
ocker的storage driver使用插件方式提供功能。插件的選擇取決於docker的版本以及使用的系統等,官方對storage driver的選擇有以下建議,能夠看出目前主要推薦overlay2。overlay和devicemapper已經在docker 18.09版本中被廢除
Linux distribution | Recommended storage drivers | Alternative drivers |
---|---|---|
Docker Engine - Community on Ubuntu | overlay2 or aufs (for Ubuntu 14.04 running on kernel 3.13) |
overlay , devicemapper , zfs , vfs |
Docker Engine - Community on Debian | overlay2 (Debian Stretch), aufs or devicemapper (older versions) |
overlay , vfs |
Docker Engine - Community on CentOS | overlay2 |
overlay , devicemapper , zfs , vfs |
Docker Engine - Community on Fedora | overlay2 |
overlay , devicemapper , zfs , vfs |
不一樣storage driver所須要的文件系統以下:
Storage driver | Supported backing filesystems |
---|---|
overlay2 , overlay |
xfs with ftype=1, ext4 |
aufs |
xfs , ext4 |
devicemapper |
direct-lvm |
btrfs |
btrfs |
zfs |
zfs |
vfs |
any filesystem |
不一樣的storage driver各有優缺點:
在對storage driver修改時須要注意
Important: When you change the storage driver, any existing images and containers become inaccessible. This is because their layers cannot be used by the new storage driver. If you revert your changes, you can access the old images and containers again, but any that you pulled or created using the new driver are then inaccessible.
下面講解下overlay2的文件結構和特色,首先下載一個centos鏡像,查看改鏡像有以下3個layer
# docker history centos:latest IMAGE CREATED CREATED BY SIZE COMMENT 1e1148e4cc2c 2 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B <missing> 2 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B <missing> 2 months ago /bin/sh -c #(nop) ADD file:6f877549795f4798a… 202MB
使用docker inspect查看該鏡像能夠看到其文件系統
"GraphDriver": { "Data": { "MergedDir": "/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/merged", "UpperDir": "/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/diff", "WorkDir": "/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/work" }, "Name": "overlay2" },
使用docker run -itd centos:latest /bin/sh啓動一個centos的容器,此時會自動建立overlay須要的lowerdir,upperdir,merged和workdir,使用docker inspect命令,能夠看到該容器的overlay2使用狀況
"GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d-init/diff:/var/lib/docker/overlay2/0bb8525e901534d5c3884a9e47b91d27f887278d0433506126c45081a2a482b8/diff", "MergedDir": "/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/merged", "UpperDir": "/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/diff", "WorkDir": "/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/work" }, "Name": "overlay2" },
merged,upperdir和lowerdir的定義以下,upperdir爲容器的讀寫層,lowerdir爲容器的鏡像只讀層,merged爲兩者的合集
在容器建立後在/var/lib/docker/overlay2下面會生成2個新的目錄,其中7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d-init用於設置容器的初始環境
drwx------. 5 root root 69 Feb 13 22:17 7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d drwx------. 4 root root 55 Feb 13 22:17 7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d-init
在7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d目錄下能夠看到以下文件和目錄:diff爲該容器的UpperDir,對於容器的讀寫層,在容器中建立的文件或目錄都會體如今該目錄中(以下圖,在容器的/home下建立一個名爲newfile的文件和一個名爲newfoler的目錄,在diff/home下面也會同步體現該變化)。
# tree -L 1
.
├── diff
├── link
├── lower
├── merged
└── work
# pwd
/var/lib/docker/overlay2/7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/diff/home
# ll
total 0
-rw-r--r--. 1 root root 0 Feb 13 23:52 newfile
drwxr-xr-x. 2 root root 6 Feb 13 23:54 newfolder
# cat link
SKDGVP5O54VJTAXE7CQNUMIVLQ
link中包含了一個指向本目錄diff文件夾的索引SKDGVP5O54VJTAXE7CQNUMIVLQ,能夠在/var/lib/docker/l目錄下找到其定義,實際上是個系統連接(l目錄存在的意義是防止掛載時符號超出頁大小限制--默認4k)。
# ll ../l |grep SKDGVP5O54VJTAXE7CQNUMIVLQ lrwxrwxrwx. 1 root root 72 Feb 13 22:17 SKDGVP5O54VJTAXE7CQNUMIVLQ -> ../7aa485418eedcd1443f76018b94b76870de074d732f6e0d5b3e4305a6d896f0d/diff
lower的內容以下,其實就是上述的GraphDriver.Data.LowerDir,對應容器鏡像的只讀層
# cat lower l/G6URSFRXVFKZI5ESH2BGXG7LFS:l/T6OXBIDQ2GU523P5CXINFO3VH5
merged爲lower和link的合集,work爲OverlayFS內部使用的文件夾。
overlayFS讀文件時使用時有以下特性:
overlayFS寫文件或目錄時有以下特性:
因爲overlayFS的CoW特性,在容器中須要注意如下2點(詳情參見Use the OverlayFS storage driver):
TIPS:
參考:
https://docs.docker.com/storage/storagedriver/
https://arkingc.github.io/2017/05/05/2017-05-05-docker-filesystem-overlay/
https://docs.docker.com/storage/storagedriver/overlayfs-driver/