三、Docker镜像、数据卷

简介: 三、Docker镜像、数据卷

4.1 镜像是什么 & 镜像的特点

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

1. UnionFS(联合文件系统)

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

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

2. 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等等。

思考:平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??

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

3. 镜像分层

我们在pull镜像的时候,可以看到docker的镜像好像是一层一层的在下载。

拿tomcat为例,一个单独的tomcat一般只有100多M,但是docker拉取的镜像有400多M,这是为什么?

因为tomcat的运行不仅仅只需要tomcat,还需要java、centos等等依赖,所以docker的tomcat镜像中会包含有java、centos等等,所以会很大。

为什么docker镜像要采用这种分层结构?

最大的一个好处就是 - 共享资源。

比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

4. 镜像的特点

Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

4.2 Docker镜像commit操作补充

docker commit提交容器副本使之成为一个新的镜像

docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]

案例演示

① 拉取tomcat镜像并运行

从Hub上下载tomcat镜像到本地并成功运行:

docker pull tomcat
# 这里将host的8888端口映射到容器的8080端口
docker run -it -p 8888:8080 tomcat

我这里虚拟机没有GUI,所以需要通过windows的浏览器来访问tomcat,先看看防火墙是否开启以及是否开放了8888端口的访问权限。

firewall-cmd --permanent --zone=public --add-port=8888/tcp
firewall-cmd --reload

然后访问还是404。搜了一圈,解决办法:Docker方式启动tomcat,访问首页出现404错误

是因为docker的tomcat中/usr/local/tomcat下的webapps文件夹是空的,而原本应该在webapps文件夹下的内容都在旁边的webapps.dist文件夹中。

# 进入正在运行的容器目录
docer exec -it tomcat容器ID /bin/bash
# 将webapps.dist命名为webapps即可,在此之前可以吧webapps重命名成别的名字
mv webapps webapps2
mv webapps.dist webapps

访问成功:

退出(停止)tomcat:ctrl+c

如果使用docker run -it -P tomcat命令:随机分配一个端口号,映射给8080

② 使用commit提交我们修改过的tomcat

docker commit -m "rename webapps.dist to webapps" -a "mrlinxi" 85fc7f7c0182 mrlinxi/tomcat:0.1

新建并运行一个我们自己修改过的tomcat容器

docker run -it -p 3333:8080 mrlinxi/tomcat:0.1 注意版本号不要掉了不然docker会到仓库中找latest版本的mrlinxi/tomcat,显然是找不到的。

访问成功

③ 后台运行-d

docker run -d -p 8888:8080 mrlinxi/tomcat:0.1 后台启动tomcat。

可以通过docker attach 容器ID 或者 docker exec -it 容器ID 进入交互页面。

五、Docker容器数据卷

5.1 容器数据卷简述

先来看看Docker的理念:

  • 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
  • 容器之间希望有可能共享数据

Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用卷。

一句话:有点类似我们Redis里面的rdb和aof文件。

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

特点:

  1. 数据卷可在容器之间共享或重用数据
  2. 卷中的更改可以直接生效
  3. 数据卷中的更改不会包含在镜像的更新中
  4. 数据卷的生命周期一直持续到没有容器使用它为止
  5. 容器卷也可以完成主机到容器、容器到主机的数据共享(类似于 docker cp)

5.2 容器数据卷案例

1. 命令添加

命令:docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名

添加之前:

执行docker run -it -v /myDataVolume:/dataVolumeContainer centos

可以看到宿主机跟容器中都生成了对应文件夹:

备注:Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied

解决办法:在挂载目录后多加一个--privileged=true参数即可

检查是否挂载成功docker inspect 容器ID

① 容器和宿主机之间数据共享

可以看到实现了宿主机跟容器之间的双向同步。

② 容器停止退出后,主机修改后数据是否同步

容器先停止退出、主机修改host.txt、容器重启进入、查看主机修改过的host.log

③ 命令(带权限)

带权限的命令:docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名

ro表示read only只读。

执行:docker run -it -v /myDataVolume:/dataVolumeContainer:ro centos

2. DockerFile添加

具体描述放到后面讲,这里先使用。

主机根目录下新建mydocker文件夹并进入mkdir mydocker

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

VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]

说明:

出于可移植和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在Dockerfile中实现。

由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。

File构建

创建一个文件Dockerfile,然后添加以下内容:

vim Dockerfile
# volume test
FROM centos   
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,--------success1"
CMD /bin/bash

build后生成镜像:获得一个新的镜像

docker build -f /mydocker/Dockerfile -t mrlinxi/centos .

run我们设置好的容器

docker run -it 27ffb21c539d /bin/bash

可以看到容器内已经创建好了卷地址。

通过上述步骤,容器内的卷目录地址已经知道,对应的主机目录地址哪??

通过docker inspect 容器ID查看

5.3 数据卷容器

1. 总体介绍

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。实际上就是通过父容器传递数据卷的配置,通过传递数据卷的配置,将不同容器挂载到宿主机的相同目录下,从而实现各容器之间的数据传递

以上一步新建的镜像mrlinxi/centos为模板并运行容器dc01/dc02/dc03,他们已经具有容器卷/dataVolumeContainer1和/dataVolumeContainer2

2. 容器间传递共享(--volumes-from)

先启动一个父容器dc01,在dataVolumeContainer2中新增内容

docker run -it --name dc01 mrlinxi/centos
cd dataVolumeContainer2
touch doc1.txt
然后ctrl+p+q退出

dc02/dc03继承自dc01,通过--volumes-from继承

docker run -it --name dc02 --volumes-from dc01 mrlinxi/centos

然后在dc02和dc03的dataVolumeContainer2中分别添加各自的内容

docker run -it --name dc02 --volumes-from dc01 mrlinxi/centos
cd dataVolumeContainer2
touch doc2.txt
docker run -it --name dc03 --volumes-from dc01 mrlinxi/centos
cd dataVolumeContainer2
touch doc3.txt

回到dc01可以看到02/03各自添加的都能共享了

同理,dc02跟dc03里面都有其他容器的数据

删除dc01,dc02修改后dc03可否访问

删除dc01后,dc02和dc03之间的数据共享并不受影响。

--volumes-from可以理解为继承数据卷的配置,即便删除了dc01,但是配置没有动依然可以同步数据

可以docker inspect查一下,宿主目录是同一个

结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止


相关实践学习
基于Hologres轻松玩转一站式实时仓库
本场景介绍如何利用阿里云MaxCompute、实时计算Flink和交互式分析服务Hologres开发离线、实时数据融合分析的数据大屏应用。
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3 )前置知识要求   课程大纲 第一章 了解数据仓库概念 初步了解数据仓库是干什么的 第二章 按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章 数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章 采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章 用户行为数据仓库 严格按照企业的标准开发 第六章 搭建业务数仓理论基础和对表的分类同步 第七章 业务数仓的搭建  业务行为数仓效果图  
相关文章
|
2天前
|
存储 Ubuntu Linux
[Docker] 镜像讲解
[Docker] 镜像讲解
|
5天前
|
运维 前端开发 Devops
云效产品使用报错问题之流水线打包docker镜像时报网络代理有问题如何解决
本合集将整理呈现用户在使用过程中遇到的报错及其对应的解决办法,包括但不限于账户权限设置错误、项目配置不正确、代码提交冲突、构建任务执行失败、测试环境异常、需求流转阻塞等问题。阿里云云效是一站式企业级研发协同和DevOps平台,为企业提供从需求规划、开发、测试、发布到运维、运营的全流程端到端服务和工具支撑,致力于提升企业的研发效能和创新能力。
|
17天前
|
应用服务中间件 Docker 容器
docker 镜像常用命令
docker 镜像常用命令
38 0
|
17天前
|
Linux Shell 虚拟化
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
linux 部署docker容器虚拟化平台(二)--------docker 镜像制作方法
28 0
|
24天前
|
存储 Kubernetes API
Docker拉取镜像或者kubectl出现的这个解决方案x509: certificate signed by unknown authority
Docker拉取镜像或者kubectl出现的这个解决方案x509: certificate signed by unknown authority
61 2
|
25天前
|
Linux Docker 容器
Linux彻底卸载Docker包括运行拉取的镜像
Linux彻底卸载Docker包括运行拉取的镜像
24 1
|
29天前
|
NoSQL 关系型数据库 MySQL
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
安装Docker&镜像容器操作&使用Docker安装部署MySQL,Redis,RabbitMQ,Nacos,Seata,Minio
380 1
|
30天前
|
Docker 容器
docker删除镜像
docker删除镜像
51 0
|
1月前
|
网络安全 Docker 容器
docker 拷贝本地镜像
【2月更文挑战第27天】
|
1月前
|
SQL 关系型数据库 数据库
docker如何进入镜像其他的SQL
【2月更文挑战第25天】