linux cpu占用率如何看
226
2022-10-28
Docker 存储卷
Docker的两类存储资源
storage driver
Docker镜像的分层结构
容器由最上面一个可写的容器层,以及若干只读的镜像层组成,容器的数据就存放在这些层中。分层结构使镜像和容器的创建、共享以及分发变得非常高效,而这些都要归功于Docker storage driver。正是storage driver实现了多层数据的堆叠并为用户提供个单一 的合并之后的统一 视图。Docker支持多种storage driver,有AUFS ,Device Mapper, Btrfs, OverlayFS, VFS 和ZFS。它们都能实现分层的架构,同时又有各自的特性。Docker 官方给优先使用Linux发行版默认的storage driver。Docker安装时会根据当前系统的配置选择默认的driver.默认driver具有最好的稳定性,因为默认driver在发行版上经过了严格的测试。
运行docker info查看centos的默认driver:
docker info
Ubuntu用的AFUS,底层文件系统是extfs,各层数据存放在 /var/lib/docker/aufs。
Redhat/CentOS的默认driver是Device Mapper, SUSE 则是Btrfs。对于某些容器,直接将数据放在由storage driver。
Data Volume之bind mount
storage driver和data volume是容器存放数据的两种方式。
Data Volume本质上是Docker Host文件系统中的目录或文件,能够直接被mount到容器的文件系统中。Data Volume有以下特点:
Data Volume是目录或文件,而非没有格式化的磁盘(块设备) . 容器可以读写volume中的数据。 volume数据可以被永久的保存,即使使用它的容器已经销毁。
这是需要持久化的数据,并且应该与镜像分开存放。
在具体的使用上,docker提供了两种类型的volume:bind mount 和 docker managed volume。
bind mount
bind mount是将host上已存在的目录或文件mount到容器。
[root@localhost ~]# mkdir /htdocs [root@localhost ~]# mv index.html /htdocs/
通过 -v将其mount到~]# docker run -d -p 8000:80 -v /htdocs/:/usr/local/apache2/htdocs 就是apache server存放静态文件的地方。由于/usr/oca/apache2/htdocs已经存在,原有数据会被隐藏起来,取而代之的是host /htdocs/中的数据,这与linux mount命令的行为是致的。
[root@localhost ~]# curl 127.0.0.1:8000
this is testcurl显示的确实是/htdocs/html.index的内容,更新一下:
[root@localhost ~]# echo "hug" > /htdocs/index.html [root@localhost ~]# curl 127.0.0.1:8000 hug
确实生效了,bind mount 可以让 host 与容器共享数据。
把容器销毁,对bind mount 也不会有什么影响。
另外还可以指定数据的读写权限,默认是可读写,指定为只读:
[root@localhost ~]# docker run -d -p 8000:80 -v /htdocs/:/usr/local/apache2/htdocs:ro mount 目录,还可以单独指定一个文件:
docker run -d -p 8000:80 -v /htdocs/test.index:/usr/local/apache2/htdocs/test.index 中的源文件必须要存在,不然会当作一个新目录bind mount给容器。mount point有很多应用场景,比如我们可以将源代码目录mount到容器中,在host中修改代码就能看到应用的实时效果。再比如将mysql容器的数据放在bind mount里,这样host可以方便地备份和迁移数据。bind mount的使用直观高效,易于理解,但它也有不足的地方: bind mount需要指定host文件系统的特定路径,这就限制了容器的可移植性,当需要将容器迁移到其他host,而该host没有要mount的数据或者数据不在相同的路径时,操作会失败。
docker managed volume
在使用上不需指定mount 源,指名 mount point 就行了。
[root@localhost ~]# docker run -d -p 8000:80 -v /usr/local/apache2/htdocs docker 需要一个 data volume,并将其 mount 到 /usr/local/apache2/htdocs。data volume 可以在容器的配置信息中找到:
[root@localhost ~]# docker inspect f480d2 Mounts": [ { "Type": "volume", "Name": "3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46", "Source": "/var/lib/docker/volumes/3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46/_data", "Destination": "/usr/local/apache2/htdocs",
Source 就是该 volume 在host上的目录。每当容器申请mount docker managed volume时,docker都会在/var/lib/docker/volumes 下生成一个目录,这个目录就mount源。
[root@localhost ~]# ls /var/lib/docker/volumes/3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46/_data/
还可以用 docker volume查看目录:
[root@localhost ~]# docker volume inspect 3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46 [ { "CreatedAt": "2020-06-02T17:50:00+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46/_data", "Name": "3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46", "Options": null, "Scope": "local" } ]
目前,docker volume只能查看docker managed volume,还看不到 bind mount,也无法知道volume对应的容器。
查看index:
[root@localhost ~]# curl 127.0.0.1:8000
It works!可以直接修改index,或添加一个index:
[root@localhost ~]# vim /var/lib/docker/volumes/3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46/_data/index.html [root@localhost ~]# vim /var/lib/docker/volumes/3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46/_data/test.index
bind mount 与 docker managed volume的区别
相同:两者都是 host 文件系统的某个路径
共享数据
共享数据是 volume 的关键特性, volume 如何在容器与host之间,容器与容器之间共享数据。
容器与host共享数据
有两种类型的data volume,它们均可实现在容器与host之间共享数据,但方式有所区别。对于bind mount是非常明确的:直接将要共享的目录mount到容器。具体请参考前面managed volume就要麻烦点。由于volume位于host中的目录,是在容器启动时才生成,所以需要将共享数据拷拷贝到 volume中。
[root@localhost ~]# docker run -d -p 8000:80 -v /usr/local/apache2/htdocs httpd [root@localhost ~]# curl 127.0.0.1:8000
It works! [root@localhost ~]# docker cp /htdocs/index.html 97373dd7f9b15f241:/usr/local/apache2/htdocs [root@localhost ~]# curl 127.0.0.1:8000 hugDocker cp可以在容器与host之间拷贝数据,也可以直接通过Linux的cp命令复制到/var/lib/docker/volumes/。
容器之间共享数据
第一种可以将共享数据放在 bind mount 中,然后将其 mount 到多个容器。
将 /htdocs mount 到三个~]# docker run --name web1 -d -p 80 -v /htdocs:/usr/local/apache2/htdocs httpd b004d4df2fe4667d01e15b1a936afd726ac7ef896dba9336d064636018cd0ab3 [root@localhost ~]# docker run --name web2 -d -p 80 -v /htdocs:/usr/local/apache2/htdocs httpd fe50f6b90793bfd385ea86ad205cab2a20b3985f911435c2f1c4463d1416f6f9 [root@localhost ~]# docker run --name web3 -d -p 80 -v /htdocs:/usr/local/apache2/htdocs httpd 2da85061d406c8cf5cbe061fb42a5e58257816dcd9eaa7db82b7ce951305ae39
查看当前主页:
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2da85061d406 " 6 seconds ago Up 5 seconds 0.0.0.0:32770->80/tcp web3 fe50f6b90793 " 11 seconds ago Up 10 seconds 0.0.0.0:32769->80/tcp web2 b004d4df2fe4 " 20 seconds ago Up 19 seconds 0.0.0.0:32768->80/tcp web1 [root@localhost ~]# curl 127.0.0.1:32768 hug [root@localhost ~]# curl 127.0.0.1:32769 hug [root@localhost ~]# curl 127.0.0.1:32770 hug
修改 volume 中的主页文件,再次查看:
[root@localhost ~]# echo "hhhhhhhhhh" > /htdocs/index.html [root@localhost ~]# curl 127.0.0.1:32769 hhhhhhhhhh [root@localhost ~]# curl 127.0.0.1:32768 hhhhhhhhhh [root@localhost ~]# curl 127.0.0.1:32770 hhhhhhhhhh
用volume container共享数据
volume container是专门为其他容器提供volume 的容器。它提供的卷可以是 bind mount ,也可以是 docker managed volume。
创建一个 volume container:
[root@localhost ~]# docker create --name vc_data -v /htdocs:/usr/local/apache2/htdocs -v /other/userful/tools httpd f5192fe00a8932df333ee2eafb0ff8797b053329e5e236bc29975f848d9a0b56
将容器命名为 vc_data。注意这里执行的是docker create命令,这是因为volume container 的作用只是提供数据,它本身不需要处于运行状态。容器 mount 了两个 volume:
1.bind mount,存放web server的静态文件2.docker managed volume,存放一些实用工具
通过docker inspect 查看 volume
[root@localhost ~]# docker inspect vc_data | grep Destina "Destination": "/usr/local/apache2/htdocs", "Destination": "/other/userful/tools",
其他容器可以使用 - -volumes-from 使用 vc_data这个 volume container:
[root@localhost ~]# docker run --name web1 -d -p 80 --volumes-from vc_data httpd aab5751a7bb371f5deffef3ad98bcee95d87dcc69c08525eaec6b3417852b381 [root@localhost ~]# docker run --name web2 -d -p 80 --volumes-from vc_data httpd a9bf189425bd4e258750fcc7b81be1e86a7184971cb49303ddf5dad579b6c676 [root@localhost ~]# docker run --name web3 -d -p 80 --volumes-from vc_data httpd bdd982b6d819fab3cfd8791f5058d8f02f875507cc98030309a9707d36f35046
三个vc_data,查看都有哪些volume:
[root@localhost ~]# docker inspect web1 | grep Destina "Destination": "/usr/local/apache2/htdocs", "Destination": "/other/userful/tools",
验证共享效果:
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bdd982b6d819 " About a minute ago Up About a minute 0.0.0.0:32773->80/tcp web3 a9bf189425bd " About a minute ago Up About a minute 0.0.0.0:32772->80/tcp web2 aab5751a7bb3 " About a minute ago Up About a minute 0.0.0.0:32771->80/tcp web1 [root@localhost ~]# echo "this this hsith" > /htdocs/index.html [root@localhost ~]# curl 127.0.0.1:32771 this this hsith [root@localhost ~]# curl 127.0.0.1:32772 this this hsith [root@localhost ~]# curl 127.0.0.1:32773 this this hsith
volume container的特点:
1.与bind mount相比,不必为每个容器指定 host path,所有path都在volume container中定义好了,容器只需与volume container关联,实现了容器与host的解耦。
2.使用volume container的容器其mount point是致的, 有利于配置的规范和标准化,但也带来定的局限, 使用时需要综合考虑。
另-种在容器之间共享数据的方式是data-packed volume container。
data-packed volume container
volume container 的数据在host里,有没有办法将数据完全放到volume container中,同时又能与其他容器共享呢?当然可以,通常我们称这种容器为data-packed volume container.其原理是将数据打包到镜像中,然后通过docker managed volume共享。
我们用Dockfile构建镜像:
[root@localhost /]# mkdir datapacked [root@localhost /]# cd datapacked/ [root@localhost datapacked]# ls [root@localhost datapacked]# cat Dockerfile FROM httpd ADD htdocs /usr/local/apache2/htdocs VOLUME /usr/local/apache2/htdocs
ADD将静态文件添加到容器目录/usr/local/apache2/htdocs.。VOLUME 的作用与-v等效,用来创建docker managedvolume, mount point为/usr/ocal/apache2/htdocs,因为这个目录就是ADD添加的目录,所以会将已有数据拷贝到volume中。
build 新镜像
[root@localhost datapacked]# mv /htdocs/ . [root@localhost datapacked]# docker build -t data .
用新镜像创建 data-packed volume container:
[root@localhost datapacked]# docker create --name vc_data2 data 345255edfd3dfb6368d3c3ad932dd6aadcffd46a00cacc6f2bf849d69a8f885c
因为在Dockerfile中使用了VOlUME指令,这里就不需要指定volume的mount point,启动容器并使用data-packed volume container。
[root@localhost datapacked]# docker run -d -p 8000:80 --volumes-from vc_data2 httpd dca8789bd56ea79574866ac115a352d9466708eb0abd6ade0129df0b5ff550bd [root@localhost datapacked]# curl 127.0.0.1:8000 this this hsith
容器能够正确读取volume中的数据。data-packed volume container是自包含的,不依赖host提供数据,具有很强的移植性,非常适合只使用静态数据的场景,比如应用的配置信息、web server的静态文件等,
volume生命周期管理
Data Volume中存放的是要的应用数据,如何管理volume对应用至关重要。前面我们主要关注的是volume的创建、共享和使用。
备份
因为volume实际上是host文件系统中的目录和文件,所以volume的备份实际上是对文件系统的备份。所有的本地镜像都存在host的/myregistry目录中,我们要做的就是定期备份这个目录。
恢复
volume的恢复也很简单,如果数据损坏了,直接用之前备份的数据拷贝到/myregistry就可以了。
迁移
如果我们想使用更新版本的Registry,这就涉及到数据迁移,方法是:
docker stop当前Registry容器。 启动新版本容器并mount原有volume.
docker run -d -P 0005000 -V /myregisty:/ar/lib/registry registry:latest
当然,在启用新容器前要确保新版本的默认数据路径是否发生变化。
销毁
可以删除不再需要的volume, volume 删除后数据是找不回来的。
docker不会销毁bind mount,删除数据的工作只能由host负责。对于docker managed volume,在执行docker rm删除容器时可以带上-V参数,docker 会将容器使用到的volume一·并删除, 但前提是没有其他容器mount该volume,目的是保护数据。如果删除容器时没有带-v这样就会产生孤儿volume,好在docker提供了volume 子命令可以对docker managedvolume进行维护。请看下面的例子:容器bbox使用的docker managed volume可以通过docker volume Is查看到。
删除孤儿volume:
[root@localhost ~]# docker volume rm 3b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff463b1a7628fe1772d91497ad2a518b1b1637ea51f26a70f9415d477c539739ff46 [root@localhost ~]# docker volume rm $(docker volume ls -q
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~