IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> docker数据卷 -> 正文阅读

[系统运维]docker数据卷

一、为什么要用数据卷

Docker的数据持久化即使数据不随着container的结束而结束,数据存在于host机器上——要么存在于host的某个指定目录中(使用bind mount),要么使用docker自己管理的volume(/var/lib/docker/volumes下)。

Docker中,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束),需要将数据从宿主机挂载到容器中。

docker分层文件系统
  性能差
  生命周期与容器相同
docker数据卷
  mount到主机中,绕开分层文件系统
  和主机磁盘性能相同,容器删除后依然保留
  仅限本地磁盘,不能随容器迁移

二、docker卷

docker提供了两种卷:
bind mount
docker managed volume

1.bind mount

(1)基本设置
bind mount 是将 host 上已存在的目录或文件 mount 到容器。
例如 docker host 上有目录 /data/nginx:

[root@localhost ~]# cd /data/nginx/
[root@localhost nginx]# pwd
/data/nginx
[root@localhost nginx]# ls
index.html

通过 -v 将其 mount 到 nginx容器:
-v 的格式为 host path:container path。

[root@localhost ~]# cd /data/nginx/
[root@localhost nginx]# pwd
/data/nginx
[root@localhost nginx]# ls
index.html

#没有mount之前,可以看到目录/usr/share/nginx/html下面是有两个文件的
[root@localhost nginx]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
77f85615efca        nginx               "/docker-entrypoint.…"   3 seconds ago       Up 2 seconds        80/tcp              affectionate_meninsky
[root@localhost nginx]# docker exec -it 77f85615efca /bin/bash
root@77f85615efca:/# ls /usr/share/nginx/html/
50x.html  index.html
 
#挂载之后 /usr/share/nginx/html下面只有一个文件了
[root@localhost nginx]# docker run -itd --name=nginx -p 80:80 -v /data/nginx:/usr/share/nginx/html nginx
3c9be3ad8788544f5533f4e1519592f4b37d4a19f4ea584e0b2d96d76d7f510d
[root@localhost nginx]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
3c9be3ad8788        nginx               "/docker-entrypoint.…"   3 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp   nginx
 
[root@localhost nginx]# docker exec -it nginx ls /usr/share/nginx/html
index.html
[root@localhost nginx]# cat index.html 
hello nginx
[root@localhost nginx]# docker exec -it nginx cat  /usr/share/nginx/html/index.html
hello nginx

在这里插入图片描述
(2)设置权限

默认权限是读写rw,可以在挂载时指定只读ro。 -v选项指定的路径,如果不存在,挂载时会自动创建。创建后宿主机文件会自动覆盖容器的文件。

在这里插入图片描述

2.docker managed volume

1.自动创建volume

docker 管理卷 是docker引擎自动为我们创建的。他在创建前会读取镜像中有没有挂载相关的参数,若有,才会自动创建。

测试:

step1:先将之前docker仓库相关的volume回收。
在这里插入图片描述
step2:以nginx镜像为例,它并没有关于卷的挂载,所以使用nginx镜像运行容器后,并没有自动为我们创建卷,这就是因为容器本身就没有定义卷的挂载:
在这里插入图片描述
反之,registry有定义卷的挂载,所以它可以自动创建卷:
在这里插入图片描述
docker inspect demo 中的mounts部分如下:

 "Mounts": [
            {
                "Type": "volume",
                "Name": "aa58d391a02d4afcb29d3b4b0f1fdff0e376483f0f7bec1f80026e3d57f03412",
                "Source": "/var/lib/docker/volumes/aa58d391a02d4afcb29d3b4b0f1fdff0e376483f0f7bec1f80026e3d57f03412/_data",
                "Destination": "/var/lib/registry",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

2.改进方式读方式

由上述代码可以看出,根据镜像中关于卷的定义,会为他自动创建一个卷(source部分),然后把他挂载到"Destination"部分,(Destination是容器内的数据路径),但是这种方式 不好读,source部分的位置是随机分配的,我们可以采用以下方式进行:

[root@server1 ~]# docker volume create vol1
vol1
[root@server1 ~]# docker volume inspect vol1
[
    {
        "CreatedAt": "2022-03-12T16:34:02+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/vol1/_data",
        "Name": "vol1",
        "Options": {},
        "Scope": "local"
    }
]

在这里插入图片描述
这样一比,比之前的/var/lib/docker/volumes/aa58d391a02d4afcb29d3b4b0f1fdff0e376483f0f7bec1f80026e3d57f03412/_data要好的多。

然后 再次运行容器:

docker run -d --name demo -v vol1:/var/lib/registry registry

在这里插入图片描述
docker inspect demo显示的mounts部分如下所示:
在这里插入图片描述

3.docker管理卷的总结

[root@localhost ~]# cd /var/lib/docker/volumes/a2ddf154e5e224acc154d4895017b65d310f6ca430fadd89ff5d3630e8939e7c/_data
[root@localhost _data]# ls
[root@localhost _data]# touch a.txt
 
[root@localhost _data]# docker exec -it busybox ls /etc/managed
a.txt

原来,每当容器申请 mount docker manged volume 时,docker 都会在/var/lib/docker/volumes 下生成一个目录(例子中是 “/var/lib/docker/volumes/a2ddf154e5e224acc154d4895017b65d310f6ca430fadd89ff5d3630e8939e7c/_data” ),这个目录就是 mount 源。

简单回顾一下 docker managed volume 的创建过程:

1.容器启动时,简单的告诉 docker “我需要一个 volume 存放数据,帮我 mount 到目录 /abc”

2.docker 在 /var/lib/docker/volumes 中生成一个随机目录作为 mount 源

3.如果 /abc 已经存在,则将数据复制到 mount 源

4.将 volume mount 到 /abc

注意:如果你要mount的目录下已经存在了文件,这些文件还是会显示出来不会被隐藏起来,这个和bind mount是不同的

[root@localhost ~]# docker run -itd -v /etc/nginx/ nginx
ee81653a884cff75bdcfae540e814fca19e25b64d546a1ff1761892d227028e5
[root@localhost ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
ee81653a884c        nginx               "/docker-entrypoint.…"   4 seconds ago       Up 2 seconds        80/tcp              charming_northcutt
 
[root@localhost ~]# docker exec -it ee81653a884c /bin/bash
root@ee81653a884c:/# cd /etc/nginx/
root@ee81653a884c:/etc/nginx# ls
conf.d	fastcgi_params	koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params	uwsgi_params  win-utf
 
[root@localhost ~]# docker inspect ee81653a884c
        "Mounts": [
            {
                "Type": "volume",
                "Name": "b923a5a77222defdc83ebd03b79ea121d87d9296535b9d335828a91b2d7d5a2c",
                "Source": "/var/lib/docker/volumes/b923a5a77222defdc83ebd03b79ea121d87d9296535b9d335828a91b2d7d5a2c/_data",
                "Destination": "/etc/nginx",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
[root@localhost ~]# cd /var/lib/docker/volumes/b923a5a77222defdc83ebd03b79ea121d87d9296535b9d335828a91b2d7d5a2c/_data
[root@localhost _data]# ls
conf.d  fastcgi_params  koi-utf  koi-win  mime.types  modules  nginx.conf  scgi_params  uwsgi_params  win-utf

3.bind mount和docker managed volume的区别

在这里插入图片描述
(1)volume的位置
由下图可以看出 新创建的卷vol2,它的目录就在/var/lib/docker/volumes/下:

[root@server1 data1]# docker volume create vol2
vol2
[root@server1 data1]# cd /var/lib/docker/volumes/
[root@server1 volumes]# ls
backingFsBlockDev  metadata.db  vol1  vol2
[root@server1 volumes]# 

(2)对挂载点的影响
由下图可以看出,以docker管理卷的方式 并不会对挂载点原内容造成覆盖,而以bind mount方式就会对挂载点造成覆盖。
(我们之前自己创建的volume 所以是docker 管理卷 ;而bind mount方式却是直接指定路径)
在这里插入图片描述
(3)权限控制
其实,docker managed volume是有一种方式可以指定权限的:

[root@server1 volumes]# docker run -d --name demo -v vol2:/usr/share/nginx/html:ro nginx
aca9d8ca84f76cab0a50bd9ec412f789d05438610eb74746ae44e2bd2ee3d8be
[root@server1 volumes]# docker exec -it demo bash
root@aca9d8ca84f7:/# cd /usr/share/nginx/html
root@aca9d8ca84f7:/usr/share/nginx/html# ls
50x.html  index.html
root@aca9d8ca84f7:/usr/share/nginx/html# touch file1
touch: cannot touch 'file1': Read-only file system

三、跨节点数据持久化(数据共享)——卷插件

上面说的bind volume 和docker managed volume都是针对单一主机,我们刚刚演示 的所有操作都是在一台主机上,假设现在有这样的情况:server1突然宕机了,在生产环境中肯定是有集群的,集群管理器检测到这个容器被意外关闭之后,他会把它调度到其他健康主机。那么此时,之前健康的那台主机,它的数据能全部同步到新的主机上吗?之前用的两种方式都不行,它们都不支持跨结点共享数据。容器可以调度到其他节点去解决问题,但此时这种情况,数据不行。

1卷插件简介

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自身的处理完成客户端的请求。

2.convoy卷插件

我知道的实现docker卷插件有flocker、convoy这两个插件,我们以convoy插件 来进行演示:

(1)部署相同的nfs文件系统实现数据共享

在server1上的操作:

mkdir /nfsshare  新建共享目录
yum install -y nfs-utils   ##安装nfs文件系统以实现不同节点的文件共享

[root@server1 nfsshare]# ll -d .
drwxr-xr-x 2 root root 6 Mar 13 11:41 .
[root@server1 nfsshare]# chmod 777 /nfsshare/   ##修改共项目权限 以便后续使用

[root@server1 nfsshare]# vim /etc/exports   ##将共享目录写入配置文件 并设置权限
[root@server1 nfsshare]# cat /etc/exports
/nfsshare	*(rw,no_root_squash)
  括号的里面内容的权限解释:
- *:允许所有的网段访问,也可以使用具体的IP
- rw:挂接此目录的客户端对该共享目录具有读写权限
- sync:资料同步写入内存和硬盘
- no_root_squash:root用户具有对根目录的完全管理访问权限。
- no_subtree_check:不检查父目录的权限。
- insecure :关闭exports文件对于端口大小不能超过1024的限制

[root@server1 nfsshare]# systemctl enable --now nfs   ##重启服务以加载配置文件
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.

[root@server1 nfsshare]# showmount -e   ##显示NFS服务器的输出清单。
Export list for server1:
/nfsshare *

在server2上的操作:

mkdir /nfsshare  新建共享目录
yum install -y nfs-utils   ##安装nfs文件系统以实现不同节点的文件共享

[root@server2 ~]# showmount -e 172.25.254.1  # 查看server1上共享的数据
Export list for 172.25.254.1:
/nfsshare *
[root@server2 ~]# mount 172.25.254.1:/nfsshare/ /nfsshare/  # 把它挂碍到当前的文件系统

如此一来就实现了不同节点的数据的同步。

此时数据是否同步:

[root@server1 nfsshare]# touch file1
[root@server1 nfsshare]# ls
file1

[root@server2 ~]# cd /nfsshare/
[root@server2 nfsshare]# ls
file1

数据已同步 。

(2)使用卷插件,使docker引擎可以调用这个底层的文件系统

在server1上操作如下:

[root@server1 ~]# tar zxf convoy-v0.5.2.tar.gz  ## 下载并解压convey
[root@server1 ~]# ls
auth               certs   convoy-v0.5.2.tar.gz  harbor                               openssl11-1.1.1k-2.el7.x86_64.rpm
base-debian10.tar  convoy  docker                harbor-offline-installer-v2.3.4.tgz  openssl11-libs-1.1.1k-2.el7.x86_64.rpm

[root@server1 ~]# cd convoy/
[root@server1 convoy]# ls
convoy  convoy-pdata_tools  SHA1SUMS
[root@server1 convoy]# cp convoy convoy-pdata_tools /usr/local/bin/   ##给用户放置自己的可执行程序在/usr/local/bin/目录下。

[root@server1 ~]# mkdir -p /etc/docker/plugins/  ## 创建 docker引擎的缺省路径 (默认路径)
                ## docker引擎会自动扫描该目录 卷插件就放这个目录下。
[root@server1 ~]# cd /etc/docker/
[root@server1 docker]# ls
certs.d  daemon.json  key.json  plugins
[root@server1 docker]# cd plugins/
[root@server1 plugins]# ls
[root@server1 plugins]# 

[root@server1 plugins]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
     ## 创建程序的socket文件 明确如何调用该插件
[root@server1 plugins]# ll
total 4
-rw-r--r-- 1 root root 35 Mar 13 15:07 convoy.spec
[root@server1 plugins]# cat convoy.spec   ## 以spec结尾,插件名称为convoy(你要使用的插件)
unix:///var/run/convoy/convoy.sock

[root@server1 plugins]# convoy daemon --drivers vfs --driver-opts vfs.path=/nfsshare & ##启动Convoy守护进程
[1] 4978
[root@server1 plugins]# DEBU[0000] Creating config at /var/lib/rancher/convoy    pkg=daemon
DEBU[0000]                                               driver=vfs driver_opts=map[vfs.path:/nfsshare] 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, /snapshots/                  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 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.Path  pkg=daemon
DEBU[0000] Registering plugin handler POST, /VolumeDriver.List  pkg=daemon
DEBU[0000] Registering plugin handler POST, /VolumeDriver.Capabilities  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, /VolumeDriver.Unmount  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.Get  pkg=daemon

#启动后检查该路径下套接字文件与刚刚设置的一样:
[root@server1 docker]# cd /var/run/convoy/  
[root@server1 convoy]# ls
convoy.sock
[root@server1 convoy]# cat /etc/docker/plugins/convoy.spec 
unix:///var/run/convoy/convoy.sock

在server2上操作如下:

[root@server2 ~]# ls
convoy-v0.5.2.tar.gz
[root@server2 ~]# tar zxf 
.bash_history         .bash_profile         convoy-v0.5.2.tar.gz  .docker/              .tcshrc               
.bash_logout          .bashrc               .cshrc                .pki/                 .viminfo              
[root@server2 ~]# tar zxf convoy-v0.5.2.tar.gz 
[root@server2 ~]# ls
convoy  convoy-v0.5.2.tar.gz
[root@server2 ~]# cd convoy/
[root@server2 convoy]# ls
convoy  convoy-pdata_tools  SHA1SUMS
[root@server2 convoy]#  cp convoy convoy-pdata_tools /usr/local/bin/
[root@server2 convoy]# which convoy
/usr/local/bin/convoy
[root@server2 convoy]#  mkdir -p /etc/docker/plugins/
[root@server2 convoy]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
[root@server2 convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/nfsshare &
[1] 4774
[root@server2 convoy]# DEBU[0000] Creating config at /var/lib/rancher/convoy    pkg=daemon
DEBU[0000]                                               driver=vfs driver_opts=map[vfs.path:/nfsshare] 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.Mount  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.List  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.Remove  pkg=daemon
DEBU[0000] Registering plugin handler POST, /VolumeDriver.Get  pkg=daemon

[root@server2 convoy]# 

[root@server1 convoy]# convoy list
{}
[root@server1 convoy]# convoy create vol1  ##创建卷 
DEBU[1068] Calling: POST, /volumes/create, request: POST, /v1/volumes/create  pkg=daemon
DEBU[1068]                                               event=create object=volume opts=map[VolumeIOPS:0 PrepareForVM:false BackupURL: EndpointURL: VolumeName:vol1 VolumeType: Size:0 VolumeDriverID:] pkg=daemon reason=prepare volume=vol1
DEBU[1068] Created volume                                event=create object=volume pkg=daemon reason=complete volume=vol1
DEBU[1068] Response:  vol1                               pkg=daemon
vol1
[root@server1 convoy]# convoy list
{
	"vol1": {
		"Name": "vol1",
		"Driver": "vfs",
		"MountPoint": "",
		"CreatedTime": "Sun Mar 13 15:28:15 +0800 2022",
		"DriverInfo": {
			"Driver": "vfs",
			"MountPoint": "",
			"Path": "/nfsshare/vol1",
			"PrepareForVM": "false",
			"Size": "0",
			"VolumeCreatedAt": "Sun Mar 13 15:28:15 +0800 2022",
			"VolumeName": "vol1"
		},
		"Snapshots": {}
	}
}

[root@server1 convoy]# cd /nfsshare/  ## 检查刚刚创建的卷
[root@server1 nfsshare]# ls
config  file1  vol1   ##注意此处的config不要删 

[root@server2 convoy]# cd /nfsshare/  ## 由于nfs底层同步 所以在server2上看到的内容是一致的
[root@server2 nfsshare]# ls
config  file1  vol1


在这里插入图片描述

[root@server2 nfsshare]# docker volume create -d convoy vol2  ##创建新的卷vol2
DEBU[0970] Handle plugin activate: POST /Plugin.Activate  pkg=daemon
DEBU[0970] Response:  {
	"Implements": [
		"VolumeDriver"
	]
}  pkg=daemon
DEBU[0970] Handle plugin capabilities: POST /VolumeDriver.Capabilities  pkg=daemon
DEBU[0970] Successfully return plugin capabilities for docker.  pkg=daemon
DEBU[0970] Response:  {
	"Capabilities": {
		"Scope": "local"
	}
}  pkg=daemon
DEBU[0970] Handle plugin get volume: POST /VolumeDriver.Get  pkg=daemon
DEBU[0970] Request from docker: &{vol2 map[]}            pkg=daemon
DEBU[0970] Response:  {
	"Err": "Could not find volume vol2."
}  pkg=daemon
DEBU[0970] Handle plugin create volume: POST /VolumeDriver.Create  pkg=daemon
DEBU[0970] Request from docker: &{vol2 map[]}            pkg=daemon
DEBU[0970] Create a new volume vol2 for docker           pkg=daemon
DEBU[0970]                                               event=create object=volume opts=map[VolumeDriverID: VolumeIOPS:0 VolumeName:vol2 VolumeType: PrepareForVM:false Size:0 BackupURL: EndpointURL:] pkg=daemon reason=prepare volume=vol2
DEBU[0970] Created volume                                event=create object=volume pkg=daemon reason=complete volume=vol2
DEBU[0970] Created volume for docker vol2                pkg=daemon
DEBU[0970] Response:  {}                                 pkg=daemon
vol2

[root@server2 nfsshare]# ls
config  file1  vol1  vol2

[root@server2 nfsshare]# docker volume list ##列出卷 
DEBU[1015] Handle plugin list volume: POST /VolumeDriver.List  pkg=daemon
DEBU[1015]                                               event=mountpoint object=volume pkg=daemon reason=prepare volume=vol1
DEBU[1015]                                               event=mountpoint mountpoint= object=volume pkg=daemon reason=complete volume=vol1
DEBU[1015]                                               event=mountpoint object=volume pkg=daemon reason=prepare volume=vol2
DEBU[1015]                                               event=mountpoint mountpoint= object=volume pkg=daemon reason=complete volume=vol2
DEBU[1015] Successfully got volume list for docker.      pkg=daemon
DEBU[1015] Response:  {
	"Volumes": [
		{
			"Name": "vol1"
		},
		{
			"Name": "vol2"
		}
	]
}  pkg=daemon
DRIVER    VOLUME NAME
convoy    vol1
convoy    vol2

测试

在server1上操作如下:

docker run -d --name demo -v vol1:/usr/share/nginx/html nginx  ## 运行一个容器
[root@server1 nfsshare]# docker ps 
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
2006a839801f   nginx     "/docker-entrypoint.…"   44 seconds ago   Up 42 seconds   80/tcp    demo

[root@server1 vol1]# docker inspect demo
"Mounts": [
            {
                "Type": "volume",
                "Name": "vol1",
                "Source": "",
                "Destination": "/usr/share/nginx/html",
                "Driver": "convoy",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
"Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",

[root@server1 nfsshare]# ls
config  file1  vol1  vol2
[root@server1 nfsshare]# cd vol1
[root@server1 vol1]# ls
50x.html  index.html
[root@server1 vol1]# echo www.westos.org > index.html
[root@server1 vol1]# curl 172.17.0.2
www.westos.org

此时,模拟一个server1上的容器故障,比如被误删了,在server2上就可以找到之前的数据;

[root@server1 vol1]# docker rm -f demo  ## 销毁server1上的容器
DEBU[2277] Handle plugin get volume: POST /VolumeDriver.Get  pkg=daemon
DEBU[2277] Request from docker: &{vol1 map[]}            pkg=daemon
DEBU[2277]                                               event=mountpoint object=volume pkg=daemon reason=prepare volume=vol1
DEBU[2277]                                               event=mountpoint mountpoint=/nfsshare/vol1 object=volume pkg=daemon reason=complete volume=vol1
DEBU[2277] Found volume vol1 for docker                  pkg=daemon
DEBU[2277] Response:  {
	"Volume": {
		"Name": "vol1",
		"Mountpoint": "/nfsshare/vol1"
	}
}  pkg=daemon
DEBU[2277] Handle plugin unmount volume: POST /VolumeDriver.Unmount  pkg=daemon
DEBU[2277] Request from docker: &{vol1 map[]}            pkg=daemon
DEBU[2277] Unmount volume: vol1 for docker               pkg=daemon
DEBU[2277]                                               event=umount object=volume pkg=daemon reason=prepare volume=vol1
DEBU[2277]                                               event=umount object=volume pkg=daemon reason=complete volume=vol1
DEBU[2277] Response:  {}                                 pkg=daemon
demo

在server2上操作如下:

docker run -d --name demo -v vol1:/usr/share/nginx/html nginx  
## 同样的指令咋server2上再次运行 表示集群管理器已经将数据转移到了健康的节点上。

[root@server2 nfsshare]# curl 172.17.0.2
www.westos.org

在这里插入图片描述

回顾一下docker卷插件的工作流程:
?
docker client -> docker daemon -> convoy plugin -> nfs ->

3.docker卷插件回收

docker volume rm vol1
docker volume rm vol2

systemctl restart docker  ## 此时会遇到卡顿,

cd /var/lib/docker/plugins 
rm -f metadata.db

cd /etc/docker/plugins
rm -fr convoy.spec
systemctl restart docker  ## 此时就不会遇到卡顿的问题了

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-13 22:13:16  更:2022-03-13 22:14:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 1:40:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码