Docker镜像原理和数据卷技术

总结:
挂载数据卷共有两种种方式
1.启动容器时使用 -v参数设置
具名挂载和匿名挂载
2.Dockerfile中设置数据卷
容器间也可以相互挂载数据卷,可以理解为病毒式的相互共享数据,其中一个容器删除,另一个容器的数据仍然还存在(两个容器挂载数据卷)

一、Docker镜像加载原理

镜像:

​ 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码,运行时(一个程序在运行或者在被执行的依赖)、库,环境变量和配置文件。

Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统是UnionFS联合文件系统。

UnionFS ( 联合文件系统) :Union文件系统( UnionFS )是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single vitualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性∶一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来文件系统会包含所有底层的文件和目录

分层理解

在这里插入图片描述

为什么Docker镜像使用分层的结构呢?

好处:资源共享!多个镜像都从相同Base镜像构建而来,宿主机只需要在磁盘保留一份base镜像,同时内存中只需要加载一份base镜像,这样镜像的每一层都可以被共享。

特点:

​ Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!这一层就是我们通常说的容器层,容器之下的都叫镜像层!

提交镜像

使用docker commit 命令提交容器成为一个新的版本

docker commit -m=“提交的描述信息”  -a="作者" 容器id 目标镜像名:[TAG] 

二、数据卷

1、定义介绍理解

个人:就是一个双向绑定,可以防止docker删除数据任然在本地。**

当容器删除后,数据自然也就没有了。 为了能保存数据在Docker中我们使用卷。

卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但卷不属于联合文件系统(Union FileSystem),因此能够绕过联合文件系统提供一些用于持续存储或共享数据的特性:。

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

特点:

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止

2、命令使用

运行容器,指定挂载数据卷命令:

#docker run -it -v 主机目录:容器目录
docker run -ia -v /home/test.java:/home centos /bin/bash

查看容器对应元数据docker inspect 容器id,可以在Mounts节点查看建立的数据卷信息。

在这里插入图片描述

三、MySQL容器建立数据卷同步数据

在Linux下的MySQL默认的数据文档存储目录为/var/lib/mysql,默认的配置文件的位置/etc/mysql/conf.d,为了确保MySQL镜像或容器删除后,造成的数据丢失,下面建立数据卷保存MySQL的数据和文件。

docker run -d -p 6603:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7

[root@iZwz99sm8v95sckz8bd2c4Z home]# docker images;
REPOSITORY            TAG       IMAGE ID       CREATED             SIZE
mytomcat              1.0       f189aac861de   About an hour ago   653MB
mysql                 5.7       f07dfa83b528   6 days ago          448MB
tomcat                latest    feba8d001e3f   10 days ago         649MB
nginx                 latest    ae2feff98a0c   12 days ago         133MB
centos                latest    300e315adb2f   2 weeks ago         209MB
portainer/portainer   latest    62771b0b9b09   5 months ago        79.1MB
elasticsearch         7.6.2     f29a1ee41030   9 months ago        791MB
[root@iZwz99sm8v95sckz8bd2c4Z home]# docker run -d -p 6603:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
72efdb845471b6bd19077b596af51122baa982c01211c39f989afaca556b149f
[root@iZwz99sm8v95sckz8bd2c4Z home]# cd /home
[root@iZwz99sm8v95sckz8bd2c4Z home]# ls
hai  mysql  pan  test  test.java
[root@iZwz99sm8v95sckz8bd2c4Z home]# cd mysql/conf
[root@iZwz99sm8v95sckz8bd2c4Z conf]# ls
[root@iZwz99sm8v95sckz8bd2c4Z conf]# cd /home/mysql/data
[root@iZwz99sm8v95sckz8bd2c4Z data]# ls
auto.cnf    client-cert.pem  ibdata1      ibtmp1              private_key.pem  server-key.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql               public_key.pem   sys
ca.pem      ib_buffer_pool   ib_logfile1  performance_schema  server-cert.pem
[root@iZwz99sm8v95sckz8bd2c4Z data]# ls
auto.cnf    client-cert.pem  ibdata1      ibtmp1              private_key.pem  server-key.pem
ca-key.pem  client-key.pem   ib_logfile0  mysql               public_key.pem   sys
ca.pem      ib_buffer_pool   ib_logfile1  performance_schema  server-cert.pem  test

如果使用配置的密码连接mysql服务失败,原因很大可能是本机挂载的配置文件中已有文件,将容器中的配置给覆盖了,我们将相应的本机文件中的文件配置删除即可

四、数据卷常用命令:

#创建数据卷
docker volume create my-vol

#查看所有的数据卷
$ docker volume ls
local my-vol

#查看指定数据卷的信息
$ docker volume inspect my-vol
[{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}]

#删除数据卷 docker volume rm ...
$ docker volume rm my-vol

#删除容器之时删除相关的卷
$ docker rm -v ...

数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷 。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。

#无主的数据卷可能会占据很多空间,要清理请使用以下命令
$ docker volume prune

#Docker 挂载主机目录的默认权限是读写 ,用户也可以通过添加readonly 参数指定为只读 。

具名挂载和匿名挂载

匿名挂载就是在指定数据卷的时候,不指定容器路径对应的主机路径,这样对应映射的主机路径就是默认的路径/var/lib/docker/volumes/中自动生成一个随机命名的文件夹。

#如下运行并匿名挂载Nginx容器:
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx01 -v /etc/nginx nginx
d3a27b969d122d5516cac75e99b17dff7aaaf1e0c042385c6b05990053f1259

#查看所有的数据卷volume的情况, VOLUME NAME这里的值是真实存在的目录。
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker volume ls
DRIVER    VOLUME NAME
local     0cd45ab893fc13971219ac5127f9c0b02491635d76d94183b0261953bdb52d26
local     668a94251e562612880a2fdb03944d67d1acdbbdae6ef7c94bee8685644f2956
local     e605f3dc4bf11ab693972592b55fb6911e5bf2083425fd58869c5f574998a09a

查看指定的数据卷信息的命令:docker volume inspect数据卷名称

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker volume inspect juming-nginx
[
    {
        "CreatedAt": "2020-12-29T22:40:25+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/juming-nginx/_data",
        "Name": "juming-nginx",
        "Options": null,
        "Scope": "local"
    }
]

Docker所有的数据卷默认在/var/lib/docker/volumes/ 目录下

两种挂载的区别

-v 容器内路径 #匿名挂载

-v 卷名:容器内路径 #具名挂载

-v /宿主机路径:容器内路径 #指定路径挂载

#指定数据卷映射的相关参数:

ro —— readonly 只读。设置了只读则只能操作宿主机的路径,不能操作容器中的对应路径。

rw ----- readwrite 可读可写

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:ro nginx
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx:rw nginx

五、Dockerfile中设置数据卷

也可以在Dockerfile中使用VOLUME指令给镜像添加一个或者多个数据卷

#下面使用Dockerfile构建一个新的镜像,dockerfile01文件的内容,匿名挂载了volume01和volume02两个目录:
FROM centos

VOLUME ["volume01","volume02"]

CMD echo "----end----"
CMD /bin/bash

#构建镜像
[root@iZwz99sm8v95sckz8bd2c4Z docker-test-volume]# docker build -f /home/docker-test-volume/dockerfile01 -t ethan/centos:1.0 .
Sending build context to Docker daemon  2.048kB
Step 1/4 : FROM centos
 ---> 300e315adb2f
Step 2/4 : VOLUME ["volume01","volume02"]
 ---> Running in 215ef28fd5a6
Removing intermediate container 215ef28fd5a6
 ---> f506ddf133d2
Step 3/4 : CMD echo "----end----"
 ---> Running in 62a1c4b9dc7b
Removing intermediate container 62a1c4b9dc7b
 ---> bbea81a6e94e
Step 4/4 : CMD /bin/bash
 ---> Running in 245d239f3776
Removing intermediate container 245d239f3776
 ---> 1df90e6fd790
Successfully built 1df90e6fd790
Successfully tagged ethan/centos:1.0

#完成镜像的生成后,启动自己生成的容器
[root@iZwz99sm8v95sckz8bd2c4Z docker-test-volume]# docker run -it 1df90e6fd790 /bin/bash
[root@828d43dba78e /]# ls -l
total 56
lrwxrwxrwx   1 root root    7 Nov  3 15:22 bin -> usr/bin
drwxr-xr-x   5 root root  360 Dec 29 15:41 dev
drwxr-xr-x   1 root root 4096 Dec 29 15:41 etc
drwxr-xr-x   2 root root 4096 Nov  3 15:22 home
lrwxrwxrwx   1 root root    7 Nov  3 15:22 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3 15:22 lib64 -> usr/lib64
drwx------   2 root root 4096 Dec  4 17:37 lost+found
drwxr-xr-x   2 root root 4096 Nov  3 15:22 media
drwxr-xr-x   2 root root 4096 Nov  3 15:22 mnt
drwxr-xr-x   2 root root 4096 Nov  3 15:22 opt
dr-xr-xr-x 111 root root    0 Dec 29 15:41 proc
dr-xr-x---   2 root root 4096 Dec  4 17:37 root
drwxr-xr-x  11 root root 4096 Dec  4 17:37 run
lrwxrwxrwx   1 root root    8 Nov  3 15:22 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3 15:22 srv
dr-xr-xr-x  13 root root    0 Dec 29 15:41 sys
drwxrwxrwt   7 root root 4096 Dec  4 17:37 tmp
drwxr-xr-x  12 root root 4096 Dec  4 17:37 usr
drwxr-xr-x  20 root root 4096 Dec  4 17:37 var
drwxr-xr-x   2 root root 4096 Dec 29 15:41 volume01
drwxr-xr-x   2 root root 4096 Dec 29 15:41 volume02

可以看到Mounts下有宿主机的挂载目录。因为dockerfile中没有指定宿主机目录,所以属于匿名挂载,在/var/lib/docker/volumes/目录下生成了随机命名的路径。

容器间的数据卷

容器数据卷是指建立数据卷,来同步多个容器间的数据,实现容器间的数据同步。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TyQUTgPa-1647498570855)(C:\Users\13262\AppData\Roaming\Typora\typora-user-images\1647484804729.png)]

首先启动容器1,volume01、volume02为挂载目录。

[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -it --name cnetos01 ethan/centos:1.0
[root@731d53b8c3d5 /]# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var  volume01	volume02

#然后启动容器2,通过参数--volumes-from,设置容器2和容器1建立数据卷挂载关系。
[root@iZwz99sm8v95sckz8bd2c4Z /]# docker run -it --name centos02 --volumes-from cnetos01 ethan/centos:1.0
[root@7f90d4147511 /]# ls -l
total 56
lrwxrwxrwx   1 root root    7 Nov  3 15:22 bin -> usr/bin
drwxr-xr-x   5 root root  360 Dec 30 14:58 dev
drwxr-xr-x   1 root root 4096 Dec 30 14:58 etc
drwxr-xr-x   2 root root 4096 Nov  3 15:22 home
lrwxrwxrwx   1 root root    7 Nov  3 15:22 lib -> usr/lib
lrwxrwxrwx   1 root root    9 Nov  3 15:22 lib64 -> usr/lib64
drwx------   2 root root 4096 Dec  4 17:37 lost+found
drwxr-xr-x   2 root root 4096 Nov  3 15:22 media
drwxr-xr-x   2 root root 4096 Nov  3 15:22 mnt
drwxr-xr-x   2 root root 4096 Nov  3 15:22 opt
dr-xr-xr-x 108 root root    0 Dec 30 14:58 proc
dr-xr-x---   2 root root 4096 Dec  4 17:37 root
drwxr-xr-x  11 root root 4096 Dec  4 17:37 run
lrwxrwxrwx   1 root root    8 Nov  3 15:22 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 Nov  3 15:22 srv
dr-xr-xr-x  13 root root    0 Dec 29 15:41 sys
drwxrwxrwt   7 root root 4096 Dec  4 17:37 tmp
drwxr-xr-x  12 root root 4096 Dec  4 17:37 usr
drwxr-xr-x  20 root root 4096 Dec  4 17:37 var
drwxr-xr-x   2 root root 4096 Dec 30 14:54 volume01
drwxr-xr-x   2 root root 4096 Dec 30 14:54 volume02

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值