浙江省水利建设行业协会网站,建e网效果图,做百科需要用什么网站做参考,wordpress都有哪些权限文章目录 1、什么是存储卷?2、为什么需要存储卷?3、存储卷分类4、管理卷 Volume5、绑定卷 bind mount6、临时卷 tmpfs7、综合实战-MySQL 灾难恢复8、常见问题 1、什么是存储卷?
存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立… 文章目录 1、什么是存储卷?2、为什么需要存储卷?3、存储卷分类4、管理卷 Volume5、绑定卷 bind mount6、临时卷 tmpfs7、综合实战-MySQL 灾难恢复8、常见问题 1、什么是存储卷?
存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着当我们在容器中的这个目录下写入数据时容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的目录。
在宿主机上的这个与容器形成绑定关系的目录被称作存储卷。卷的本质是文件或者目录它可以绕过默认的联合文件系统直接以文件或目录的形式存在于宿主机上。
宿主机的/data/web 目录与容器中的/container/data/web 目录绑定关系然后容器中的进程向这个目录中写数据时是直接写在宿主机的目录上的绕过容器文件系统与宿主机的文件系统建立关联关系使得可以在宿主机和容器内共享数据库内容让容器直接访问宿主机中的内容也可以宿主机向容器写入内容容器和宿主机的数据读写是同步的。
容器的销毁并不会影响存储卷的数据
2、为什么需要存储卷?
1. 数据丢失问题
容器按照业务类型总体可以分为两类
无状态的数据不需要被持久化有状态的数据需要被持久化
显然容器更擅长无状态应用。因为未持久化数据的容器根目录的生命周期与容器的生命周期一样容器文件系统的本质是在镜像层上面创建的读写层运行中的容器对任何文件的修改都存在于该读写层当容器被删除时容器中的读写层也会随之消失。
虽然容器希望所有的业务都尽量保持无状态这样容器就可以开箱即用并且可以任意调度但实际业务总是有各种需要数据持久化的场景比如 MySQL、Kafka 等有状态的业务。因此为了解决有状态业务的需求Docker 提出了卷Volume的概念。
2. 性能问题 UnionFS 对于修改删除等一般效率非常低如果对一于 I/O 要求比较高的应用如redis 在实现持化存储时是在底层存储时的性能要求比较高。
3. 宿主机和容器互访不方便
宿主机访问容器或者容器访问要通过 docker cp 来完成应用很难操作
4. 容器和容器共享不方便
3、存储卷分类
目前 Docker 提供了三种方式将数据从宿主机挂载到容器中
volume docker 管理卷默认映射到宿主机的/var/lib/docker/volumes 目录下只需要在容器内指定容器的挂载点是什么而被绑定宿主机下的那个目录是由容器引擎 daemon 自行创建一个空的目录或者使用一个已经存在的目录与存储卷建立存储关系这种方式极大解脱用户在使用卷时的耦合关系缺陷是用户无法指定那些使用目录临时存储比较适合。
bind mount 绑定数据卷映射到宿主机指定路径下在宿主机上的路径要人工的指定一个特定的路径在容器中也需要指定一个特定的路径两个已知的路径建立关联关系。
tmpfs mount 临时数据卷映射到于宿主机内存中一旦容器停止运行tmpfs mounts 会被移除数据就会丢失用于高性能的临时数据存储。 4、管理卷 Volume
创建卷 存储卷可以通过命令方式创建也可以在创建容器的时候通过 -v and --mount 指定。
方式一Volume 命令操作
命令清单如下
命令别名功能docker volume create创建存储卷docker volume inspect显示存储卷详细信息docker volume lsdocker volume list列出存储卷docker volume prune清理所有无用数据卷docker volume rm删除卷使用中的无法删除
docker volume create 创建存储卷
docker volume create [OPTIONS]关键参数 -d, --driver指定驱动默认是 local - -label指定元数据
创建匿名卷
docker volume create创建命名卷
docker volume create myvolume1docker volume inspect 查看卷详细信息
docker volume inspect [OPTIONS] VOLUME [VOLUME...]关键参数 -f指定相应个格式如 json
查看myvolume1的详细信息
docker volume inspect myvolume创建一个卷这个卷的默认位置是 /var/lib/docker/volumes 下如果改过根目录对应的目录也会发生变化
docker volume ls 列出卷
docker volume ls [OPTIONS]关键参数 - -format指定相应个格式如 json,table - -filter,-f: 过滤 -q: 仅显示名称
docker volume rm 删除卷需要容器不使用卷中的数据也会被删除
docker volume rm [OPTIONS] VOLUME [VOLUME...]关键参数 -f, --force:强制删除
删除名为myvolume1的存储卷
docker volume rm myvolume1docker volume prune 删除不使用的本地卷如果是命名卷即使没使用也不会被删除
docker volume prune [OPTIONS]关键参数 - -filter:过滤 -f, --force :不提示是否删除 方式二-v 或者--mount 指定 -v 和-mount 都可以完成管理卷的创建
-v 参数完成目录映射
docker run -v name:directory[:options] ......
#这种创建的匿名卷
docker run -v directory[:options] ......参数 第一个参数卷名称 第二个参数卷映射到容器的目录 第三个参数选项如 ro 表示 readonly
运行一个容器并使用-v参数指定目录映射
docker run -d --name mynginx -v volnginx1:/usr/share/nginx/html/ nginx:1.21.3查看存储卷映射的目录下是否有数据 当我们使用-v参数指定容器目录映射到宿主机时容器目录下的数据也会在宿主机中
进入容器内部的指定目录下删除文件再退出容器再查看宿主机中对应的文件是否还存在 在运行容器时指定为readonly再次测试是否能被删除 发现即使是rm -f 也无法删除
如果在宿主机中删除对应的文件是能被删除的也就是参数 -ro 只能限定容器而不能限定宿主机 –mount 参数完成目录映射
--mount keyvalue,keyvalue
#这种创建的匿名卷
关键参数 type 类型表示 bind, volume, or tmpfs source src 对于命名卷这是卷的名称。对于匿名卷省略此字段 destinationdst,target文件或目录挂载在容器中的路径 ro,readonly: 只读方式挂载
采用 mount 创建命名 volume
docker run -d --name mynginx2 --mount srcvolnginx3,dst/usr/share/nginx/html nginx:1.21.3采用 mount 创建匿名volume
docker run -d --name mynginx3 --mount ,dst/usr/share/nginx/html nginx:1.21.3既然是匿名如何知道名为mynginx3的容器它的存储卷是哪个呢
通过docker inspect mynginx3查看其中有个名为Mounts的json里面有个name字段就是 方式三Dockerfile 匿名卷 通过 Dockerfile 的 VOLUME 可以创建 docker 管理卷后续博客再讲
我们也可以通过 dockerfile 的 VOLUME 指令在镜像中创建 Data Volume这样只要通过该镜像创建的容器都会存在挂载点但值得注意的是通过 VOLUME 指令创建的挂载点无法指定主机上对应的目录而是由 docker 随机生成的
操作案例
命令创建管理卷
docker volume inspect test1启动一个nginx并进行管理卷的映射
docker run -d --name nginx -p 80:80 -v test1:/usr/share/nginx/html nginx:1.21.3查看存储卷映射的宿主机中对应的目录下是否有数据 修改nginx的首页index.html 进入容器查看对应的index.html是否有变化 已经发生了变化再通过浏览器访问也能成功访问到nginx的页面 如果在宿主机上对文件做了修改那么在容器内部也是会实时响应的
Docker卷的生命周期如果将容器删除卷中的数据是不会被删除的除非手动删除这个卷 Docker 卷共享
docker volume create test
docker run -d --name nginx1 -p 6379:80 -v test:/usr/share/nginx/html nginx:1.21.3
docker run -d --name nginx2 -p 6380:80 -v test:/usr/share/nginx/html nginx:1.21.3
docker ps查看卷在宿主机的映射位置并修改里面的index.html 分别进入两个容器内查看index.html是否被修改 分别通过浏览器访问查看nginx的页面是否一致 共享卷本质就多个卷映射到宿主机的同一个目录下因此数据如果一旦修改影响是相互的
5、绑定卷 bind mount
-v 和-mount 都可以完成绑定卷的创建
通过-v创建
docker run -v name:directory[:options] .........参数
第一个参数宿主机目录这个和管理卷是不一样的 第二个参数卷映射到容器的目录 第三个参数选项如 ro 表示 readonly
创建绑定卷
docker run -d --name nginx -v /data/fl/testbind/:/usr/share/nginx/html/ nginx:1.21.3查看对应的绑定信息
docker inspect nginx查看宿主机绑定的目录 里面什么都没有这跟管理卷是不一样的管理卷中有数据会将数据拷贝到宿主机上而绑定卷是不会的绑定卷的数据是来自宿主机的宿主机有绑定卷就有否则就没有
创建一个文件然后进入容器内查看 容器里也只有宿主机创建的这个文件
通过 --mount创建
--mount keyvalue,keyvalue关键参数
type 类型表示 bind, volume, or tmpfs source src 宿主机目录这个和管理卷是不一样的 destinationdst,target文件或目录挂载在容器中的路径 ro,readonly: 只读方式挂载
docker run -d --name nginx --mount typebind,src/data/fl/testbind/,dst/usr/share/nginx/html/ nginx:1.21.3检测一下容器的Mounts 进入容器创建一个文件再在宿主机中查看是否存在 用mount创建绑定卷在绑定时如果宿主机的目录不存在则失败但是用-v参数时宿主机的目录不存在会自动创建 如果宿主机中存在内容和容器里的内容一样则会以宿主机的为准-v和 --mount是一样的 绑定卷的共享和管理卷的共享是一样的宿主机中进行数据的修改同步影响其他容器
6、临时卷 tmpfs
临时卷数据位于内存中在容器和宿主机之外
tmpfs 局限性
不同于卷和绑定挂载不能在容器之间共享 tmpfs 挂载这个功能只有在 Linux 上运行 Docker 时才可用
创建卷 方式一指定 --tmpfs 创建
--tmpfs /appdocker run -d --name nginx --tmpfs /test nginx:1.21.3进入容器在映射的目录下创建文件然后再重启查看文件是否存在 结果发现文件消失了这就是临时卷的一个缺点容器退出或者重启后数据都会消失
方式二 --mount 指定参数创建
--mount keyvalue,keyvalue关键参数 type 类型表示 bind, volume, or tmpfs destinationdst,target挂载在容器中的路径 tmpfs-sizetmpfs 挂载的大小以字节为单位。默认无限制 tmpfs-modetmpfs 的八进制文件模式。例如700 或 0770。默认为 1777或全局可写
docker run -d --name nginx --mount typetmpfs,dst/test1 nginx:1.21.3进入容器在映射的目录下创建文件然后再重启查看文件是否存在 结果跟前面的一样数据已经丢失了
内存会覆盖容器内的数据
docker run -d --name nginx --tmpfs /usr/share/nginx/html/ -p 80:80 nginx:1.21.3进入容器内查看/usr/share/nginx/html/下是否有数据 里面并没有数据说明数据已经被覆盖了创建一个html文件通过浏览器访问
echo hello tmpfs!index.html退出容器重启再通过浏览器访问就会发现出现403原因就是重启后创建的html文件就会丢失 - -mount同目录处理、内存读取、大小限制验证
创建临时卷并指定内存大小为1M
docker run -d --name nginx --mount typetmpfs,dst/usr/share/nginx/html/,tmpfs-size1m -p 80:80 nginx:1.21.3进入容器内创建html文件通过浏览器验证是否能正常访问nginx 将一个超过1M的文件拷贝到容器的根目录下 在容器内将这个文件拷贝到容器映射的目录下结果就会发现拷贝失败因为前面设置了内存限制为1M tmpfs失踪了
创建一个nginx容器进入容器创建一个文件 在另一个终端上查找这个文件是能找到的 再创建一个容器进入容器创建一个文件 在另一个终端上查找这个文件结果是找不到 这就验证了tmpfs是把文件放在宿主机的内存里面在宿主机中通过find或者cat等命令就不能随意找到这些文件也就验证了临时卷是具备一定的安全性的一些保密性的数据就可以考虑用tmpfs不过也需要考虑容器重启或停止数据就会消失这个局限性
7、综合实战-MySQL 灾难恢复
使用 MySQL 5.7 的镜像创建容器并创建一个普通数据卷 mysql-data 用来保存容器中产生的数据。需要在容器中连接 MySQL 服务 并创建数据库 test, 并在在该数据库中创建一个简单的表并插入一些数据进来
创建容器并绑定卷
docker run --name mysql -v /data/fl/mysqltest:/var/lib/mysql -e MYSQL_ROOT_PASSWORDfltest -d mysql:5.7连接 MySQL 的 shell 创建一个 user 数据库并在该数据库中创建一个 student 表在表中插入了两条数据 在宿主机中查看 volume 可以看到容器中 MySQL 创建的数据库和表数据以及持久化到宿主机挂载的目录下了
有一天莫名其妙停电了 然后服务器重启了这个时候 Mysql 没有起来然后有个哥们看磁盘空间不多了把所有停止的容器都删除了。结果我们的 Mysql 也没有了 幸好我们的数据还在这个时候怎么恢复呢我们再次启动我们的运行命令确保目录映射一致就能找回我们的数据了 8、常见问题
什么时候用 Volume什么时候用 bind、tmpfs volumevolume 是 docker 的宿主机文件系统一部分用于不需要规划具体目录的场景 bindbind mount 完全是依赖于主机的目录结构和操作系统用于目录需要提前规划比如 mysql 的目录需要个空间大的其他服务有不占用的时候用 volume 就不太合适了 tmpfs用于敏感文件存储文件不想存储的宿主机和容器的可写层之中
存储卷在实际研发中带来了哪些问题 跨主机使用 docker 存储卷是使用其所在的宿主机上的本地文件系统目录也就是宿主机有一块磁盘这块磁盘并没有共享给其他的 docker 主机容器在这宿主机上停止或删除是可以重新再创建的但是不能调度到其他的主机上这也是 docker 本身没有解决的问题所以 docker 存储卷默认就是 docker 所在主机的本地但是自己搭建一个共享的 NFS来存储 docker 存储的数据也可以实现但是这个过程强依赖于运维人员的能力。所以未来应用的存储和数据往往分离越来越多的分布式存储方案出现如 s3 系列nfs 等 启动参数未知 容器有一个问题一般与进程的启动不太一样就是容器启动时选项比较多如果下次再启动时很容器会忘记它启动时的选项所以最好有一个文件来保存容器的启动这就是容器编排工具的作用 一般情况下是使用命令来启动操作 docker,但是可以通过文件来读也就读文件来启动读所需要的存储卷等但是它也只是操作一个容器如果要几十上百个容器操作就需要专业的容器编排工具 这种一般像开源的 k8s各个云厂商也有自己的企业版编排软件 复杂场景仍然需要运维 对于有状态要持久的集群化组件如 mysql 的主从。部署维护一个 Mysql 主从需要运维知识、经验整合进去才能实现所谓的部署扩展或缩容出现问题后修复必须要了解集群的规模有多大有多少个主节点有多少个从节点主节点上有多少个库这些都要一清二楚才能修复故障这些就强依赖于运维经验 这种复杂的场景往往还是需要人力很难有完美的工具出现