目录
1).bind mount
是将主机上的目录或文件 mount 到容器里;使用起来直观高效,易于理解;
使用 -v 选项指定路径,格式 < host path>:< container path>
bind mount 默认权限是读写rw,可以在挂载时指定为只读ro;
-v 选项指定的路径,如果不存在,挂载时会自动创建。
- [root@node11 ~]# docker run -it --rm -v /web1:/web1 busybox 挂接到容器内权限默认时读写
- / # ls
- bin dev etc home proc root sys tmp usr var web1
- / # cd /web1
- /web1 # ls
- /web1 # touch file
- /web1 #
- [root@node11 ~]# cd /web1
- [root@node11 web1]# ls
- file
- [root@node11 web1]# docker run -it --rm -v /web1:/web1 -v /web2:/web2:ro busybox挂接到容器内,web2权限为只读
- / # ls
- bin dev etc home proc root sys tmp usr var web1 web2
- / # cd /web1
- /web1 # ls
- file
- /web1 # rm -rf file
- /web1 # ls
- /web1 # cd
- ~ # cd /web2
- /web2 # touch file2
- touch: file2: Read-only file system
- /web2 #
- [root@node11 web1]# ls
- [root@node11 web1]# docker run -it --rm -v /web1:/web1 -v /web2:/web2:ro -v /etc/passwd:/passwd:ro busybox 挂接文件到容器内
- / # ls
- bin dev etc home passwd proc root sys tmp usr var web1 web2
- / # cat passwd
- root:x:0:0:root:/root:/bin/bash
- bin:x:1:1:bin:/bin:/sbin/nologin
- daemon:x:2:2:daemon:/sbin:/sbin/nologin
- adm:x:3:4:adm:/var/adm:/sbin/nologin
- lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
- sync:x:5:0:sync:/sbin:/bin/sync
- shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
- halt:x:7:0:halt:/sbin:/sbin/halt
- mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
- operator:x:11:0:operator:/root:/sbin/nologin
- games:x:12:100:games:/usr/games:/sbin/nologin
- ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
- nobody:x:99:99:Nobody:/:/sbin/nologin
- systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
- dbus:x:81:81:System message bus:/:/sbin/nologin
- polkitd:x:999:998:User for polkitd:/:/sbin/nologin
- libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
- abrt:x:173:173::/etc/abrt:/sbin/nologin
- rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
- apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
- sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
- postfix:x:89:89::/var/spool/postfix:/sbin/nologin
- ntp:x:38:38::/etc/ntp:/sbin/nologin
- chrony:x:997:995::/var/lib/chrony:/sbin/nologin
- tcpdump:x:72:72::/:/sbin/nologin
- / # rm -rf passwd
- rm: can't remove 'passwd': Device or resource busy
- / #
2).docker managed volume
bind mount 必须指定 host 文件系统路径,限制了移植性;
docker managed volume 不需要指定 mount 源,docker 自动为容器创建数据卷目录;
默认创建的数据卷目录都在 /var/lib/docker/volumes 中。
如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。
- [root@node11 ~]# 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
- [root@node11 ~]# docker run -d --name vm1 registry
- 48cf5d7fabec8f7fce8b30b3996c9e262231fb554272f29d760e66f58d001f7c
- [root@node11 ~]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 48cf5d7fabec registry "/entrypoint.sh /etc…" 7 seconds ago Up 6 seconds 5000/tcp vm1
- [root@node11 ~]# docker inspect vm1
- "Mounts": [
- {
- "Type": "volume",
- "Name": "b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585",
- "Source": "/var/lib/docker/volumes/b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585/_data",
- "Destination": "/var/lib/registry",
- "Driver": "local",
- "Mode": "",
- "RW": true,
- "Propagation": ""
- [root@node11 ~]# docker rm -f vm1
- vm1
- [root@node11 ~]# docker volume ls
- DRIVER VOLUME NAME
- local b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585
- [root@node11 ~]# docker volume rm b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585
- b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585
- [root@node11 ~]# docker volume create vol1
- vol1
- [root@node11 ~]# docker volume ls
- DRIVER VOLUME NAME
- local vol1
- [root@node11 ~]# docker volume inspect vol1
- [
- {
- "CreatedAt": "2022-08-22T16:44:12+08:00",
- "Driver": "local",
- "Labels": {},
- "Mountpoint": "/var/lib/docker/volumes/vol1/_data",
- "Name": "vol1",
- "Options": {},
- "Scope": "local"
- }
- ]
- [root@node11 ~]# docker run -d --name vm1 -v vol1:/usr/share/nginx/html nginx
- b045af5d6ea57bab7171d792cdbaff6298ed9a9da3cfe2f27c424ae6c484a7c6
- [root@node11 ~]# docker inspect vm1
- "Mounts": [
- {
- "Type": "volume",
- "Name": "vol1",
- "Source": "/var/lib/docker/volumes/vol1/_data",
- "Destination": "/usr/share/nginx/html",
- "Driver": "local",
- "Mode": "z",
- "RW": true,
- "Propagation": ""
- [root@node11 ~]# cd /var/lib/docker/
- [root@node11 docker]# cd volumes/
- [root@node11 volumes]# ls
- backingFsBlockDev metadata.db vol1
- [root@node11 volumes]# cd vol1/
- [root@node11 vol1]# cd _data/
- [root@node11 _data]# ls
- 50x.html index.html 当挂接到容器会将数据从容器内拷到宿主机
bind mount与docker managed volume对比
相同点:两者都是 host 文件系统中的某个路径。
不同点:
| bind mount | docker managed volume | |
| volume 位置 | 可任意指定 | /var/lib/docker/volumes/... |
| 对已有mount point 影响 | 隐藏并替换为volume | 原有数据复制到volume |
| 是否支持单个文件 | 支持 | 不支持,只能是目录 |
| 权限控制 | 可设置为只读,默认为读写权限 | 无控制,均为读写权限 |
| 移植性 | 移植性弱,与 host path 绑定 | 移植性强,无需指定 host 目录 |
可以在挂载时将 bind mount 和 docker managed volume 结合起来;
- [root@node11 ~]# docker create --name datavol -v /web1:/web1 -v /web2:/web2:ro busybox
- b5e7431fffc8cd073720cf042a30bb2e89be0ee54a2119637382363b2e0111ce
- [root@node11 ~]# docker ps -a
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- b5e7431fffc8 busybox "sh" 7 seconds ago Created datavol
- [root@node11 ~]# docker run -it --rm --volumes-from datavol busybox
- / # ls
- bin dev etc home proc root sys tmp usr var web1 web2
- / # cd web1
- /web1 # ls
- /web1 # cd ..
- / # cd web2
- /web2 # ls
- /web2 #
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自身的处理完成客户端的请求。
convoy 卷插件实现
支持三种运行方式:devicemapper、NFS、EBS。
以下实验使用nfs方式。
下载软件:https://github.com/rancher/convoy/releases/download/v0.5.0/ convoy.tar.gz
在所有节点提前挂载NFS存储。
1).在第一台主机上安装 NFS 存储,然后将其共享;
- [root@node11 bin]# mkdir /mnt/nfs
- [root@node11 bin]# ll -d /mnt/nfs/
- drwxr-xr-x 2 root root 6 Aug 23 10:35 /mnt/nfs/
- [root@node11 bin]# chmod 777 /mnt/nfs/
- [root@node11 bin]# yum install -y nfs-utils
- [root@node11 bin]# vim /etc/exports
- [root@node11 bin]# cat /etc/exports
- /mnt/nfs *(rw,no_root_squash)
- [root@node11 bin]# systemctl start nfs
- [root@node11 bin]# showmount -e
- Export list for node11:
- /mnt/nfs *
-
- [root@node22 ~]# yum install nfs-utils.x86_64 -y
- [root@node22 ~]# mkdir /mnt/nfs
- [root@node22 ~]# mount 192.168.0.11:/mnt/nfs/ /mnt/nfs/
- [root@node22 ~]# df
- Filesystem 1K-blocks Used Available Use% Mounted on
- /dev/mapper/rhel-root 28289540 1865264 26424276 7% /
- devtmpfs 485764 0 485764 0% /dev
- tmpfs 497948 0 497948 0% /dev/shm
- tmpfs 497948 7960 489988 2% /run
- tmpfs 497948 0 497948 0% /sys/fs/cgroup
- /dev/sda1 1038336 138088 900248 14% /boot
- /dev/sr0 4391278 4391278 0 100% /rhel7.6
- tmpfs 99592 0 99592 0% /run/user/0
- 192.168.0.11:/mnt/nfs 28289664 5737600 22552064 21% /mnt/nfs
- [root@node22 ~]# cd /mnt/nfs/
2)convoy卷插件安装:
- [root@node11 ~]# tar zxf convoy-v0.5.2.tar.gz
- [root@node11 ~]# cd convoy/
- [root@node11 convoy]# ls
- convoy convoy-pdata_tools SHA1SUMS
- [root@node11 convoy]# cp convoy* /usr/local/bin/
- [root@node11 convoy]# cd /usr/local/bin/
- [root@node11 bin]# ls
- convoy convoy-pdata_tools docker-compose
- [root@node11 bin]# scp convoy* node22:/usr/local/bin/
- root@node22's password:
- convoy 100% 17MB 25.1MB/s 00:00
- convoy-pdata_tools 100% 22MB 40.7MB/s 00:00
- [root@node11 bin]# cd /mnt/nfs/
- [root@node11 nfs]# mkdir -p /etc/docker/plugins/
- [root@node11 nfs]# cd /etc/docker/plugins/
- [root@node11 plugins]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
- [root@node11 plugins]# cat /etc/docker/plugins/convoy.spec
- unix:///var/run/convoy/convoy.sock
- [root@node11 docker]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
- [1] 29087
- DEBU[0000] Creating config at /var/lib/rancher/convoy pkg=daemon
- DEBU[0000] driver=vfs driver_opts=map[vfs.path:/mnt/nfs] event=init pkg=daemon reason=prepare root=/var/lib/rancher/convoy
- DEBU[0000] driver=vfs event=init pkg=daemon reason=complete
- DEBU[0000] Registering DELETE, /volumes/ pkg=daemon
- DEBU[0000] Registering DELETE, /snapshots/ pkg=daemon
- DEBU[0000] Registering DELETE, /backups pkg=daemon
- DEBU[0000] Registering GET, /backups/list pkg=daemon
- DEBU[0000] Registering GET, /backups/inspect pkg=daemon
- DEBU[0000] Registering GET, /info pkg=daemon
- DEBU[0000] Registering GET, /volumes/list pkg=daemon
- DEBU[0000] Registering GET, /volumes/ pkg=daemon
- DEBU[0000] Registering GET, /snapshots/ pkg=daemon
- DEBU[0000] Registering POST, /snapshots/create pkg=daemon
- DEBU[0000] Registering POST, /backups/create pkg=daemon
- DEBU[0000] Registering POST, /volumes/create pkg=daemon
- DEBU[0000] Registering POST, /volumes/mount pkg=daemon
- DEBU[0000] Registering POST, /volumes/umount pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Remove pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Path pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.List pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Unmount pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Get pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Capabilities pkg=daemon
- DEBU[0000] Registering plugin handler POST, /Plugin.Activate pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Create pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Mount pkg=daemon
-
- [root@node11 ~]# docker volume create -d convoy vol1
- [root@node11 ~]# convoy list
- {
- "vol1": {
- "Name": "vol1",
- "Driver": "vfs",
- "MountPoint": "",
- "CreatedTime": "Tue Aug 23 10:59:04 +0800 2022",
- "DriverInfo": {
- "Driver": "vfs",
- "MountPoint": "",
- "Path": "/mnt/nfs/vol1",
- "PrepareForVM": "false",
- "Size": "0",
- "VolumeCreatedAt": "Tue Aug 23 10:59:04 +0800 2022",
- "VolumeName": "vol1"
- },
- "Snapshots": {}
- }
- }
在node22主机配置:
- [root@node22 nfs]# mkdir -p /etc/docker/plugins/
- [root@node22 nfs]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
- [root@node22 nfs]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
- [1] 9468
- [root@node22 nfs]# DEBU[0000] Creating config at /var/lib/rancher/convoy pkg=daemon
- DEBU[0000] driver=vfs driver_opts=map[vfs.path:/mnt/nfs] event=init pkg=daemon reason=prepare root=/var/lib/rancher/convoy
- DEBU[0000] driver=vfs event=init pkg=daemon reason=complete
- DEBU[0000] Registering POST, /volumes/create pkg=daemon
- DEBU[0000] Registering POST, /volumes/mount pkg=daemon
- DEBU[0000] Registering POST, /volumes/umount pkg=daemon
- DEBU[0000] Registering POST, /snapshots/create pkg=daemon
- DEBU[0000] Registering POST, /backups/create pkg=daemon
- DEBU[0000] Registering DELETE, /volumes/ pkg=daemon
- DEBU[0000] Registering DELETE, /snapshots/ pkg=daemon
- DEBU[0000] Registering DELETE, /backups pkg=daemon
- DEBU[0000] Registering GET, /info pkg=daemon
- DEBU[0000] Registering GET, /volumes/list pkg=daemon
- DEBU[0000] Registering GET, /volumes/ pkg=daemon
- DEBU[0000] Registering GET, /snapshots/ pkg=daemon
- DEBU[0000] Registering GET, /backups/list pkg=daemon
- DEBU[0000] Registering GET, /backups/inspect pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Unmount pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Path pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Get pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.List pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Create pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Remove pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Mount pkg=daemon
- DEBU[0000] Registering plugin handler POST, /Plugin.Activate pkg=daemon
- DEBU[0000] Registering plugin handler POST, /VolumeDriver.Capabilities pkg=daemon
-
- [root@node22 nfs]# ls
- config vol1
- [root@node22 nfs]# convoy list
- {
- "vol1": {
- "Name": "vol1",
- "Driver": "vfs",
- "MountPoint": "",
- "CreatedTime": "Tue Aug 23 10:59:04 +0800 2022",
- "DriverInfo": {
- "Driver": "vfs",
- "MountPoint": "",
- "Path": "/mnt/nfs/vol1",
- "PrepareForVM": "false",
- "Size": "0",
- "VolumeCreatedAt": "Tue Aug 23 10:59:04 +0800 2022",
- "VolumeName": "vol1"
- },
- "Snapshots": {}
- }
- }
- [root@node11 ~]# docker run -d --name vm1 -v vol1:/usr/share/nginx/html nginx
- [root@node11 ~]# docker inspect vm1
- "Mounts": [
- {
- "Type": "volume",
- "Name": "vol1",
- "Source": "",
- "Destination": "/usr/share/nginx/html",
- "Driver": "convoy",
- "Mode": "",
- "RW": true,
- "Propagation": ""
- }
- ],
- [root@node11 ~]# cd /mnt/nfs/
- [root@node11 nfs]# cd vol1/
- [root@node11 vol1]# ls
- 50x.html index.html
- [root@node11 vol1]# echo www.westos.org > index.html
- [root@node11 vol1]# curl 172.17.0.2
- www.westos.org
- [root@node11 vol1]# docker save nginx:latest -o nginx.tar
- [root@node11 vol1]# scp nginx.tar node22:
- root@node22's password:
- nginx.tar 100% 139MB 7.8MB/s 00:17
- [root@node22 ~]# docker load -i nginx.tar
- [root@node22 ~]# docker run -d --name vm1 -v vol1:/usr/share/nginx/html nginx
- [root@node22 ~]# curl 172.17.0.2
- www.westos.org
- [root@node22 ~]# cd /mnt/nfs
- [root@node22 nfs]# cd vol1/
- [root@node22 vol1]# cat index.html
- www.westos.org
- 当在一个结点回收卷时,所有结点都会回收;
- [root@node22 vol1]# convoy delete vol1
- DEBU[0987] Calling: DELETE, /volumes/, request: DELETE, /v1/volumes/ pkg=daemon
- DEBU[0987] event=delete object=volume pkg=daemon reason=prepare volume=vol1
- DEBU[0987] Cleaning up /mnt/nfs/vol1 for volume vol1 pkg=vfs
- DEBU[0987] event=delete object=volume pkg=daemon reason=complete volume=vol1
- [root@node22 vol1]# cd /mnt/nfs/
- [root@node22 nfs]# ls
- config
- 当不需要插件信息时,删除过程如下:
- [root@node11 nfs]# cd /etc/docker
- [root@node11 docker]# cd plugins/
- [root@node11 plugins]# rm -rf convoy.spec
- [root@node11 plugins]# ls
- [root@node11 plugins]# docker volume ls
- DEBU[1483] Handle plugin list volume: POST /VolumeDriver.List pkg=daemon
- DEBU[1483] Successfully got volume list for docker. pkg=daemon
- DEBU[1483] Response: {} pkg=daemon
- DRIVER VOLUME NAME
- [root@node11 plugins]# systemctl restart docker
- [root@node11 plugins]# docker volume ls
- DRIVER VOLUME NAME
- 对于另一台主机上的删除,此时也可以需要同样的操作来结束进程。
- [root@node22 nfs]# fg
- convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs
- ^CCaught signal interrupt: shutting down.
- DEBU[1303] Cleaning up environment... pkg=daemon
- ERRO[1303] http server erroraccept unix /var/run/convoy/convoy.sock: use of closed network connection pkg=daemon
- [root@node22 nfs]# cd /etc/docker/plugins/
- [root@node22 plugins]# rm -f convoy.spec
- [root@node22 plugins]# systemctl restart docker
- [root@node22 plugins]# docker volume ls
- DRIVER VOLUME NAME
对于 docker 数据卷的管理,以及第三方的卷插件的使用进行了学习,以下为一些常用的命令:
convoy卷插件子命令;
convoy list 列出卷;
convoy delete 删除卷;
convoy snapshot create 创建快照;
convoy snapshot delete 删除快照;
convoy backup create 创建备份;
convoy create res1 --backup < url> 还原备份