• 企业运维容器之 docker 数据卷


    目录

    1. Docker 数据卷管理

    2. 卷插件简介

    3. convoy卷插件

    4. 总结

    1. Docker 数据卷管理

    • 为什么要用数据卷
      docker 分层文件系统:性能差、生命周期与容器相同
      docker 数据卷:mount到主机中,绕开分层文件系统;和主机磁盘性能相同,容器删除后依然保留;仅限本地磁盘,不能随容器迁移
    • docker 提供了两种卷:
      bind mount
      docker managed volume

    1).bind mount

    是将主机上的目录或文件 mount 到容器里;使用起来直观高效,易于理解;

    使用 -v 选项指定路径,格式 < host path>:< container path>

    bind mount 默认权限是读写rw,可以在挂载时指定为只读ro;

    -v 选项指定的路径,如果不存在,挂载时会自动创建。

    1. [root@node11 ~]# docker run -it --rm -v /web1:/web1 busybox 挂接到容器内权限默认时读写
    2. / # ls
    3. bin dev etc home proc root sys tmp usr var web1
    4. / # cd /web1
    5. /web1 # ls
    6. /web1 # touch file
    7. /web1 #
    8. [root@node11 ~]# cd /web1
    9. [root@node11 web1]# ls
    10. file
    11. [root@node11 web1]# docker run -it --rm -v /web1:/web1 -v /web2:/web2:ro busybox挂接到容器内,web2权限为只读
    12. / # ls
    13. bin dev etc home proc root sys tmp usr var web1 web2
    14. / # cd /web1
    15. /web1 # ls
    16. file
    17. /web1 # rm -rf file
    18. /web1 # ls
    19. /web1 # cd
    20. ~ # cd /web2
    21. /web2 # touch file2
    22. touch: file2: Read-only file system
    23. /web2 #
    24. [root@node11 web1]# ls
    25. [root@node11 web1]# docker run -it --rm -v /web1:/web1 -v /web2:/web2:ro -v /etc/passwd:/passwd:ro busybox 挂接文件到容器内
    26. / # ls
    27. bin dev etc home passwd proc root sys tmp usr var web1 web2
    28. / # cat passwd
    29. root:x:0:0:root:/root:/bin/bash
    30. bin:x:1:1:bin:/bin:/sbin/nologin
    31. daemon:x:2:2:daemon:/sbin:/sbin/nologin
    32. adm:x:3:4:adm:/var/adm:/sbin/nologin
    33. lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
    34. sync:x:5:0:sync:/sbin:/bin/sync
    35. shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
    36. halt:x:7:0:halt:/sbin:/sbin/halt
    37. mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
    38. operator:x:11:0:operator:/root:/sbin/nologin
    39. games:x:12:100:games:/usr/games:/sbin/nologin
    40. ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
    41. nobody:x:99:99:Nobody:/:/sbin/nologin
    42. systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    43. dbus:x:81:81:System message bus:/:/sbin/nologin
    44. polkitd:x:999:998:User for polkitd:/:/sbin/nologin
    45. libstoragemgmt:x:998:997:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
    46. abrt:x:173:173::/etc/abrt:/sbin/nologin
    47. rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
    48. apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
    49. sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
    50. postfix:x:89:89::/var/spool/postfix:/sbin/nologin
    51. ntp:x:38:38::/etc/ntp:/sbin/nologin
    52. chrony:x:997:995::/var/lib/chrony:/sbin/nologin
    53. tcpdump:x:72:72::/:/sbin/nologin
    54. / # rm -rf passwd
    55. rm: can't remove 'passwd': Device or resource busy
    56. / #

    2).docker managed volume

    bind mount 必须指定 host 文件系统路径,限制了移植性;

    docker managed volume 不需要指定 mount 源,docker 自动为容器创建数据卷目录;

    默认创建的数据卷目录都在 /var/lib/docker/volumes 中。

    如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。

    1. [root@node11 ~]# docker volume prune 删除没有被容器占用的卷
    2. WARNING! This will remove all local volumes not used by at least one container.
    3. Are you sure you want to continue? [y/N] y
    4. [root@node11 ~]# docker run -d --name vm1 registry
    5. 48cf5d7fabec8f7fce8b30b3996c9e262231fb554272f29d760e66f58d001f7c
    6. [root@node11 ~]# docker ps
    7. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    8. 48cf5d7fabec registry "/entrypoint.sh /etc…" 7 seconds ago Up 6 seconds 5000/tcp vm1
    9. [root@node11 ~]# docker inspect vm1
    10. "Mounts": [
    11. {
    12. "Type": "volume",
    13. "Name": "b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585",
    14. "Source": "/var/lib/docker/volumes/b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585/_data",
    15. "Destination": "/var/lib/registry",
    16. "Driver": "local",
    17. "Mode": "",
    18. "RW": true,
    19. "Propagation": ""
    20. [root@node11 ~]# docker rm -f vm1
    21. vm1
    22. [root@node11 ~]# docker volume ls
    23. DRIVER VOLUME NAME
    24. local b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585
    25. [root@node11 ~]# docker volume rm b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585
    26. b67e701cfa375d921473e7797085c505df1ef541e8f7504d492ddf660bd1f585
    27. [root@node11 ~]# docker volume create vol1
    28. vol1
    29. [root@node11 ~]# docker volume ls
    30. DRIVER VOLUME NAME
    31. local vol1
    32. [root@node11 ~]# docker volume inspect vol1
    33. [
    34. {
    35. "CreatedAt": "2022-08-22T16:44:12+08:00",
    36. "Driver": "local",
    37. "Labels": {},
    38. "Mountpoint": "/var/lib/docker/volumes/vol1/_data",
    39. "Name": "vol1",
    40. "Options": {},
    41. "Scope": "local"
    42. }
    43. ]
    44. [root@node11 ~]# docker run -d --name vm1 -v vol1:/usr/share/nginx/html nginx
    45. b045af5d6ea57bab7171d792cdbaff6298ed9a9da3cfe2f27c424ae6c484a7c6
    46. [root@node11 ~]# docker inspect vm1
    47. "Mounts": [
    48. {
    49. "Type": "volume",
    50. "Name": "vol1",
    51. "Source": "/var/lib/docker/volumes/vol1/_data",
    52. "Destination": "/usr/share/nginx/html",
    53. "Driver": "local",
    54. "Mode": "z",
    55. "RW": true,
    56. "Propagation": ""
    57. [root@node11 ~]# cd /var/lib/docker/
    58. [root@node11 docker]# cd volumes/
    59. [root@node11 volumes]# ls
    60. backingFsBlockDev metadata.db vol1
    61. [root@node11 volumes]# cd vol1/
    62. [root@node11 vol1]# cd _data/
    63. [root@node11 _data]# ls
    64. 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 结合起来;

    1. [root@node11 ~]# docker create --name datavol -v /web1:/web1 -v /web2:/web2:ro busybox
    2. b5e7431fffc8cd073720cf042a30bb2e89be0ee54a2119637382363b2e0111ce
    3. [root@node11 ~]# docker ps -a
    4. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    5. b5e7431fffc8 busybox "sh" 7 seconds ago Created datavol
    6. [root@node11 ~]# docker run -it --rm --volumes-from datavol busybox
    7. / # ls
    8. bin dev etc home proc root sys tmp usr var web1 web2
    9. / # cd web1
    10. /web1 # ls
    11. /web1 # cd ..
    12. / # cd web2
    13. /web2 # ls
    14. /web2 #

    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存储。

    1).在第一台主机上安装 NFS 存储,然后将其共享;

    1. [root@node11 bin]# mkdir /mnt/nfs
    2. [root@node11 bin]# ll -d /mnt/nfs/
    3. drwxr-xr-x 2 root root 6 Aug 23 10:35 /mnt/nfs/
    4. [root@node11 bin]# chmod 777 /mnt/nfs/
    5. [root@node11 bin]# yum install -y nfs-utils
    6. [root@node11 bin]# vim /etc/exports
    7. [root@node11 bin]# cat /etc/exports
    8. /mnt/nfs *(rw,no_root_squash)
    9. [root@node11 bin]# systemctl start nfs
    10. [root@node11 bin]# showmount -e
    11. Export list for node11:
    12. /mnt/nfs *
    13. [root@node22 ~]# yum install nfs-utils.x86_64 -y
    14. [root@node22 ~]# mkdir /mnt/nfs
    15. [root@node22 ~]# mount 192.168.0.11:/mnt/nfs/ /mnt/nfs/
    16. [root@node22 ~]# df
    17. Filesystem 1K-blocks Used Available Use% Mounted on
    18. /dev/mapper/rhel-root 28289540 1865264 26424276 7% /
    19. devtmpfs 485764 0 485764 0% /dev
    20. tmpfs 497948 0 497948 0% /dev/shm
    21. tmpfs 497948 7960 489988 2% /run
    22. tmpfs 497948 0 497948 0% /sys/fs/cgroup
    23. /dev/sda1 1038336 138088 900248 14% /boot
    24. /dev/sr0 4391278 4391278 0 100% /rhel7.6
    25. tmpfs 99592 0 99592 0% /run/user/0
    26. 192.168.0.11:/mnt/nfs 28289664 5737600 22552064 21% /mnt/nfs
    27. [root@node22 ~]# cd /mnt/nfs/

    2)convoy卷插件安装:
     

    1. [root@node11 ~]# tar zxf convoy-v0.5.2.tar.gz
    2. [root@node11 ~]# cd convoy/
    3. [root@node11 convoy]# ls
    4. convoy convoy-pdata_tools SHA1SUMS
    5. [root@node11 convoy]# cp convoy* /usr/local/bin/
    6. [root@node11 convoy]# cd /usr/local/bin/
    7. [root@node11 bin]# ls
    8. convoy convoy-pdata_tools docker-compose
    9. [root@node11 bin]# scp convoy* node22:/usr/local/bin/
    10. root@node22's password:
    11. convoy 100% 17MB 25.1MB/s 00:00
    12. convoy-pdata_tools 100% 22MB 40.7MB/s 00:00
    13. [root@node11 bin]# cd /mnt/nfs/
    14. [root@node11 nfs]# mkdir -p /etc/docker/plugins/
    15. [root@node11 nfs]# cd /etc/docker/plugins/
    16. [root@node11 plugins]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
    17. [root@node11 plugins]# cat /etc/docker/plugins/convoy.spec
    18. unix:///var/run/convoy/convoy.sock
    19. [root@node11 docker]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
    20. [1] 29087
    21. DEBU[0000] Creating config at /var/lib/rancher/convoy pkg=daemon
    22. DEBU[0000] driver=vfs driver_opts=map[vfs.path:/mnt/nfs] event=init pkg=daemon reason=prepare root=/var/lib/rancher/convoy
    23. DEBU[0000] driver=vfs event=init pkg=daemon reason=complete
    24. DEBU[0000] Registering DELETE, /volumes/ pkg=daemon
    25. DEBU[0000] Registering DELETE, /snapshots/ pkg=daemon
    26. DEBU[0000] Registering DELETE, /backups pkg=daemon
    27. DEBU[0000] Registering GET, /backups/list pkg=daemon
    28. DEBU[0000] Registering GET, /backups/inspect pkg=daemon
    29. DEBU[0000] Registering GET, /info pkg=daemon
    30. DEBU[0000] Registering GET, /volumes/list pkg=daemon
    31. DEBU[0000] Registering GET, /volumes/ pkg=daemon
    32. DEBU[0000] Registering GET, /snapshots/ pkg=daemon
    33. DEBU[0000] Registering POST, /snapshots/create pkg=daemon
    34. DEBU[0000] Registering POST, /backups/create pkg=daemon
    35. DEBU[0000] Registering POST, /volumes/create pkg=daemon
    36. DEBU[0000] Registering POST, /volumes/mount pkg=daemon
    37. DEBU[0000] Registering POST, /volumes/umount pkg=daemon
    38. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Remove pkg=daemon
    39. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Path pkg=daemon
    40. DEBU[0000] Registering plugin handler POST, /VolumeDriver.List pkg=daemon
    41. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Unmount pkg=daemon
    42. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Get pkg=daemon
    43. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Capabilities pkg=daemon
    44. DEBU[0000] Registering plugin handler POST, /Plugin.Activate pkg=daemon
    45. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Create pkg=daemon
    46. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Mount pkg=daemon
    47. [root@node11 ~]# docker volume create -d convoy vol1
    48. [root@node11 ~]# convoy list
    49. {
    50. "vol1": {
    51. "Name": "vol1",
    52. "Driver": "vfs",
    53. "MountPoint": "",
    54. "CreatedTime": "Tue Aug 23 10:59:04 +0800 2022",
    55. "DriverInfo": {
    56. "Driver": "vfs",
    57. "MountPoint": "",
    58. "Path": "/mnt/nfs/vol1",
    59. "PrepareForVM": "false",
    60. "Size": "0",
    61. "VolumeCreatedAt": "Tue Aug 23 10:59:04 +0800 2022",
    62. "VolumeName": "vol1"
    63. },
    64. "Snapshots": {}
    65. }
    66. }

    在node22主机配置:

    1. [root@node22 nfs]# mkdir -p /etc/docker/plugins/
    2. [root@node22 nfs]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
    3. [root@node22 nfs]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
    4. [1] 9468
    5. [root@node22 nfs]# DEBU[0000] Creating config at /var/lib/rancher/convoy pkg=daemon
    6. DEBU[0000] driver=vfs driver_opts=map[vfs.path:/mnt/nfs] event=init pkg=daemon reason=prepare root=/var/lib/rancher/convoy
    7. DEBU[0000] driver=vfs event=init pkg=daemon reason=complete
    8. DEBU[0000] Registering POST, /volumes/create pkg=daemon
    9. DEBU[0000] Registering POST, /volumes/mount pkg=daemon
    10. DEBU[0000] Registering POST, /volumes/umount pkg=daemon
    11. DEBU[0000] Registering POST, /snapshots/create pkg=daemon
    12. DEBU[0000] Registering POST, /backups/create pkg=daemon
    13. DEBU[0000] Registering DELETE, /volumes/ pkg=daemon
    14. DEBU[0000] Registering DELETE, /snapshots/ pkg=daemon
    15. DEBU[0000] Registering DELETE, /backups pkg=daemon
    16. DEBU[0000] Registering GET, /info pkg=daemon
    17. DEBU[0000] Registering GET, /volumes/list pkg=daemon
    18. DEBU[0000] Registering GET, /volumes/ pkg=daemon
    19. DEBU[0000] Registering GET, /snapshots/ pkg=daemon
    20. DEBU[0000] Registering GET, /backups/list pkg=daemon
    21. DEBU[0000] Registering GET, /backups/inspect pkg=daemon
    22. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Unmount pkg=daemon
    23. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Path pkg=daemon
    24. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Get pkg=daemon
    25. DEBU[0000] Registering plugin handler POST, /VolumeDriver.List pkg=daemon
    26. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Create pkg=daemon
    27. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Remove pkg=daemon
    28. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Mount pkg=daemon
    29. DEBU[0000] Registering plugin handler POST, /Plugin.Activate pkg=daemon
    30. DEBU[0000] Registering plugin handler POST, /VolumeDriver.Capabilities pkg=daemon
    31. [root@node22 nfs]# ls
    32. config vol1
    33. [root@node22 nfs]# convoy list
    34. {
    35. "vol1": {
    36. "Name": "vol1",
    37. "Driver": "vfs",
    38. "MountPoint": "",
    39. "CreatedTime": "Tue Aug 23 10:59:04 +0800 2022",
    40. "DriverInfo": {
    41. "Driver": "vfs",
    42. "MountPoint": "",
    43. "Path": "/mnt/nfs/vol1",
    44. "PrepareForVM": "false",
    45. "Size": "0",
    46. "VolumeCreatedAt": "Tue Aug 23 10:59:04 +0800 2022",
    47. "VolumeName": "vol1"
    48. },
    49. "Snapshots": {}
    50. }
    51. }
    1. [root@node11 ~]# docker run -d --name vm1 -v vol1:/usr/share/nginx/html nginx
    2. [root@node11 ~]# docker inspect vm1
    3. "Mounts": [
    4. {
    5. "Type": "volume",
    6. "Name": "vol1",
    7. "Source": "",
    8. "Destination": "/usr/share/nginx/html",
    9. "Driver": "convoy",
    10. "Mode": "",
    11. "RW": true,
    12. "Propagation": ""
    13. }
    14. ],
    15. [root@node11 ~]# cd /mnt/nfs/
    16. [root@node11 nfs]# cd vol1/
    17. [root@node11 vol1]# ls
    18. 50x.html index.html
    19. [root@node11 vol1]# echo www.westos.org > index.html
    20. [root@node11 vol1]# curl 172.17.0.2
    21. www.westos.org
    22. [root@node11 vol1]# docker save nginx:latest -o nginx.tar
    23. [root@node11 vol1]# scp nginx.tar node22:
    24. root@node22's password:
    25. nginx.tar 100% 139MB 7.8MB/s 00:17
    26. [root@node22 ~]# docker load -i nginx.tar
    27. [root@node22 ~]# docker run -d --name vm1 -v vol1:/usr/share/nginx/html nginx
    28. [root@node22 ~]# curl 172.17.0.2
    29. www.westos.org
    30. [root@node22 ~]# cd /mnt/nfs
    31. [root@node22 nfs]# cd vol1/
    32. [root@node22 vol1]# cat index.html
    33. www.westos.org
    34. 当在一个结点回收卷时,所有结点都会回收;
    35. [root@node22 vol1]# convoy delete vol1
    36. DEBU[0987] Calling: DELETE, /volumes/, request: DELETE, /v1/volumes/ pkg=daemon
    37. DEBU[0987] event=delete object=volume pkg=daemon reason=prepare volume=vol1
    38. DEBU[0987] Cleaning up /mnt/nfs/vol1 for volume vol1 pkg=vfs
    39. DEBU[0987] event=delete object=volume pkg=daemon reason=complete volume=vol1
    40. [root@node22 vol1]# cd /mnt/nfs/
    41. [root@node22 nfs]# ls
    42. config
    43. 当不需要插件信息时,删除过程如下:
    44. [root@node11 nfs]# cd /etc/docker
    45. [root@node11 docker]# cd plugins/
    46. [root@node11 plugins]# rm -rf convoy.spec
    47. [root@node11 plugins]# ls
    48. [root@node11 plugins]# docker volume ls
    49. DEBU[1483] Handle plugin list volume: POST /VolumeDriver.List pkg=daemon
    50. DEBU[1483] Successfully got volume list for docker. pkg=daemon
    51. DEBU[1483] Response: {} pkg=daemon
    52. DRIVER VOLUME NAME
    53. [root@node11 plugins]# systemctl restart docker
    54. [root@node11 plugins]# docker volume ls
    55. DRIVER VOLUME NAME
    56. 对于另一台主机上的删除,此时也可以需要同样的操作来结束进程。
    57. [root@node22 nfs]# fg
    58. convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs
    59. ^CCaught signal interrupt: shutting down.
    60. DEBU[1303] Cleaning up environment... pkg=daemon
    61. ERRO[1303] http server erroraccept unix /var/run/convoy/convoy.sock: use of closed network connection pkg=daemon
    62. [root@node22 nfs]# cd /etc/docker/plugins/
    63. [root@node22 plugins]# rm -f convoy.spec
    64. [root@node22 plugins]# systemctl restart docker
    65. [root@node22 plugins]# docker volume ls
    66. DRIVER VOLUME NAME

    4. 总结

    对于 docker 数据卷的管理,以及第三方的卷插件的使用进行了学习,以下为一些常用的命令:

    convoy卷插件子命令;

    convoy list 列出卷;

    convoy delete 删除卷;

    convoy snapshot create 创建快照;

    convoy snapshot delete 删除快照;

    convoy backup create 创建备份;

    convoy create res1 --backup < url> 还原备份

  • 相关阅读:
    2022-11-06
    AOP(JDK动态代理实现)
    TC8:UDP_INTRODUCTION_01-03
    内核不中断前提下,Gaussdb(DWS)内存报错排查方法
    变分自动编码器 (VAE)02/2 PyTorch 教程
    五大架构风格
    计组大作业|硬件小学期的思路
    三、MyBatis(3)
    比较爽的导航查询 功能 .NET ORM / SqlSugar
    多业务模式下的交易链路探索与实践
  • 原文地址:https://blog.csdn.net/z17609273238/article/details/126638581