企业运维容器之 docker 数据卷
Posted 123坤
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了企业运维容器之 docker 数据卷相关的知识,希望对你有一定的参考价值。
企业运维容器之 docker 数据卷
1. Docker 数据卷管理
- 为什么要用数据卷
docker 分层文件系统:性能差、生命周期与容器相同
docker 数据卷:mount到主机中,绕开分层文件系统;和主机磁盘性能相同,容器删除后依然保留;仅限本地磁盘,不能随容器迁移 - docker 提供了两种卷:
bind mount
docker managed volume
- bind mount
是将主机上的目录或文件 mount 到容器里;使用起来直观高效,易于理解;
使用 -v 选项指定路径,格式 < host path>:< container path>
bind mount 默认权限是读写rw,可以在挂载时指定为只读ro;
-v 选项指定的路径,如果不存在,挂载时会自动创建。
[root@server2 ~]# docker run -it --rm -v /data1:/data1 -v /data2:/data2:ro busybox
/ # ls
bin data2 etc proc sys usr
data1 dev home root tmp var
/ # cd data1/
/data1 # touch zxkfile
/data1 # cd ..
/ # cd data2/
/data2 # touch zxkfile111
touch: zxkfile111: Read-only file system
/data2 #
[root@server2 ~]# cd /data1/
[root@server2 data1]# ls
zxkfile
[root@server2 data1]# cd /data2/
[root@server2 data2]# ls
- docker managed volume
bind mount 必须指定 host 文件系统路径,限制了移植性;
docker managed volume 不需要指定 mount 源,docker 自动为容器创建数据卷目录;
默认创建的数据卷目录都在 /var/lib/docker/volumes 中。
如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。
[root@server2 ~]# docker volume create website
website
[root@server2 ~]# docker volume ls
DRIVER VOLUME NAME
local website
[root@server2 ~]# docker volume inspect website
[
{
"CreatedAt": "2021-05-29T10:42:33+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/website/_data",
"Name": "website",
"Options": {},
"Scope": "local"
}
]
[root@server2 ~]# docker run -d --name demo -v website:/usr/share/nginx/html nginx
c4f8a6668323f110954f9d01adc6f55d0ebdaa3b2cc5fdace9a25e2a20122e22
[root@server2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c4f8a6668323 nginx "/docker-entrypoint.…" 25 seconds ago Up 25 seconds 80/tcp demo
[root@server2 ~]# cd /var/lib/docker/volumes/website/_data
[root@server2 _data]# ls ##会将容器中的数据挂载到目录上
50x.html index.html
[root@server2 _data]# echo www.westos.org > index.html
[root@server2 _data]# curl 172.17.0.2 ##访问运行容器分配到的IP
www.westos.org
[root@server2 _data]# docker inspect demo
"Mounts": [
{
"Type": "volume",
"Name": "website",
"Source": "/var/lib/docker/volumes/website/_data",
"Destination": "/usr/share/nginx/html",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
bind mount与docker managed volume对比
相同点:两者都是 host 文件系统中的某个路径。
不同点:
可以在挂载时将 bind mount
和 docker managed volume
结合起来;
[root@server2 _data]# docker run -d --name demo -v website:/usr/share/nginx/html:ro nginx
230ae47cb89d33be3444600f09f1f6f1348e0fcea2376f04a23135fa9200248f
此时的:ro
是容器内的权限。
2. 卷插件简介
docker 卷默认使用的是 local 类型的驱动,只能存在宿主机,跨主机的volume就需要使用第三方的驱动,可以查看以下链接:
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins
docker官方只提供了卷插件的 api,开发者可以根据实际需求定制卷插件驱动。
https://docs.docker.com/engine/extend/plugins_volume/#volume-plugin-protocol
Docker Plugin 是以 Web Service 的服务运行在每一台 Docker Host上的,通过HTTP协议传输RPC风格的JSON数据完成通信;
Plugin 的启动和停止,并不归Docker管理,Docker Daemon依靠在缺省路径下查找Unix Socket文件,自动发现可用的插件;
当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的 socket 文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求。
3. convoy卷插件
- convoy 卷插件实现
支持三种运行方式:devicemapper、NFS、EBS。
以下实验使用nfs方式。
下载软件:https://github.com/rancher/convoy/releases/download/v0.5.0/ convoy.tar.gz
在所有节点提前挂载NFS存储。
在第一台主机上安装 NFS 存储,然后将其共享;
[root@server1 ~]# yum install -y nfs-utils.x86_64
[root@server1 ~]# mkdir /mnt/nfs
[root@server1 ~]# ll -d /mnt/nfs
drwxr-xr-x 2 root root 6 May 29 11:27 /mnt/nfs
[root@server1 ~]# chmod 777 /mnt/nfs
[root@server1 ~]# vim /etc/exports
[root@server1 ~]# cat /etc/exports ##不转换 root 用户身份
/mnt/nfs *(rw,no_root_squash)
[root@server1 ~]# systemctl start nfs
[root@server1 ~]# showmount -e
Export list for server1:
/mnt/nfs *
在第二台主机上将共享的进行挂载;然后挂载之后写入文件,看其是否挂载完整;
[root@server2 ~]# docker volume rm website
website
[root@server2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@server2 ~]# docker volume prune ##清除不用的卷
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
[root@server2 ~]# yum install nfs-utils.x86_64 -y
[root@server2 ~]# mkdir /mnt/nfs
[root@server2 ~]# mount 172.25.15.1:/mnt/nfs/ /mnt/nfs/
[root@server2 ~]# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/rhel-root 17811456 1796500 16014956 11% /
devtmpfs 1011444 0 1011444 0% /dev
tmpfs 1023468 0 1023468 0% /dev/shm
tmpfs 1023468 16988 1006480 2% /run
tmpfs 1023468 0 1023468 0% /sys/fs/cgroup
/dev/vda1 1038336 135088 903248 14% /boot
tmpfs 204696 0 204696 0% /run/user/0
172.25.15.1:/mnt/nfs 17811456 5452288 12359168 31% /mnt/nfs
[root@server2 ~]# cd /mnt/nfs/
[root@server2 nfs]# touch file1
[root@server2 nfs]# touch zxkfile1
[root@server2 nfs]# ll
total 0
-rw-r--r-- 1 root root 0 May 29 11:30 file1
-rw-r--r-- 1 root root 0 May 29 11:30 zxkfile1
在第一台主机上查看写入的内容,说明挂载没有问题;
[root@server1 ~]# cd /mnt/nfs/
[root@server1 nfs]# ls
file1 zxkfile1
[root@server1 nfs]# ll
total 0
-rw-r--r-- 1 root root 0 May 29 11:30 file1
-rw-r--r-- 1 root root 0 May 29 11:30 zxkfile1
- convoy卷插件安装:
可以从官网下载,此处直接将已经下载好的包来解压;
[root@server1 ~]# tar zxf convoy.tar.gz
[root@server1 ~]# ls
base-debian10.tar convoy convoy.tar.gz docker harbor harbor-offline-installer-v1.10.1.tgz rhel7.tar
[root@server1 ~]# cd convoy/
[root@server1 convoy]# ls
convoy convoy-pdata_tools SHA1SUMS
[root@server1 convoy]# cp convoy* /usr/local/bin/
##将二进制程序复制到系统环境中
[root@server1 convoy]# mkdir -p /etc/docker/plugins/
##创建插件目录
[root@server1 convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[root@server1 convoy]# ps ax
26180 pts/0 Sl 0:00 convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs
[root@server1 convoy]# cd /var/run/convoy/
[root@server1 convoy]# ls ##会有一个sock 文件,
convoy.sock
[root@server1 convoy]# echo "unix:var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
##创建默认扫描文件。命名规则为卷名称加.spec
[root@server1 convoy]# cat /etc/docker/plugins/convoy.spec
unix:var/run/convoy/convoy.sock
[root@server1 convoy]# docker volume ls
##此时查看时会看到新建的卷信息
DEBU[0348] Handle plugin activate: POST /Plugin.Activate pkg=daemon
DEBU[0348] Response: {
"Implements": [
"VolumeDriver"
]
} pkg=daemon
DEBU[0348] Handle plugin list volume: POST /VolumeDriver.List pkg=daemon
DEBU[0348] Successfully got volume list for docker. pkg=daemon
DEBU[0348] Response: {} pkg=daemon
DRIVER VOLUME NAME
local 7c342c18f10f6dbd21b2a4b5cc3247524a34b7c121619b5d5f18c575195ae305
local 16e4cf77380b6e44a1d303aff980c9a5fa2c92f370d6a06502a9804130e79419
local 880e08098df4d779af609547d7a6566f024959308f68b14e5a2c97eba94ecf3e
local 5448e97b5787e41257959201c8fd2e9fd29b872006e81425a8d319012629c935
local ac6099385cca02031765fc2592c7a4fcbb63e502aaa76017b753d8da02737348
local bafd00a8486bde75e887c2c2b60fee74b2f841d00f76829714f26f98606b93c7
local ced83e3b56c21f1e868a747a30f9f3080a4f23b25a49953c31ceae3e59ea9b78
local dbf67c39bc5c2f0be328650845a00b61a436f6bad71e58d1ff98a33074f66b16
local fa34e96e88bbfd3d373f011b006bb2c94640ec7347a3e3038814705273bf94e3
local ff365d32c54fe53501d2e147e2f5583be699d631f12df758fa7dd7e9e15ad79c
创建卷:
在第一台主机上创建卷;
[root@server1 convoy]# convoy create vol1
DEBU[0409] Calling: POST, /volumes/create, request: POST, /v1/volumes/create pkg=daemon
DEBU[0409] event=create object=volume opts=map[PrepareForVM:false Size:0 BackupURL: VolumeName:vol1 VolumeDriverID: VolumeType: VolumeIOPS:0] pkg=daemon reason=prepare volume=vol1
DEBU[0409] Created volume event=create object=volume pkg=daemon reason=complete volume=vol1
DEBU[0409] Response: vol1 pkg=daemon
vol1
[root@server1 convoy]# convoy list
{
"vol1": {
"Name": "vol1",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Sat May 29 11:42:23 +0800 2021",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol1",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Sat May 29 11:42:23 +0800 2021",
"VolumeName": "vol1"
},
"Snapshots": {}
}
}
[root@server1 convoy]# docker volume ls
##再次查看时会有
convoy vol1
使用卷:
在第二台主机上使用卷;
[root@server2 ~]# cd /etc/docker/
[root@server2 docker]# ls
certs.d daemon.json key.json plugins
[root@server2 docker]# cd plugins
[root@server2 plugins]# ls
convoy.spec
[root@server2 plugins]# cat convoy.spec
unix:var/run/convoy/convoy.sock
[root@server2 plugins]# cd /usr/local/bin/
[root@server2 bin]# ls
convoy convoy-pdata_tools
[root@server2 nfs]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[root@server2 nfs]# ps ax
5849 pts/0 Sl 0:00 convoy daemon --drivers vfs --driver-opts vf
[root@server2 nfs]# convoy list
{
"vol1": {
"Name": "vol1",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Sat May 29 11:42:23 +0800 2021",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol1",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Sat May 29 11:42:23 +0800 2021",
"VolumeName": "vol1"
},
"Snapshots": {}
}
}
[root@server2 ~]# cd /mnt/nfs/
[root@server2 nfs]# ls
config vol1
在 vol1 卷中写入数据,会自动存储到物理主机中;
[root@server1 docker]# docker run -it --rm -v vol1:/data busybox
/ # cd /data/
/data # ls
/data # touch file
/data # touch zxkfile
[root@server1 docker]# cd /mnt/nfs/vol1/
[root@server1 vol1]# ls
file zxkfile
在第二台主机上用相同的指令,来运行容器,会看到数据;基础的逻辑还是 nfs 系统;
[root@server2 ~]# docker run -it --rm -v vol1:/data busybox
/ # cd /data/
/data # ls
file zxkfile
/data #
当在一个结点回收卷时,所有结点都会回收;
[root@server2 ~]# convoy delete vol1
DEBU[0446] Calling: DELETE, /volumes/, request: DELETE, /v1/volumes/ pkg=daemon
DEBU[0446] event=delete object=volume pkg=daemon reason=prepare volume=vol1
DEBU[0446] Cleaning up /mnt/nfs/vol1 for volume vol1 pkg=vfs
DEBU[0446] event=delete object=volume pkg=daemon reason=complete volume=vol1
[root@server2 ~]# convoy list
{}
[root@server1 ~]# convoy list
{}
当不需要插件信息时,删除过程如下:
[root@server2 ~]# cd /etc/docker/plugins/
[root@server2 plugins]# ls
convoy.spec
[root@server2 plugins]# rm -f convoy.spec
[root@server2 plugins]# ls
[root@server2 ~]# ps ax
[root@server2 ~]# kill 5849 ##结束进程
[root@server2 ~]# systemctl restart docker
##此时在重启时会非常慢,可以删除数据再次启动就快了
[root@server2 ~]# cd /var/lib/docker/volumes/
[root@server2 volumes]# ls
metadata.db
[root@server2 volumes]# rm -f metadata.db
[root@server2 volumes]# systemctl restart docker
##删除之后此时再次启动就快了
对于第一台主机上的删除,此时也可以需要同样的操作来结束进程。
4. 总结
对于 docker 数据卷的管理,以及第三方的卷插件的使用进行了学习,以下为一些常用的命令:
- convoy卷插件子命令;
- convoy list 列出卷;
- convoy delete 删除卷;
- convoy snapshot create 创建快照;
- convoy snapshot delete 删除快照;
- convoy backup create 创建备份;
- convoy create res1 --backup < url> 还原备份
以上是关于企业运维容器之 docker 数据卷的主要内容,如果未能解决你的问题,请参考以下文章