調查 Docker 的文件系統node
首先應該想到的是 aufs。git
aufs 已是比較古老的了。github
實際上有如下集中類型可供使用。docker
存儲驅動 | 支持的文件系統 |
---|---|
overlay, overlay2 | xfs, ext4 |
devicemapper | direct-lvm, loopback-lvm |
aufs | xfs, ext4 |
btrfs | btrfs |
zfs | zfs |
vfs | 其餘文件系統 |
注: aufs 在 Fedora、CentOS 上沒有被支持。json
目前官方推薦 overlay2 ,若是 OS 支持,在首次安裝 Docker 便會採用此文件系統。之前有過默認採用 aufs 的年代,若是已經安裝了 Docker 並使用 aufs,更新版本時仍會使用。bash
如何查看當前使用的storage driver?架構
docker info
app
$ docker info
Containers: 34
Running: 16
Paused: 0
Stopped: 18
Images: 13
Server Version: 18.09.4
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: systemd
複製代碼
DeviceMapper 由2個磁盤構成,分別是 metadata 和 data。tcp
擁有 Thin-Provisioning 功能。oop
DeviceMapper 使用 LVM。
有以上2種方式。
mount 方式不同。
由以上部分組成,建立成以下的鏡像:
Docker 在設計時,就充分利用 Union FS 的技術,將其設計爲分層存儲的架構。鏡像實際是由多層文件系統聯合組成。
鏡像構建時,會一層層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在本身這一層。
好比,刪除前一層文件的操做,實際不是真的刪除前一層的的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,可是實際上該文件會一直跟隨鏡像。所以,在構建鏡像的時候,須要額外當心,每一層儘可能只包含該層須要的添加的東西,任何額外的東西應該在該層構建結束前清理掉。
分層存儲的特徵還使得鏡像的複用、定製變得更爲容易。甚至能夠用以前構建好的鏡像做爲基礎層,而後進一步添加新的層,以定製本身所需的內容,構建新的鏡像。
# pull a new image
$ docker pull busybox
Using default tag: latest
latest: Pulling from library/busybox
fc1a6b909f82: Pull complete
Digest: sha256:954e1f01e80ce09d0887ff6ea10b13a812cb01932a0781d6b0cc23f743a874fd
Status: Downloaded newer image for busybox:latest
$ clear
$ ls -lht
總用量 12K
drwx------. 3 root root 30 4月 13 16:05 289e5e2a228b1ff909050212126a2fa99dd6f2665134a19770e5b7eea50b2e86
drwx------. 2 root root 8.0K 4月 13 16:05 l
# be aware of 'docker/overlay2/l' is recording image layers' connection
$ pwd
/var/lib/docker/overlay2/l
$ ls -lht | head -n5
總用量 0
lrwxrwxrwx. 1 root root 72 4月 13 16:38 HN6VUXSR7NBMXZW37AIXRTEUTM -> ../7b36dab9d59a60efcd4a3995971ad062a25e6a390bf3f3e897292d53503a466d/diff
lrwxrwxrwx. 1 root root 77 4月 13 16:38 Y4QZHPBVBNBITRHGYYVM5TDHDY -> ../7b36dab9d59a60efcd4a3995971ad062a25e6a390bf3f3e897292d53503a466d-init/diff
lrwxrwxrwx. 1 root root 72 4月 13 16:38 V6CDQKWZHYWB5JVR5DVERURLCD -> ../202659682f2b0823d72cd8316717bbfd494dee22e85efd092d782d3927b04fed/diff
lrwxrwxrwx. 1 root root 77 4月 13 16:38 LCXZSOCIBLIKGLXHDKQV52ZKXG -> ../202659682f2b0823d72cd8316717bbfd494dee22e85efd092d782d3927b04fed-init/diff
$
# let's check out what is in busybox image's filesystem
$ pwd
/var/lib/docker/overlay2/289e5e2a228b1ff909050212126a2fa99dd6f2665134a19770e5b7eea50b2e86
$ ls -lh
總用量 4.0K
drwxr-xr-x. 10 root root 96 4月 13 16:05 diff
-rw-r--r--. 1 root root 26 4月 13 16:05 link
$ cd diff
$ ls -lh
總用量 16K
drwxr-xr-x. 2 root root 12K 4月 2 12:32 bin
drwxr-xr-x. 2 root root 6 4月 2 12:32 dev
drwxr-xr-x. 3 root root 79 4月 2 12:33 etc
drwxr-xr-x. 2 65534 65534 6 4月 2 12:32 home
drwx------. 2 root root 6 4月 2 12:32 root
drwxrwxrwt. 2 root root 6 4月 2 12:32 tmp
drwxr-xr-x. 3 root root 18 4月 2 12:32 usr
drwxr-xr-x. 4 root root 30 4月 2 12:32 var
$ cd usr
$ ls -lh
總用量 0
drwxr-xr-x. 2 bin bin 6 4月 2 12:32 sbin
$
# build my image
$ docker build -t go-server-9860 .
Sending build context to Docker daemon 7.311MB
Step 1/5 : FROM busybox
---> af2f74c517aa
Step 2/5 : MAINTAINER https://github.com/aruruka
---> Running in f50d07d89177
Removing intermediate container f50d07d89177
---> d02fd95709de
Step 3/5 : COPY server_9860 /usr/local/bin/
---> 94f0965b4ce9
Step 4/5 : WORKDIR /usr/local/bin/
---> Running in f0afc045a941
Removing intermediate container f0afc045a941
---> cc90efd3c240
Step 5/5 : ENTRYPOINT ["server_9860"]
---> Running in 51ca3dd962ec
Removing intermediate container 51ca3dd962ec
---> 2f31d1b7c458
Successfully built 2f31d1b7c458
Successfully tagged go-server-9860:latest
# check out upper layer's contents
# layer link info is in 'lower' file
$ pwd ; ls
/var/lib/docker/overlay2/1fbb0c7d6b69db147dea4de13b70dad9cc2c98536869c3a53082ad961836403d
diff link lower work
$ cat lower
l/UFX72NO2WA4Y7EELEHYCA6YXNZ$
# newer file will be in 'diff' dir
$ pwd
/var/lib/docker/overlay2/1fbb0c7d6b69db147dea4de13b70dad9cc2c98536869c3a53082ad961836403d/diff/usr/local/bin
$ ls -lh
總用量 7.0M
-rwxrwxr-x. 1 root root 7.0M 4月 13 16:23 server_9860
$
# use docker history command to verify image content
$ docker images | sed -n '1p;/go-server/Ip'
REPOSITORY TAG IMAGE ID CREATED SIZE
go-server-9860 latest 2f31d1b7c458 24 hours ago 8.51MB
$ docker history go-server-9860
IMAGE CREATED CREATED BY SIZE COMMENT
2f31d1b7c458 24 hours ago /bin/sh -c #(nop) ENTRYPOINT ["server_9860"] 0B
cc90efd3c240 24 hours ago /bin/sh -c #(nop) WORKDIR /usr/local/bin/ 0B
94f0965b4ce9 24 hours ago /bin/sh -c #(nop) COPY file:f7a8106426c88c00… 7.31MB
d02fd95709de 24 hours ago /bin/sh -c #(nop) MAINTAINER https://github… 0B
af2f74c517aa 11 days ago /bin/sh -c #(nop) CMD ["sh"] 0B
<missing> 11 days ago /bin/sh -c #(nop) ADD file:6051b0ebe4098ccbb… 1.2MB
$
複製代碼
# run a container by the image I just build and observe filesystem's change
$ docker run -d --name go-server-9860 -p 127.0.0.1:9860:9860/tcp --rm go-server-9860
[root@lab-01 1fbb0c7d6b69db147dea4de13b70dad9cc2c98536869c3a53082ad961836403d]# mount | grep overlay
overlay on /var/lib/docker/overlay2/ee0374838eb0133ee43da57551c49ccd7b63eb04b9221d02e50c4966cdbae440/merged type overlay (rw,relatime,seclabel,lowerdir=/var/lib/docker/overlay2/l/ZEHVHEBBCDTTPJNQSCPZEU5MTC:/var/lib/docker/overlay2/l/7XHO5S33QZEIRZFKS4N4GZCPCO:/var/lib/docker/overlay2/l/UFX72NO2WA4Y7EELEHYCA6YXNZ,upperdir=/var/lib/docker/overlay2/ee0374838eb0133ee43da57551c49ccd7b63eb04b9221d02e50c4966cdbae440/diff,workdir=/var/lib/docker/overlay2/ee0374838eb0133ee43da57551c49ccd7b63eb04b9221d02e50c4966cdbae440/work)
複製代碼
# check go-server container's id
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
65a25b310253 go-server-9860 "server_9860" 5 hours ago Up 5 hours 127.0.0.1:9860->9860/tcp go-server-9860
# determine container's filesystem directory
$ docker inspect --format='{{json .GraphDriver.Data.MergedDir}}' 65a25b310253
"/var/lib/docker/overlay2/ee0374838eb0133ee43da57551c49ccd7b63eb04b9221d02e50c4966cdbae440/merged"
$ cd /var/lib/docker/overlay2/ee0374838eb0133ee43da57551c49ccd7b63eb04b9221d02e50c4966cdbae440/merged
$ cd usr/local/bin
$ ls -lh
總用量 7.0M
# be careful of the inode of the program
-rwxrwxr-x. 1 root root 7.0M 4月 13 16:23 server_9860
$ ls -i server_9860
33638603 server_9860
# now let's find lower layers of the container layer
$ cd /var/lib/docker/overlay2/ee0374838eb0133ee43da57551c49ccd7b63eb04b9221d02e50c4966cdbae440/merged
$ cd ..
$ ls -lh
總用量 8.0K
drwxr-xr-x. 2 root root 6 4月 14 17:52 diff
-rw-r--r--. 1 root root 26 4月 14 17:52 link
-rw-r--r--. 1 root root 86 4月 14 17:52 lower
drwxr-xr-x. 1 root root 6 4月 14 17:52 merged
drwx------. 3 root root 18 4月 14 17:52 work
$ cat lower
l/ZEHVHEBBCDTTPJNQSCPZEU5MTC:l/7XHO5S33QZEIRZFKS4N4GZCPCO:l/UFX72NO2WA4Y7EELEHYCA6YXNZ$
# the second lower layer would be the server_9860 file layer which was build by myself
$ ls -AFlh /var/lib/docker/overlay2/l/7XHO5S33QZEIRZFKS4N4GZCPCO
lrwxrwxrwx. 1 root root 72 4月 13 16:27 /var/lib/docker/overlay2/l/7XHO5S33QZEIRZFKS4N4GZCPCO -> ../1fbb0c7d6b69db147dea4de13b70dad9cc2c98536869c3a53082ad961836403d/diff/
$ cd /var/lib/docker/overlay2/l/../1fbb0c7d6b69db147dea4de13b70dad9cc2c98536869c3a53082ad961836403d/diff/
$ ls -lh
總用量 0
drwxr-xr-x. 3 root root 19 4月 13 16:27 usr
$ cd usr/local/bin
$ ls -lh
總用量 7.0M
-rwxrwxr-x. 1 root root 7.0M 4月 13 16:23 server_9860
# be aware of the inode is as same as the file in container's layer
$ ls -i server_9860
33638603 server_9860
$
複製代碼