当前位置:   article > 正文

Docker入门5——Docker镜像、容器数据卷_docker volumn ntfs

docker volumn ntfs

Docker入门5——Docker镜像、容器数据卷

本篇主要是介绍一下docker的镜像和容器数据卷的理论

image-20201026120338279

Docker镜像

首先我们抱着一个疑问,镜像是什么?

在实际开发中,可能遇到相同的复制环境就是镜像,在docker中,镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的所有内容,包括代码、运行时、库、环境变量和配置文件。

Dcoker镜像加载原理

UnionFS(联合文件系统)

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

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

Docker镜像加载原理

Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。 bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启 动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是 一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已 由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标 准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

image.png

我们看看docker中的centos,才200多M

image-20201026120711726

对于一个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直 接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的linux发行版, bootfs基本是一 致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。

分层

镜像分层

可以看到我们在下载镜像的时候,分了很多层

GIF 2020-10-26 12-11-38

查看镜像的分层方式可以通过docker image inspect命令

image-20201026121456232

深入理解分层

所有的 Docker 镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之 上,创建新的镜像层。

举一个简单的例子,假如基于 Ubuntu Linux 16.04 创建一个新的镜像,这就是新镜像的第一层;如果 在该镜像中添加 Python包,就会在基础镜像层之上创建第二个镜像层;如果继续添加一个安全补丁,就 会创建第三个镜像层。

该镜像当前已经包含 3 个镜像层,如下图所示(这只是一个用于演示的很简单的例子)。

image-20201026121537647

在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了 一个简单的例子,每个镜像层包含 3 个文件,而镜像包含了来自两个镜像层的 6 个文件。

image-20201026121548627

上图中的镜像层跟之前图中的略有区别,主要目的是便于展示文件。 下图中展示了一个稍微复杂的三层镜像,在外部看来整个镜像只有 6 个文件,这是因为最上层中的文件 7 是文件 5 的一个更新版本。

image-20201026121601569

这种情况下,上层镜像层中的文件覆盖了底层镜像层中的文件。这样就使得文件的更新版本作为一个新 镜像层添加到镜像当中。

Docker 通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保证多镜像层对外展示为统 一的文件系统。

Linux 上可用的存储引擎有 AUFS、Overlay2、Device Mapper、Btrfs 以及 ZFS。顾名思义,每种存储 引擎都基于 Linux 中对应的文件系统或者块设备技术,并且每种存储引擎都有其独有的性能特点。

Docker 在 Windows 上仅支持 windowsfilter 一种存储引擎,该引擎基于 NTFS 文件系统之上实现了分 层和 CoW[1]。

下图展示了与系统显示相同的三层镜像。所有镜像层堆叠并合并,对外提供统一的视图。

image-20201026121643759

分层特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部!

这一层就是我们通常说的容器层,容器之下的都叫镜像层!

Commit镜像

docker commit 从容器创建一个新的镜像。

docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[标签名tag]
  • 1

前几篇我们docker里启动的tomcat没有首页,是因为他的webapps下确实没有任何文件,今天我们再来具体看看

首先docker启动一个tomcat

[root@feng ~]# docker run -it -p 8090:8080 tomcat
  • 1

这里我挂在8090端口的

#查看一下tomcat的容器id
[root@feng ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS              PORTS                    NAMES
2a86a1dffb5f        tomcat                "catalina.sh run"   33 seconds ago      Up 31 seconds       0.0.0.0:8090->8080/tcp   determined_ramanujan
455bdc084fe9        portainer/portainer   "/portainer"        15 hours ago        Up 14 hours         0.0.0.0:8088->9000/tcp   prtainer

#进入这个tomcat的bash页面
[root@feng ~]# docker exec -it 2a86a1dffb5f /bin/bash
#看看webapps有什么
root@2a86a1dffb5f:/usr/local/tomcat# cd webapps
root@2a86a1dffb5f:/usr/local/tomcat/webapps# ls
#果然啥也没有
root@2a86a1dffb5f:/usr/local/tomcat/webapps# cd ..
#我们发现有一个webapps.dist的文件夹,里面有东西
root@2a86a1dffb5f:/usr/local/tomcat# ls
BUILDING.txt	 LICENSE  README.md	 RUNNING.txt  conf  logs	    temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin	      lib   native-jni-lib  webapps  work
#把他复制到webapps下看看
root@2a86a1dffb5f:/usr/local/tomcat# cp -r webapps.dist/* webapps
root@2a86a1dffb5f:/usr/local/tomcat# cd webapps
root@2a86a1dffb5f:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  manager
root@2a86a1dffb5f:/usr/local/tomcat/webapps# 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

此时运行的tomcat实例就是一个没有docs的容器,我们使用它为模板commit一个没有docs的tomcat新镜像,tomcat02

[root@feng ~]# docker commit -a="feng_tomcat" -m="no tomcat docs" 2a86a1dffb5f tomcat02:1.1
sha256:cf161fd1393d177c5e07ffac8c6a98c463965f2866a9ce65c0aac3bd960c39a8
[root@feng ~]# 
  • 1
  • 2
  • 3

再docker images一下,发现自己提交的docker镜像已经有了

image-20201026122845314

我们也可以启动看看

[root@feng ~]# docker run -it -p 8090:8080 tomcat02:1.1
  • 1

可以看到没有问题,随便启动

image-20201026122941147

随便进

image-20201026123145696

容器数据卷

概念

docker的理念回顾:

将应用和运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对于数据的要求,是希望能够 持久化的!

就好比,你安装一个MySQL,结果你把容器删了,就相当于删库跑路了,显然不合理吧。

image-20201026123644352

所以我们希望容器之间有可能可以共享数据,Docker容器产生的数据,如果不通过docker commit 生成 新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了!这样是行 不通的!

为了能保存数据在Docker中我们就可以使用卷!让数据挂载到我们本地!这样数据就不会因为容器删除 而丢失了!

image-20201026123551950

作用:

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

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

特点:

1、数据卷可在容器之间共享或重用数据

2、卷中的更改可以直接生效

3、数据卷中的更改不会包含在镜像的更新中

4、数据卷的生命周期一直持续到没有容器使用它为止

使用数据卷(重要)

其实我们命令篇已经涉及到了一些简单的挂载命令,这里细讲

在容器中直接使用命令添加
具名挂载
# 命令
docker run -it -v 宿主机绝对路径目录:容器内目录 镜像名

# 测试
[root@feng ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
  • 1
  • 2
  • 3
  • 4
  • 5

怎么看是否挂载成功?

使用查看容器详情命令

docker inspect 容器id
  • 1

image-20201026124339230

测试挂载

可以发现在宿主机和容器中互相修改对应文件,数据同步

GIF 2020-10-25 20-23-43

除了具名挂载,甚至还有匿名挂载

所有docker的卷没有指定目录的情况下都在cd /var/lib/docker/volumes/**/_data 下,通过具名挂载可方便地找到我们的卷,大多数情况下使用的都是具名挂载

image-20201026124900503

如何确定是具名挂载、匿名挂载还是指定地址挂载

-v 容器路径  #匿名挂载
-v 卷名:容器类路径 #具名挂载
-v /宿主机路径:容器内路径 #指定路径挂载
  • 1
  • 2
  • 3
改变文件的读写权限
# 改变文件的读写权限
# ro: readonly
# rw: readwrite
# 指定容器对我们挂载出来的内容的读写权限
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx:ro nginx
docker run -d -P --name nginx02 -v nginxconfig:/etc/nginx:rw nginx

#ro表示这个路径只能通过宿主机操作,容器无权限操作
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号