在使用 Docker的过程中,往往需要对容器内应用产生的数据进行持久化,或者需要将容器内数据进行备份,或者需要在多个容器之间进行数据共享,这必然会涉及到容器的数据管理:
- Data Volume (数据卷)
- Data Volume Dontainers (数据卷容器)
数据卷( Data Volume )是一个可供一个或多个容器使用的特殊目录或文件(文件不常使用,容易出错出错,推荐使用目录), 这个目录和宿主机里的某个目录有特殊的映射关联关系,使用类似与 Linux 下对目录或者文件进行 mount(挂载)操作。
数据卷的特征:
- 数据卷可以在容器之间共享和重用,容器之间传递数据将变得高效与方便;
- 对数据卷内数据的修改会立马生效,无论是容器内操作还是宿主机本地操作;
- 对数据卷的更新不会影响镜像,解耦开应用和数据;
- 卷会一直存在,直到没有容器使用,可以安全地卸载它。
1、创建一个数据卷 - docker volume create 命令
在本地创建一个供容器使用和存储数据的新卷。如果未指定名称,则 Docker会生成一个随机名称。
基本语法:docker volume create [OPTIONS] [VOLUME]
OPTIONS说明:
- --driver , -d local 指定卷驱动程序名称
- --label 设置卷的元数据
- --name 指定卷名
- --opt , -o 设置驱动程序特定选项
[root@centos7 ~]# docker volume create vtest1
vtest1
[root@centos7 ~]# docker volume create
93960c97d9ecdb820403d32e288e3fc844dcdadee757b46b3a7bb20a9c7950c0
默认采用内置的 local 驱动创建的本地卷只能被所在节点的容器使用。使用 -d 参数可以指定不同的驱动。
第三方驱动可以通过插件方式接入。这些驱动提供了高级存储特性,并为 Docker 集成了外部存储系统。涵盖了块存储、文件存储、对象存储等。已经存在有二三十种卷插件,涵盖了块存储、文件存储、对象存储等。
- 块存储:相对性能更高,适用于对小块数据的随机访问负载。
- 文件存储:包括 NFS 和 SMB 协议的系统,同样在高性能场景下表现优异。
- 对象存储:适用于较大且长期存储的、很少变更的二进制数据存储。通常对象存储是根据内容寻址,并且性能较低。
2、查看数据卷的信息
1. 列出已知的所有卷 - docker volume ls命令
列出Docker已知的所有卷。您可以使用-f或 --filter标志进行过滤。
基本语法:docker volume ls [OPTIONS]
OPTIONS说明:
- --quiet , -q 仅显示卷名
- --filter , -f 提供过滤器值,格式为“键=值”(例如'dangling = true')
- dangling (boolean - true or false, 0 or 1)
- driver (a volume driver’s name)
- label (label= or label==)
- name (a volume’s name)
[root@centos7 ~]# docker volume ls
DRIVER VOLUME NAME
local 93960c97d9ecdb820403d32e288e3fc844dcdadee757b46b3a7bb20a9c7950c0
local vtest1
2. 显示一个或多个卷上的详细信息 - docker volume inspect 命令
默认情况下,此命令将所有结果呈现在JSON数组中。
基本语法:docker volume inspect [OPTIONS] VOLUME [VOLUME...]
OPTIONS说明:
- --format , -f 使用给定的Go模板格式化输出
[root@centos7 ~]# docker volume inspect vtest1
[
{
"CreatedAt": "2020-09-13T22:08:32+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/vtest1/_data",
"Name": "vtest1",
"Options": {},
"Scope": "local"
}
]
注意:
- Driver 和 Scope 都是 local。这意味着卷使用默认 local 驱动创建,只能用于当前 Docker 主机上的容器。
- Mountpoint 属性说明卷位于 Docker 主机上的位置。使用 local 驱动创建的卷在 Docker 主机上有其专属目录,在 Linux 中位于 /var/lib/docker/volumes 目录下。
查看 /var/lib/docker/volumes路径下,会发现所创建的数据卷。
[root@centos7 ~]# ls /var/lib/docker/volumes
93960c97d9ecdb820403d32e288e3fc844dcdadee757b46b3a7bb20a9c7950c0
vtest1
3、删除 Docker 卷
1. 删除一个或多个未挂载的卷 - docker volume rm命令
删除一个或多个未挂载的卷。不能删除容器正在使用的卷。
基本语法:docker volume rm [OPTIONS] VOLUME [VOLUME...]
OPTIONS说明:
- --force , -f 强制删除一个或多个卷
[root@centos7 ~]# docker volume rm 93960c97d9ecdb820403d32e288e3fc844dcdadee757b46b3a7bb20a9c7950c0
93960c97d9ecdb820403d32e288e3fc844dcdadee757b46b3a7bb20a9c7950c0
2. 删除所有未使用的本地卷 - docker volume prune命令
删除所有未使用的本地卷。未使用的本地卷是任何容器都未引用的卷。谨慎使用!
基本语法:docker volume prune [OPTIONS]
OPTIONS说明:
- --filter 提供过滤器值(例如'label =')
- --force , -f 不提示确认
3、删除正在被使用的数据卷 - docker rm -v 命令
删除正在被使用的数据卷,最后一个和该数据卷绑定的容器删除时,该数据卷也会一起删除。
基本语法:docker [container] rm [OPTIONS] CONTAINER [CONTAINER...]
OPTIONS说明:
- -v, --volumes=false:删除与容器关联的数据卷。
[root@centos7 ~]# docker rm -v containerID
二、使用数据卷
使用 docker [container] run 命令的 --mount 选项来挂载数据卷,也可以使用 -v 选项。
- -t: 让Doker分配一个伪终端并绑定到容器的标准输入上,
- -i: 让容器的标准输人保持打开。
- --name ' ':给容器起别名
- -d: 在后台以守护态(Daemonized)形式运行
- --mount 将文件系统挂载附加到容器,支持三种类型的数据卷,包括:
- volume: 普通数据卷,映射到主机/var/lib/docker/volumes路径下;
- bind: 绑定数据卷,映射到主机指定路径下;
- tmpfs: 临时数据卷,只存在于内存中(不常用)。
1、挂载已创建好的数据卷
创建并启动一个容器,同时使用 --mount type=volume, source= , destination= 把一个已存在的数据卷挂载到该容器的某目录。destination 目录不存在时,会自动创建。
# 先进入数据卷
[root@centos7 ~]# cd /var/lib/docker/volumes/vtest1/_data
[root@centos7 _data]# docker run -dit --mount type=volume,source=vtest1,destination=/test1 centos:7 3709513c58491f1733707b1ee98a5d617626815034a1b675e2195de33d9518f4
查看容器
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3709513c5849 centos:7 "/bin/bash" 52 seconds ago Up 51 seconds focused_borg
[root@centos7 ~]# docker attach 3709513c5849
[root@3709513c5849 /]# ls
anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys test1 tmp usr var
容器和宿主机 source 两边的目录,其中一个里面有更改数据,两边都会立马同步生效。
[root@centos7 _data]# touch a.txt
[root@centos7 _data]# ls
a a.txt
[root@3709513c5849 /]# mkdir /test1/a
[root@3709513c5849 /]# ls /test1/
a a.txt
2、挂载不存在的数据卷到指定目录
创建并启动一个容器,同时使用 --mount type=bind 把一个不存在的数据卷挂载到该容器的某目录。会自动创建该数据卷,然后挂载。
[root@centos7 ~]# mkdir /root/aabbcc
[root@centos7 ~]# docker run -dit --name 'vctos7' --mount type=bind,source=/root/aabbcc,destination=/abc2 centos:7
14849889c78fe8bec39f1418202be42857d5fb145862321a0530613bb44e99f4
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
14849889c78f centos:7 "/bin/bash" 12 seconds ago Up 11 seconds vctos7
[root@centos7 ~]# docker attach vctos7
[root@14849889c78f /]# ls
abc2 anaconda-post.log bin dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
注意:查看数据卷时,默认在 /var/lib/docker/volumes路径下,但是,数据共享已经生效,操作同上。
[root@centos7 ~]# docker volume ls
DRIVER VOLUME NAME
local vtest1
3、使用 -v 选项挂载
type=bind的命令可以使用 -v 选项替换,作用同上,挂载数据卷
[root@centos7 ~]# docker run -dit --name 'v2ctos7' -v /root/aabbcc:/abc22 centos:7
如果 /root/aabbcc: 省略,数据卷默认会在 /var/lib/docker/volumes路径下
[root@centos7 ~]# docker run -dit --name 'v3ctos7' -v abc33 centos:7
0411175b83bef5480afa6b90e8700b7164f295967fbd6a0aab102c4da8007f14
[root@centos7 ~]# docker volume ls
DRIVER VOLUME NAME
local 5095ae7cabdbdcc2da056ce8c464804e6e82690951e8c0157069f5c39dde0ab0
local vtest1
4、指定容器内对所挂载数据卷内的数据为只读
Docker挂载数据卷的默认权限是读写(rw)。
加了 :ro之后,容器内对所挂载数据卷内的数据为只读。无法修改。宿主机这边的 source 读写不影响。
[root@centos7 ~]# docker run -dit --name 'v2ctos7' -v /root/aabbcc:/abc22:ro centos:7
三、数据卷容器 Data Volume Dontainers
数据卷容器本身也是一个容器,和容器的操作一样。
但是它的目的是专门提供数据卷给其他容器挂载的,从而实现在多个容器之间共享一些持续更新的数据。
1、创建一个数据卷容器
创建一个数据卷容器 vdbctos7,并挂载一个数据卷到该容器里的 /dbdata目录。
[root@centos7 ~]# mkdir /root/vdbdata
[root@centos7 ~]# docker run -it --name 'vdbctos7' -v /root/vdbdata:/dbdata centos:7
[root@a33fb1c89ad2 /]# ls
anaconda-post.log bin dbdata dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
2、创建几个容器
创建几个容器,并使用 --volumes-from 来挂载vdbctos7数据卷容器中的数据卷。
- --volumes-from 从其他容器挂载卷
[root@centos7 ~]# docker run -dit --name 'db1' --volumes-from vdbctos7 centos:7
f2df8cdc7b2bed3884db9e621c79d7ae5792c2f636aaa9faddb3610ba8ec63c3
[root@centos7 ~]# docker run -dit --name 'db2' --volumes-from vdbctos7 centos:7
7c330d1e5721d67e61389dbd7c90faef0b3d8c75e1dfc09a1acf0322eb297ef9
此时,容器db1和db2都挂载到同一个数据卷到相同的 /dbdata目录,三个容器任何一方在该目录下的写人,其他容器都可以看到。宿主机 /vdbdata目录中写入,其他容器也都可以看到。
注意:如果删除了挂载的容器(包括vdbctos7、db1和db2),数据卷并不会被自动删除。必须在删除最后一个还挂载着它的容器时显式使用 docker rm -v 命令来指定同时删除关联的容器和数据卷。
四、数据卷容器的备份、恢复、迁移可以利用数据卷对其中的数据进行进行备份、恢复和迁移。
[root@centos7 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7c330d1e5721 centos:7 "/bin/bash" 21 hours ago Up 33 seconds db2
f2df8cdc7b2b centos:7 "/bin/bash" 21 hours ago Up 37 seconds db1
a33fb1c89ad2 centos:7 "/bin/bash" 21 hours ago Up 15 seconds vdbctos7
1、备份
使用下面的命令来备份 vdbctos7数据卷容器内的数据卷 dbdata:
命令格式:# docker run --name 'backupcon' --volumes-from vdbctos7 -v $(pwd):/backup centos:7 tar cvf /backup/backup.tar /dbdata
具体分析:
- 首先利用 centos:7 镜像创建了一个容器backupcon;
- 使用--volumes-from vdbctos7 参数来让 backupcon容器挂载vdbctos7数据卷容器的数据卷(即dbdata 数据卷);
- 使用 -v $(pwd):/backup参数来挂载本地的当前目录到backupcon容器的/backup目录。
- backupcon容器创建启动后,使用 tar cvf /backup/backup.tar /dbdata 命令将 /dbdata下内容备份为容器内的/backup/backup.tar文件。
- 即宿主机当前目录下的backup.tar
通俗的讲,加深印象:
- 其实,backupcon容器也是一个数据卷容器(共享其他容器的可持续更新的/dbdata数据卷数据),
- 同时backupcon容器的/backup目录与宿主机的$(pwd)当前目录映射关联,
- 然后,使用tar命令来打包共享的/dbdata数据卷到backupcon容器的/backup/backup.tar,
- 所以,在宿主机当前目录下可看到backup.tar的备份文件。
- $(pwd) 表示当前目录,也可自定义宿主机路径。
- 也可以使用 docker run 的更多参数来操作 backupcon容器。
例如:完成备份操作后让backupcon容器销毁
--rm,--rm=true|fasle 容器退出后是否自动删除,不能跟 -d 同时使用。
[root@centos7 ~]# mkdir /root/vbackup
[root@centos7 ~]# docker run --rm --name 'backupcon' --volumes-from vdbctos7 -v /root/vbackup:/backup centos:7 tar cvf /backup/backup.tar /dbdata
tar: Removing leading `/' from member names
/dbdata/
/dbdata/db1.txt
/dbdata/db2.txt
/dbdata/vdbctos7.txt
/dbdata/vdbdata.txt
[root@centos7 ~]# ls /root/vbackup/
backup.tar
2、恢复
如果要将上面备份好的 backup.tar文件恢复数据到一个或者多个容器中。使用下面命令:
命令格式:# docker run --name 'backupcon2' --volumes-from vdbctos7 -v $(pwd):/backup centos:7 tar xvf /backup/backup.tar -C /
- tar命令 -C 参数是解压到指定目录中
具体分析:
- 首先利用 centos:7 镜像创建了一个容器backupcon2;
- 使用--volumes-from vdbctos7参数来让 backupcon容器挂载vdbctos7数据卷容器的数据卷(即dbdata 数据卷);
- 使用 -v $(pwd):/backup参数来挂载本地的当前目录到backupcon2容器的/backup目录。
- backupcon2容器创建启动后,使用 tar xvf /backup/backup.tar -C / 命令将 /backup/backup.tar拆到到 backupcon2容器的 / 目录下(或者其他目录,然后文件迁移到容器之间共享的卷中)。
- 所以,与 dbdata 数据卷有映射关联的容器都可以看到恢复的数据。
实例:先把 vdbctos7容器的卷数据删除,然后恢复。
[root@f2df8cdc7b2b dbdata]# rm -rf db1.txt db2.txt vdbctos7.txt vdbdata.txt
[root@f2df8cdc7b2b dbdata]# ll
total 0
[root@centos7 ~]# docker run --rm --name 'backupcon2' --volumes-from vdbctos7 -v /root/vbackup:/backup2 centos:7 tar xvf /backup2/backup.tar -C /
dbdata/
dbdata/db1.txt
dbdata/db2.txt
dbdata/vdbctos7.txt
dbdata/vdbdata.txt
[root@centos7 ~]#
其他容器也恢复数据了。
[root@f2df8cdc7b2b dbdata]# ls
db1.txt db2.txt vdbctos7.txt vdbdata.txt
总结:利用数据卷对其中的数据进行进行备份、恢复和迁移,其实就是创建新容器,挂载数据卷(挂载目录自定义),实现容器之间数据共享,最后使用 tar命令打包拆包。
—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。