:以前宿主机路径,:以后容器路径
如果存在自动挂载,如果不存在默认会创建
对于镜像来说存储是一种需求,也可以通过这样的方式(挂载)修改容器的配置
/usr/share/nginx/html是Nginx默认的程序发布目录(数据挂载上)
[root@docker1 /]# mkdir /webdata
[root@docker1 /]# docker run -d --name demo -v /webdata:/usr/share/nginx/html nginx
[root@docker1 /]# cd /webdata/
[root@docker1 webdata]# vim index.html
[root@docker1 webdata]# cat index.html
www.yan.org
[root@docker1 webdata]# curl 172.17.0.2
www.yan.org
[root@docker1 webdata]# docker inspect demo
[root@docker1 webdata]# docker exec -it demo bash
root@a1f6892bc233:/# cd /usr/share/nginx/html/
root@a1f6892bc233:/usr/share/nginx/html# ls
index.html
root@a1f6892bc233:/usr/share/nginx/html# cat index.html
www.yan.org
[root@docker1 webdata]# docker rm -f demo
需要配置文件
[root@docker1 webdata]# mkdir conf
[root@docker1 webdata]# mkdir html
[root@docker1 webdata]# mv index.html html/
[root@docker1 webdata]# cd conf/
进去容器看看配置文件
[root@docker1 conf]# docker run -it --rm nginx bash
root@d775f75c01df:/# cd /etc/nginx/
root@d775f75c01df:/etc/nginx# ls
conf.d mime.types nginx.conf uwsgi_params
fastcgi_params modules scgi_params
root@d775f75c01df:/etc/nginx# cat nginx.conf
root@d775f75c01df:/etc/nginx# cd conf.d/
root@d775f75c01df:/etc/nginx/conf.d# ls
default.conf
root@d775f75c01df:/etc/nginx/conf.d# cat default.conf
[root@docker1 conf]# vim www.conf
[root@docker1 conf]# cat www.conf
server {
listen 80;
server_name www.yan.org;
location / {
root /html;虚拟主机的发布目录(容器)
index index.html;
}
}
[root@docker1 conf]# cd ..
[root@docker1 webdata]# cd html/
[root@docker1 html]# ls
index.html
[root@docker1 ~]# docker run -d --name demo -v /webdata/html:/html -v /webdata/conf/www.conf:/etc/nginx/conf.d/www.conf:ro -p 80:80 nginx
[root@docker1 ~]# vim /etc/hosts
172.25.254.1 docker1 reg.yan.org www.yan.org
访问域名www.yan.org,容器占用宿主机的80端口,所以请求会重定向到容器内。
[root@docker1 ~]# curl www.yan.org
www.yan.org
访问宿主机的80会重定向到容器里面
[root@docker1 ~]# ps ax
[root@docker1 ~]# iptables -t nat -nL
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80
[root@docker1 ~]# cd /webdata/
[root@docker1 webdata]# ls
conf html
[root@docker1 webdata]# cd html/
[root@docker1 html]# vim index.html
[root@docker1 html]# cat index.html
www.yan.org
123456789
[root@docker1 html]# curl www.yan.org
www.yan.org
123456789
[root@docker1 volumes]# docker history nginx:latest
IMAGE CREATED CREATED BY SIZE COMMENT
605c77e624dd 6 weeks ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 6 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
<missing> 6 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 6 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["/docker-entr… 0B
<missing> 6 weeks ago /bin/sh -c #(nop) COPY file:09a214a3e07c919a… 4.61kB
<missing> 6 weeks ago /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7… 1.04kB
<missing> 6 weeks ago /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0… 1.96kB
<missing> 6 weeks ago /bin/sh -c #(nop) COPY file:65504f71f5855ca0… 1.2kB
<missing> 6 weeks ago /bin/sh -c set -x && addgroup --system -… 61.1MB
<missing> 6 weeks ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~bullseye 0B
<missing> 6 weeks ago /bin/sh -c #(nop) ENV NJS_VERSION=0.7.1 0B
<missing> 6 weeks ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.21.5 0B
<missing> 7 weeks ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B
<missing> 7 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 7 weeks ago /bin/sh -c #(nop) ADD file:09675d11695f65c55… 80.4MB
registry定义了
[root@docker1 volumes]# docker history registry:latest
IMAGE CREATED CREATED BY SIZE COMMENT
<missing> 3 months ago /bin/sh -c #(nop) VOLUME [/var/lib/registry] 0B
_data就会被挂接到容器内
[root@docker1 docker]# cd /var/lib/docker/volumes/
[root@docker1 volumes]# ls
metadata.db
[root@docker1 volumes]# docker volume ls
DRIVER VOLUME NAME
local 489ec21e4aa78de9ca13565361142459a460b1beb7f64124714299d4d4b964e9
[root@docker1 volumes]# ls
489ec21e4aa78de9ca13565361142459a460b1beb7f64124714299d4d4b964e9 metadata.db
root@docker1 volumes]# cd 489ec21e4aa78de9ca13565361142459a460b1beb7f64124714299d4d4b964e9/
[root@docker1 489ec21e4aa78de9ca13565361142459a460b1beb7f64124714299d4d4b964e9]# ls
_data
[root@docker1 489ec21e4aa78de9ca13565361142459a460b1beb7f64124714299d4d4b964e9]# cd _data/
[root@docker1 _data]# ls
由于自动生成的卷名字很长,而且看不出对应关系
删掉容器卷还保留着
[root@docker1 _data]# docker rm -f registry
registry
[root@docker1 _data]# docker volume ls
DRIVER VOLUME NAME
local 489ec21e4aa78de9ca13565361142459a460b1beb7f64124714299d4d4b964e9
[root@docker1 _data]# 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@docker1 volumes]# cd /var/lib/docker/volumes/
[root@docker1 volumes]# ls
metadata.db
[root@docker1 volumes]# docker volume create registry
[root@docker1 _data]# docker volume ls
DRIVER VOLUME NAME
local registry
[root@docker1 volumes]# ls
metadata.db registry
[root@docker1 volumes]# docker run -d --name registry -v registry:/var/lib/registry registry
[root@docker1 volumes]# docker inspect registry
特点:
-v不是docker manager 的话(bind mount )是用宿主机内的数据覆盖掉容器内的,docker manager卷的话会把容器的挂载点里原有的文件考入物理节点上,持久化
[root@docker1 volumes]# docker volume create vol1
[root@docker1 volumes]# ls
metadata.db vol1
[root@docker1 volumes]# cd vol1/
[root@docker1 vol1]# ls
_data
[root@docker1 vol1]# cd _data/
[root@docker1 _data]# ls
[root@docker1 _data]# docker run -d --name nginx -v vol1:/usr/share/nginx/html nginx
[root@docker1 _data]# ls
50x.html index.html
mind mount是覆盖的(没有该目录自动创建),不会考入原有容器挂载点内的数据
[root@docker1 mnt]# cd /yan
-bash: cd: /yan: No such file or directory
[root@docker1 mnt]# docker run -d --name nginx2 -v /yan:/usr/share/nginx/html nginx
[root@docker1 ~]# docker run -d --name nginx4 nginx:latest
[root@docker1 ~]# docker exec -it nginx4 bash
root@f1177ba608b8:/# cd /usr/share/nginx/html/
root@f1177ba608b8:/usr/share/nginx/html# ls
50x.html index.html
[root@docker1 mnt]# cd /yan
[root@docker1 yan]# ls
[root@docker1 yan]# docker exec -it nginx2 bash
root@be477783aa8a:/# cd /usr/share/nginx/html/
root@be477783aa8a:/usr/share/nginx/html# ls
root@be477783aa8a:/usr/share/nginx/html#
可以实现跨主机共享
客户端把请求给docker引擎,引擎再连接插件(存储),插件再连接底层的nfs.
插件就相当于一个接口,引擎不能直接连接Nfs。
Daemon docker引擎
/etc/docker/plugins/这个路径就是docker引擎缺省的扫描路径
直接使用nfs(网络文件共享系统),-v挂接也也可以,但是你需要写路径,不同主机路径不一样,不好操作,所以直接用插件便用使用
跨主机共享
将/mnt/nfs输出出去
底层文件nfs共享系统搭建
[root@docker1 ~]# mkdir /mnt/nfs
[root@docker1 ~]# vim /etc/exports
[root@docker1 ~]# cat /etc/exports
/mnt/nfs *(rw,sync)
[root@docker1 ~]# chmod 777 /mnt/nfs/
[root@docker1 ~]# ll -d /mnt/nfs/
drwxrwxrwx 2 root root 6 Feb 14 21:45 /mnt/nfs/
[root@docker1 ~]# yum install nfs-utils
[root@docker1 ~]# systemctl start nfs
[root@docker1 ~]# showmount -e
Export list for docker1:
/mnt/nfs *
[root@docker2 ~]# mkdir /mnt/nfs
[root@docker2 ~]# yum install nfs-utils -y
[root@docker2 ~]# mount 172.25.254.1:/mnt/nfs/ /mnt/nfs/
[root@docker2 ~]# cd /mnt/nfs/
[root@docker2 nfs]# ls
[root@docker2 nfs]# touch file
[root@docker2 nfs]# ls
file
[root@docker1 ~]# cd /mnt/nfs/
[root@docker1 nfs]# ls
file
[root@docker1 nfs]# rm -f file
[root@docker1 nfs]# ls
[root@docker2 nfs]# ls
安装插件
解压后里面就两个二进制程序,将它移动到/usr/local/bin/底下调用就行了
/etc/docker/plugins/这个路径就是docker引擎缺省的扫描路径(docker引擎会自动扫描这个路径上面的插件)
[root@docker1 ~]# ls
auth certs convoy.tar.gz docker
[root@docker1 ~]# tar zxf convoy.tar.gz
[root@docker1 convoy]# ls
convoy convoy-pdata_tools SHA1SUMS
[root@docker1 convoy]# mkdir -p /etc/docker/plugins/
启动插件服务
[root@docker1 convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[root@docker1 convoy]# ps ax
11173 pts/0 Sl 0:00 convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs
这个进程在后端
插件sock文件路径,只有程序启动后,sock才出现
[root@docker1 convoy]# cd /var/run/
[root@docker1 run]# cd convoy/
[root@docker1 convoy]# ls
convoy.sock
把sock路径写入docker缺省路径里面
[root@docker1 convoy]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
[root@docker1 convoy]# cat /etc/docker/plugins/convoy.spec
unix:///var/run/convoy/convoy.sock
给服务器2添加该插件
[root@docker2 ~]# ls
convoy.tar.gz
[root@docker2 ~]# tar zxf convoy.tar.gz
[root@docker2 convoy]# mv convoy* /usr/local/bin/
[root@docker2 convoy]# mkdir -p /etc/docker/plugins/
[root@docker2 convoy]# convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs &
[root@docker2 convoy]# cd /var/run/convoy/
[root@docker2 convoy]# ls
convoy.sock
[root@docker2 convoy]# echo "unix:///var/run/convoy/convoy.sock" > /etc/docker/plugins/convoy.spec
插件使用
[root@docker1 ~]# convoy --help
[root@docker1 ~]# convoy create vol1
[root@docker1 ~]# convoy list
{
"vol1": {
"Name": "vol1",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Mon Feb 14 22:15:16 +0800 2022",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol1",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Mon Feb 14 22:15:16 +0800 2022",
"VolumeName": "vol1"
},
"Snapshots": {}
}
}
提示权限错误了
[root@docker2 convoy]# convoy list
{}
no_root_squash 超级用户挂载的时候不要去变更权限,要不然就变成nfs nobody
[root@docker1 ~]# vim /etc/exports
[root@docker1 ~]# cat /etc/exports
/mnt/nfs *(rw,no_root_squash)
[root@docker1 ~]# showmount -e
Export list for docker1:
/mnt/nfs *
[root@docker1 ~]# exportfs -rv 刷新
exporting *:/mnt/nfs
[root@docker2 config]# convoy list
{
"vol1": {
"Name": "vol1",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Mon Feb 14 22:15:16 +0800 2022",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol1",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Mon Feb 14 22:15:16 +0800 2022",
"VolumeName": "vol1"
},
"Snapshots": {}
}
}
docker卷可以自动识别到
[root@docker2 config]# docker volume ls
DEBU[0707] Handle plugin activate: POST /Plugin.Activate pkg=daemon
DEBU[0707] Response: {
"Implements": [
"VolumeDriver"
]
} pkg=daemon
DEBU[0707] Handle plugin list volume: POST /VolumeDriver.List pkg=daemon
DEBU[0707] event=mountpoint object=volume pkg=daemon reason=prepare volume=vol1
DEBU[0707] event=mountpoint mountpoint= object=volume pkg=daemon reason=complete volume=vol1
DEBU[0707] Successfully got volume list for docker. pkg=daemon
DEBU[0707] Response: {
"Volumes": [
{
"Name": "vol1"
}
]
} pkg=daemon
ERRO[0707] Handler not found: POST /VolumeDriver.Capabilities pkg=daemon
DRIVER VOLUME NAME
convoy vol1
[root@docker2 config]# convoy create vol2
[root@docker1 ~]# convoy list
{
"vol1": {
"Name": "vol1",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Mon Feb 14 22:15:16 +0800 2022",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol1",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Mon Feb 14 22:15:16 +0800 2022",
"VolumeName": "vol1"
},
"Snapshots": {}
},
"vol2": {
"Name": "vol2",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Mon Feb 14 22:25:28 +0800 2022",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol2",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Mon Feb 14 22:25:28 +0800 2022",
"VolumeName": "vol2"
},
"Snapshots": {}
}
}
用convoy和docker volume都能操作
[root@docker1 ~]# docker volume rm -f vol2
[root@docker1 ~]# docker volume ls
DEBU[1386] Handle plugin list volume: POST /VolumeDriver.List pkg=daemon
DEBU[1386] event=mountpoint object=volume pkg=daemon reason=prepare volume=vol1
DEBU[1386] event=mountpoint mountpoint= object=volume pkg=daemon reason=complete volume=vol1
DEBU[1386] Successfully got volume list for docker. pkg=daemon
DEBU[1386] Response: {
"Volumes": [
{
"Name": "vol1"
}
]
} pkg=daemon
ERRO[1386] Handler not found: POST /VolumeDriver.Capabilities pkg=daemon
DRIVER VOLUME NAME
convoy vol1
[root@docker1 ~]# convoy list
{
"vol1": {
"Name": "vol1",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Mon Feb 14 22:15:16 +0800 2022",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol1",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Mon Feb 14 22:15:16 +0800 2022",
"VolumeName": "vol1"
},
"Snapshots": {}
}
}
插件搭建成功
容器跨主机迁移以及数据跨主机迁移
docker 管理卷可以考出容器内数据
[root@docker1 ~]# docker run -d --name demo -v vol1:/usr/share/nginx/html nginx
[root@docker1 ~]# cd /mnt/nfs/vol1/
[root@docker1 vol1]# ls
50x.html index.html
[root@docker1 vol1]# vim test.html
[root@docker1 vol1]# cat test.html
www.yan.com
yan wei qiu
由于没有做端口映射
[root@docker1 vol1]# curl 172.17.0.2
<title>Welcome to nginx!</title>
[root@docker1 vol1]# curl 172.17.0.2/test.html
www.yan.com
yan wei qiu
正常情况下容器是自动迁移的,集群
[root@docker1 vol1]# docker rm -f demo
现在是手动迁移,容器跨主机迁移,数据也跨主机迁移
[root@docker2 config]# docker run -d --name demo -v vol1:/usr/share/nginx/html nginx
[root@docker2 config]# curl 172.17.0.2/test.html
www.yan.com
yan wei qiu
卸载该插件
[root@docker2 config]# fg
convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs (wd: ~/convoy)
^CCaught signal interrupt: shutting down.
[root@docker2 config]# cd /etc/docker/plugins/
[root@docker2 plugins]# ls
convoy.spec
[root@docker2 plugins]# rm -fr convoy.spec
[root@docker2 plugins]# systemctl stop docker
[root@docker2 plugins]# systemctl daemon-reload
[root@docker2 plugins]# systemctl start docker
不卸载的话,docker重启会慢
[root@docker1 vol1]# convoy list
{}
[root@docker1 vol1]# convoy create vol1
[root@docker1 vol1]# convoy list
{
"vol1": {
"Name": "vol1",
"Driver": "vfs",
"MountPoint": "",
"CreatedTime": "Mon Feb 14 22:47:43 +0800 2022",
"DriverInfo": {
"Driver": "vfs",
"MountPoint": "",
"Path": "/mnt/nfs/vol1",
"PrepareForVM": "false",
"Size": "0",
"VolumeCreatedAt": "Mon Feb 14 22:47:43 +0800 2022",
"VolumeName": "vol1"
},
"Snapshots": {}
}
}
[root@docker1 plugins]# systemctl stop docker
[root@docker1 plugins]# systemctl daemon-reload
[root@docker1 plugins]# systemctl start docker
[root@docker1 plugins]# docker volume ls
DRIVER VOLUME NAME
慢是因为有缓存信息
解决
docker所有数据在这里
重启恢复了(之前所有卷的数据也丢失了),所以卷的缓存信息都在元数据里面
[root@docker1 plugins]# cd /var/lib/docker
[root@docker1 docker]# cd volumes/
[root@docker1 volumes]# ls
metadata.db
[root@docker1 volumes]# mv metadata.db /mnt/
[root@docker1 volumes]# ls
[root@docker1 volumes]# systemctl restart docker
可以看出元数据缓存之前的卷,还可以重新将该服务写入docker缺省路径,按照正常的方式关闭
[root@docker1 volumes]# cd /mnt/
[root@docker1 mnt]# ls
metadata.db nfs
[root@docker1 mnt]# cat metadata.db
��
�
�������>[��
�
�z3Ff�l
nvolumes:vol1{"Name":"","Driver":"convoy","Labels":null,"Options":null}
volumes