存储
-
Docker为容器提供了两种存放数据的资源:
- 由storage driver管理的镜像层和容器层:适用于无状态的应用,并且没有需要持久化的数据,比如busybox之类的
- Data Volume:需要持久化数据的容器
-
分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于Docker storage driver。Docker支持多种storage driver,有AUFS、Device Mapper、Btrfs、OverlayFS、VFS和ZFS。没有哪个driver能够适应所有的场景,最佳实践是优先使用Linux发行版默认的storage driver。Docker安装时会根据当前系统的配置选择默认的driver。默认driver具有最好的稳定性,因为默认driver在发行版上经过了严格的测试。
1. 着重查看 Storage Driver: overlay2信息 $ docker info Client: Debug Mode: false Server: Containers: 3 Running: 3 Paused: 0 Stopped: 0 Images: 109 Server Version: 19.03.9 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: inactive Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd init version: fec3683 Security Options: seccomp Profile: default Kernel Version: 4.4.227-1.el7.elrepo.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 2 Total Memory: 3.842GiB Name: jannal.docker.com ID: XKUN:GE65:TC7N:YAEW:VWVN:247J:EQ24:HZ2S:YSFG:ZL7P:IBUK:RN2L Docker Root Dir: /var/lib/docker Debug Mode: false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://7m2taepc.mirror.aliyuncs.com/ Live Restore Enabled: false
数据卷(Data Volume)
-
Data Volume本质上是Docker Host文件系统中的目录或文件,能够直接被mount到容器的文件系统中
- Data Volume是目录或文件,而非没有格式化的磁盘(块设备)
- 容器可以读写volume中的数据
- volume数据可以被永久地保存,即使使用它的容器已经销毁。数据卷可以在容器之间共享和重用,容器间传递数据将变得高效与方便
- volume实际上是docker host文件系统的一部分,所以volume的容量取决于文件系统当前未使用的空间,目前还没有方法设置volume的容量
- docker提供了两种类型的volume:bind mount和docker managed volume
-
bind mount:将host上已存在的目录或文件mount到容器。默认是可读可写
-
-v的格式为 <host path>:<container path>
-
设置只读权限
-v /root:/root:ro
-
指定一个文件
-v /root/a.txt:/root/a_new.txt
。使用单一文件需要注意,host中的源文件必须要存在,不然会当作一个新目录bind mount给容器。 -
指定一个目录
-v /root/install/:/root:install/:rw
-
-
docker managed volume:
-
bind mount需要指定host文件系统的特定路径,这就限制了容器的可移植性。docker managed volume不需要指定mount源,只需要指明
mount point
-v
-
bind mount需要指定host文件系统的特定路径,这就限制了容器的可移植性。docker managed volume不需要指定mount源,只需要指明
-
示例
通过-v告诉docker需要一个data volume,并将其mount到/root/a.txt $ docker run -it --name data-busybox -v "/root/a.txt" busybox 查看data volume 具体的位置 $ docker inspect c94fb9f45eea ...省略... "Mounts": [ { "Type": "volume", "Name": "6504feb75a4eafeb3b9049da2bacc6d37a20b046f23e752d1e48774510a18bd7", "Source": "/var/lib/docker/volumes/6504feb75a4eafeb3b9049da2bacc6d37a20b046f23e752d1e48774510a18bd7/_data", "Destination": "/root/a.txt", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ] ...省略... $ docker volume ls DRIVER VOLUME NAME local 3232b71e69b26e362ac8032577982d7a85847537d4eb4aa2cf54270419988621 local 6504feb75a4eafeb3b9049da2bacc6d37a20b046f23e752d1e48774510a18bd7 docker volume只能查看docker managed volume,还看不到bind mount; 同时也无法知道volume对应的容器,这些信息还得靠docker inspect。 $ docker volume inspect 6504feb75a4eafeb3b9049da2bacc6d37a20b046f23e752d1e48774510a18bd7 [ { "CreatedAt": "2021-09-17T10:27:17+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/6504feb75a4eafeb3b9049da2bacc6d37a20b046f23e752d1e48774510a18bd7/_data", "Name": "6504feb75a4eafeb3b9049da2bacc6d37a20b046f23e752d1e48774510a18bd7", "Options": null, "Scope": "local" } ]
-
每当容器申请mount docker manged volume时,docker都会在
/var/lib/docker/volumes
下生成一个目录,这个目录就是mount源。由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据复制到volume中
复制数据
-
docker cp
可以在容器与Host之间复制数据。也可以直接通过Linux的cp命令复制到/var/lib/docker/volumes/xxx
容器间共享数据
-
共享数据方式
- 共享数据放在bind mount中,然后将其mount到多个容器
- 使用volume container(专门为其他容器提供volume的容器),提供的卷可以是bind mount,也可以是docker managed volume
-
创建数据卷容器
1. 数据卷的作用只是提供数据,它本身不需要处于运行状态 $ docker create --name vc_my \ -v /root/a.txt \ -v /root/b.txt:/root/bb.txt \ busybox ea764715a12d9073d2722ac07fd54a819996f1d3fa8c46252d9728ffb23a0b2d 查看卷容器 $ docker inspect vc_my --volumes-from使用数据卷容器 $ docker run -it --name data0-busybox -volumes-from=vc_my busybox
-
删除孤儿volume
$ docker volume rm $(docker volume ls -q)