Docker存储
Docker存储
Docker镜像采用分层构建的设计,这种设计使得镜像结构和容器的创建、共享和分发变得非常高效。每个镜像层被称为一个layer,这些layer存储在/var/lib/docker//目录下,其中storage-driver可以是AUFS、OverlayFS、VFS、Btrfs等。
可以通过docker info命令查看当前使用的存储驱动。通常,Ubuntu系统默认采用AUFS,而CentOS 7.1+系列默认采用OverlayFS。
OverlayFS是一种堆叠文件系统,它依赖并建立在其它的文件系统(例如ext4、xfs等)之上,并不直接参与磁盘空间结构的划分,而是将底层文件系统中不同的目录进行合并,然后向用户呈现,这种技术称为联合挂载。
Linux内核为Docker提供的OverlayFS驱动有两种:overlay和overlay2。overlay2是overlay的改进版,在inode利用率方面更高效。使用overlay2需要满足以下环境需求:
1.Docker版本17.06.02+
2.宿主机文件系统需要是ext4或xfs格式。
data volume
数据卷是 Docker 容器中用于持久化存储数据的特殊目录,它绕过联合文件系统(UFS),提供以下特性:
- 数据持久化:容器删除后数据仍然保留
- 数据共享:多个容器可以共享同一数据卷
- 高性能:直接访问宿主机文件系统
- 解耦设计:数据与容器生命周期分离
| 特性 | Bind Mounts | Docker Managed Volume |
|---|---|---|
| 存储位置 | 宿主机任意路径 | Docker 管理目录(/var/lib/docker/volumes/) |
| 权限控制 | 依赖宿主机文件权限 | Docker 管理,可设置只读等 |
| 可移植性 | 差(依赖宿主机路径) | 好(与宿主机路径无关) |
| 备份和迁移 | 需要手动处理 | 使用 docker 命令容易备份 |
| 性能 | 直接使用宿主机文件系统 | 直接使用宿主机文件系统(但可能经过一层虚拟化) |
| 使用场景 | 开发环境、配置文件挂载 | 生产环境、数据持久化 |
bind mounts是从宿主机映射到容器内,而Docker Managed Volume是从容器映射到目录,二者的结果相同,但概念不同
Bind Mounts
1.在创建容器时使用 -v 参数来指定宿主机目录或文件与容器目录或文件的映射关系。
2.可以多次使用 -v 参数来映射多个目录或文件。
3.注意:目录只能映射到目录,文件只能映射到文件,否则会报错
示例
在docker host中创建一个/html的目录,与容器内/usr/share/nginx/html的目录做映射
[root@docker ~]# mkdir /html
[root@docker ~]# echo test1 > /html/index.html
[root@docker ~]# docker run -itd --name nginx1 -P -v /html:/usr/share/nginx/html nginx:latest
2863f5bf76a87ed7a0e2259c002a4d7172d44465f92161d310212bbc50f86261
[root@docker ~]# curl http://192.168.100.10:32768
test1
当docker host上的数据发生变化时,容器内映射的数据也会发生变换,但是当容器出故障数据丢失时,docker host上的数据不会发生变化
[root@docker ~]# docker stop nginx1
nginx1
[root@docker ~]# cat /html/index.html
test1
[root@docker ~]# curl http://192.168.100.10:32768
curl: (7) Failed connect to 192.168.100.10:32768; Connection refused
[root@docke
当docker host上的数据发生变化时
[root@docker ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2863f5bf76a8 nginx:latest "/docker-entrypoint.…" 4 minutes ago Up 28 seconds 0.0.0.0:32769->80/tcp, :::32769->80/tcp nginx1
[root@docker ~]# echo test222 > /html/index.html
[root@docker ~]# curl http://192.168.100.10:32769
test222
bind mounts还可以指定数据读写权限,默认权限是可读可写,在映射时,可以指定容器内的文件权限只读,无法修改,但只是容器内的文件只读,在docker host上还是能够修改,这样也提高了容器的安全性。
但是bind mounts也有自身的不足之处,使用时需要指定Docker host上的文件或目录为源数据,这样就限制了容器的可移植性,如果需要将容器移植到其他的docker host上,对方没有相应的源数据库,或者路径不同,操作会失败
docker managed volume
与Bind mounts相比,Docker管理的volume在使用时不需要指 定Docker host路径,Docker管理的volume具有以下几个优点:
1、与Bind mounts相比,Docker管理的volume更易于备份或迁移。
2、用户可以使用Docker CLI命令或Docker API管理volume。
3、volume在Linux和Windows容器上均可工作。
4、可以在多个容器之间更安全地共享volume,提供volume加密功能。
示例
[root@docker ~]# docker run -itd --name nginx2 -P -v /usr/share/nginx/html nginx:latest
a6b1a690aa21c3186c53a18cd90fc77ef3061283cb74ec0f432bc2e3281b9ab0
使用docker inspect查看容器的mounts部分
[root@docker ~]# docker inspect nginx2
"Mounts": [
{
"Type": "volume",
"Name": "f9c94a0b5ad42edec6946c9e91f9df3716322b1010a6639e857aaf9f908291c5",
"Source": "/var/lib/docker/volumes/f9c94a0b5ad42edec6946c9e91f9df3716322b1010a6639e857aaf9f908291c5/_data",
"Destination": "/usr/share/nginx/html",
说使用Docker管理的volume,在做映射时,会把容器中的数据映射到Docker host。
[root@docker ~]# cd /var/lib/docker/volumes/f9c94a0b5ad42edec6946c9e91f9df3716322b1010a6639e857aaf9f908291c5/_data
[root@docker _data]# ls
50x.html index.html
修改数据查看容器内数据是否发生改变
[root@docker _data]# echo test333 > index.html
[root@docker _data]# curl http://192.168.100.10:32770
test333
但是映射的名字太长了,我们可以自己创建volume
使用docker volume ls命令查看
[root@docker _data]# docker volume ls
DRIVER VOLUME NAME
local f9c94a0b5ad42edec6946c9e91f9df3716322b1010a6639e857aaf9f908291c5
[root@docker ~]# docker volume create kami
kami
[root@docker ~]# docker volume ls
DRIVER VOLUME NAME
local f9c94a0b5ad42edec6946c9e91f9df3716322b1010a6639e857aaf9f908291c5
local kami
[root@docker ~]# docker run -itd --name nginx3 -P -v kami:/usr/share/nginx/html nginx:latest
d3e974886cef08b56d01ce01643f41b325514cd0fd34b3658964ce868ec109aa
[root@docker ~]# cd /var/lib/docker/volumes/kami/
[root@docker kami]# ls
_data
[root@docker kami]# cd _data/
[root@docker _data]# ls
50x.html index.html
修改数据查看容器内容是否发生改变
[root@docker _data]# echo test555 > index.html
[root@docker _data]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d3e974886cef nginx:latest "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:32771->80/tcp, :::32771->80/tcp nginx3
[root@docker _data]# curl http://192.168.100.10:32771
test555
在使用docker volume命令创建volume时,volume默认都是存在在本地的,实际上本地的volume就是一个目录。除此之外Docker还支持在外部存储系统上创建volume,比如:NFS、Ceph等
Docker数据共享
实现容器间数据共享的方法如下:
1.第一种方法是将共享数据放在volume中,然后将其mount到多个容器。
2.第二种方法是使用volume container,volume container是用来为其他容器提供volume的容器。 这样可以提高容器的可移植性。
3.第三种方法是将数据打包到镜像中,然后通过–volumes-from共享
第一种
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@docker ~]# docker run -itd --name nginx3 -p 8081:80 -v /html:/usr/share/nginx/html nginx:latest
e16cf8a5a53951837907ac0d0fe042d782384afd5a74d28459c95ada569f984d
[root@docker ~]# docker run -itd --name nginx2 -p 8082:80 -v /html:/usr/share/nginx/html nginx:latest
93bf09407a248740cf22d13a46d3e24b2a6957b0ae184b4243a8249b8eadf938
[root@docker ~]# docker run -itd --name nginx1 -p 8083:80 -v /html:/usr/share/nginx/html nginx:latest
154c20a51b40ecd1cafe7f5561b7a24e5def58f1584d1408426b8aa560b0452a
查看
[root@docker ~]# curl http://192.168.100.10:8081
test222
[root@docker ~]# curl http://192.168.100.10:8082
test222
[root@docker ~]# curl http://192.168.100.10:8083
test222
第二种方法是使用volume container,volume container是用来为其他容器提供volume的容器。这样可以提高容器的可移植性
只需要创建一个容器提供html文件,其他容器指定这个提供html文件的容器就行
[root@docker ~]# docker pull busybox
[root@docker ~]# docker create --name kami1 -v /html:/usr/share/nginx/html busybox
1edf9ade5b9d3cf1517f8a6311f8a617a4af727138ab48add6c20aae8535e647
[root@docker ~]# docker run -itd --name nginx1 -p 8811:80 --volumes-from kami1 nginx
1c9606f160b03ca4c9da5453e39200a723f690d8b4fc22d02cfbd0962092052a
[root@docker ~]# docker run -itd --name nginx2 -p 8812:80 --volumes-from kami1 nginx
edd15acbe17ef5854e3ceef31f1bf682f12cfdff41a45a76a6478d9bed557d0b
[root@docker ~]# docker run -itd --name nginx3 -p 8813:80 --volumes-from kami1 nginx
ed2b88e4dfe4e95262a2a90e651a50de0ef2366a997f2a634d6133ad7d5731bc
[root@docker ~]# curl http://192.168.100.10:8811
test222
[root@docker ~]# curl http://192.168.100.10:8812
test222
[root@docker ~]# curl http://192.168.100.10:8813
test222
修改html内容
[root@docker ~]# echo agito > /html/index.html
[root@docker ~]# curl http://192.168.100.10:8811
agito
[root@docker ~]# curl http://192.168.100.10:8812
agito
[root@docker ~]# curl http://192.168.100.10:8813
agito
与第一种实现数据共享的方法相比,不必再为每个容器指定volemu,所有volume都在volume container 中定义好了,容器只需与volume container关联,实现了容器与Docker host的解耦。
data-packed volume container
使用data-packed volume container,其原理是将数据打包到镜像中,然后通过–volumes-from共享
[root@docker ~]# vim Dockerfile
FROM busybox:latest
ADD html /usr/share/nginx/html
VOLUME /usr/share/nginx/html
CMD ["/bin/bash"]
[root@docker ~]# mkdir html
[root@docker ~]# echo test12341 > html/index.html
[root@docker ~]# docker build -t te .
[root@docker ~]# docker create --name xie1 te
70c6226aa81ed3cf27d484d13aac532f76fad02648054696fb6271dce3e82080
[root@docker ~]# docker run --name xnginx -itd -p 8881:80 --volumes-from xie1 nginx:latest
69e6fd7553f7c03f6277d0c269eec74257d2abd36dd1bf915867fb07c47c9117
测试
[root@docker ~]# curl http://192.168.100.10:8881
test12341
容器能够正确读取volume中的数据。data-packed volume container是自包含的,不依赖Docker host提供数据,具有很强的移植性,非常适合只使用静态数据的场景,比如应用的配置信息、web server的静态文件等。
更多推荐


所有评论(0)