docker学习(六)—— docker存储卷

版权声明:如需转载,请注明作者及出处 https://blog.csdn.net/qq_33317586/article/details/85461140

参考:https://www.imooc.com/article/26316


Docker镜像由多个只读层叠加而成,启动容器时,Docker会加载只读镜像层并在镜像栈顶部添加一个读写层

如果运行中的容器修改了一个现有的一个已存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本已隐藏,此即“写时复制”机制。

 


为什么需要存储卷?

这得从 docker 容器的文件系统说起。出于效率等一系列原因,docker 容器的文件系统在宿主机上存在的方式很复杂,这会带来下面几个问题:

  • 无法在多个容器之间共享数据。
  • 当容器删除时,容器中产生的数据将丢失。
  • 为了解决这些问题,docker 引入了数据卷(volume) 机制。数据卷是存在于一个或多个容器中的特定文件或文件夹,这个文件或文件夹以独立于 docker 文件系统的形式存在于宿主机中。数据卷的最大特定是:其生存周期独立于容器的生存周期

有状态应用:redis(需要持久存储数据),mysql(需要持久存储数据),tomcat(不用持久存储)

无状态应用:nginx(无持久存储)

有状态应用的数据如果放容器上,会有很大麻烦,容器挂了数据就没了,迁移麻烦。

Why Data Volume?

  • 关闭并重启容器,其数据不受影响;但删除Docker容器,则其更改将会全部丢失。
  • 存在的问题:
    • 存储于联合文件系统,不易于宿主机访问;
    • 荣期间共享数据不便
    • 删除容器其数据全部丢失

解决方案:“卷”

  • “卷”是容器上的一个或多个目录,此类目录可绕过联合文件系统,与宿主机上某目录“绑定(关联)”。(一个卷是一个目录)

Data volumes

  • Data volumes provide several useful features for persistent or shared data
    • Volume于容器初始化之时即会创建,由base image 提供的卷中的数据会于此期间完成复制
    • Data volumes can be shared and reused among containers
    • Changes to a data volume are made directly
    • Changes to a data volume will not be included when you updated an image
    • Data volumes persist even if the container itself is deleted
  • Volume的初衷是独立于容器的生命周期实现数据持久化,因此删除容器之时既不会删除卷,也不会对哪怕未引用的卷做垃圾回收操作。
  • 卷为docker提供了独立于容器的数据管理机制
    • 可以把镜像想象成静态文件,例如“程序”,把卷类比为动态内容,例如“数据”;于是,镜像可以重用,而卷可以共享。
    • 卷实现了“程序(镜像)”和“数据(卷)”分离,以及“程序(镜像)”和“制作镜像的主机”分离,用户制作镜像时无需再考虑镜像运行的容器所在的主句环境;

Volume types

Docker有两种类型的卷,每种类型都在容器中存在一个挂载点,但其在宿主机上的位置有所不同。

  • Bind mount volume 
    • a volume that points to a user-specified location on the host file system
  • Docker-managed volume
    • the docker daemon creates managed volumes in a portion of the host's file system that's owned by Docker

在容器中使用Volumes

为docker run命令使用-v选项即可使用volume

  • docker-managed volume
    • [root@docker2 ~]# docker container run --name t1 --rm -it -v /data busybox
    • [root@docker2 ~]# docker inspect -f {{.Mounts}} t1
  • Bind-mount Volume
    • [root@docker2 ~]# docker container run --name t1 --rm -it -v /data/volumes/t1:/data busybox
    • [root@docker2 _data]# docker inspect t1

docker管理卷

运行容器t1,-v指定挂载卷

[root@docker2 ~]# docker container run --name t1 --rm -it -v /data busybox
/ # ls /
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ # 

新开终端,查看容器挂载详情:

[root@docker2 ~]# docker inspect -f {{.Mounts}} t1
[{volume f46554c192d70109c2608ae5101d58739a0d6a2fb6fa64830e171ecc91dcc142 /var/lib/docker/volumes/f46554c192d70109c2608ae5101d58739a0d6a2fb6fa64830e171ecc91dcc142/_data /data local  true }]

到此目录下面创建文件

[root@docker2 ~]# cd /var/lib/docker/volumes/f46554c192d70109c2608ae5101d58739a0d6a2fb6fa64830e171ecc91dcc142/_data
[root@docker2 _data]# echo hehe>hehe.txt
[root@docker2 _data]# cat hehe.txt 
hehe

在容器中查看,有了

/ # ls /data/
hehe.txt
/ # cat /data/hehe.txt 
hehe

Bind-mount volumes

创建容器,指定将容器的/data目录挂载到宿主机的/data/volumes/t1

[root@docker2 ~]# docker container run --name t1 --rm -it -v /data/volumes/t1:/data busybox
/ # ls /
bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
/ # echo hello > /data/hello.txt

宿主机会自动创建该目录,当容器删除时该目录的文件从仍然存在,不会丢失

[root@docker2 ~]# docker inspect -f {{.Mounts}} t1
[{bind  /data/volumes/t1 /data   true rprivate}]
[root@docker2 ~]# ls /data/volumes/t1
hello.txt
[root@docker2 ~]# cat /data/volumes/t1/hello.txt 
hello

docker inspect的选项:

帮助信息:

[root@docker2 ~]# docker inspect --help

Usage:	docker inspect [OPTIONS] NAME|ID [NAME|ID...]

Return low-level information on Docker objects

Options:
  -f, --format string   Format the output using the given Go template
  -s, --size            Display total file sizes if the type is container
      --type string     Return JSON for specified type

使用:

[root@docker2 ~]# docker inspect -f {{.NetworkSettings}} t1
{{ 4d5c3e3e315c80afce68befbbff1045c8638334a543062c5093326546b7dba7b false  0 map[] /var/run/docker/netns/4d5c3e3e315c [] []} {c050ae065505a6fc02657274a3972897729f74553bc6e33997dd6f446986afad 172.17.0.1  0 172.17.0.4 16  02:42:ac:11:00:04} map[bridge:0xc420150000]}
[root@docker2 ~]# docker inspect -f {{.NetworkSettings.IPAddress}} t1
172.17.0.4

两个容器共享宿主机的卷

t1容器已经在运行,现在创建t2容器,共享一个卷

[root@docker2 ~]# docker container run --name t2 --rm -it -v /data/volumes/t1:/data busybox
/ # ls /data
hello.txt
/ # echo t2 container >> /data/hello.txt 

....


[root@docker2 ~]# docker container run --name t1 --rm -it -v /data/volumes/t1:/data busybox
/ # cat /data/hello.txt 
hello
t2 container

共享卷的两种使用方式

多个容器的卷使用同一个主机目录

  • [root@docker1 ~]# docker run --name b1 -it -v /data/docker_volumes/v1:/data --rm busybox
  • [root@docker1 ~]# docker run --name b2 -it -v /data/docker_volumes/v1:/data --rm busybox

复制其他容器的卷,为docker run 命令使用--volumes-from选项

  • [root@docker1 ~]# docker run --name b1 -it -v /data/docker_volumes/v1:/data busybox
  • [root@docker1 ~]# docker run --name b2 -it --volumes-from b1 --rm busybox

如下图

创建基础支撑容器:

  • [root@docker1 ~]# docker container run --name infra -it -v /data/infra/volume:/data/web/html busybox

创建nginx容器:

  • [root@docker1 ~]# docker container run --name nginx --network container:infra --volumes-from infra -it --rm busybox

创建tomcat:

  • [root@docker1 ~]# docker container run --name tomcat --network container:infra --volumes-from infra -it busybox

......


docker compose

docker容器单机编排工具

......

猜你喜欢

转载自blog.csdn.net/qq_33317586/article/details/85461140