三、Docker镜像、数据卷

本文涉及的产品
数据可视化DataV,5个大屏 1个月
可视分析地图(DataV-Atlas),3 个项目,100M 存储空间
简介: 三、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查一下,宿主目录是同一个

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


相关实践学习
DataV Board用户界面概览
本实验带领用户熟悉DataV Board这款可视化产品的用户界面
阿里云实时数仓实战 - 项目介绍及架构设计
课程简介 1)学习搭建一个数据仓库的过程,理解数据在整个数仓架构的从采集、存储、计算、输出、展示的整个业务流程。 2)整个数仓体系完全搭建在阿里云架构上,理解并学会运用各个服务组件,了解各个组件之间如何配合联动。 3 )前置知识要求   课程大纲 第一章 了解数据仓库概念 初步了解数据仓库是干什么的 第二章 按照企业开发的标准去搭建一个数据仓库 数据仓库的需求是什么 架构 怎么选型怎么购买服务器 第三章 数据生成模块 用户形成数据的一个准备 按照企业的标准,准备了十一张用户行为表 方便使用 第四章 采集模块的搭建 购买阿里云服务器 安装 JDK 安装 Flume 第五章 用户行为数据仓库 严格按照企业的标准开发 第六章 搭建业务数仓理论基础和对表的分类同步 第七章 业务数仓的搭建  业务行为数仓效果图  
相关文章
|
11天前
|
缓存 Linux 网络安全
docker的镜像无法下载如何解决?
【10月更文挑战第31天】docker的镜像无法下载如何解决?
332 28
|
17天前
|
SQL 关系型数据库 数据库
国产数据实战之docker部署MyWebSQL数据库管理工具
【10月更文挑战第23天】国产数据实战之docker部署MyWebSQL数据库管理工具
56 4
国产数据实战之docker部署MyWebSQL数据库管理工具
|
7天前
|
关系型数据库 数据管理 应用服务中间件
【赵渝强老师】Docker的数据持久化
在生产环境中使用Docker时,为了实现数据的持久化和共享,可以通过数据卷(Data Volumes)和数据卷容器(Data Volume Containers)两种方式来管理数据。数据卷是一个独立于容器的挂载目录,可以跨多个容器共享和重用。数据卷容器则是一种特殊容器,用于维护数据卷,便于数据迁移和共享。本文通过示例详细介绍了这两种方法的使用步骤。
|
7天前
|
存储 关系型数据库 Linux
【赵渝强老师】什么是Docker的镜像
Docker镜像是一个只读模板,包含应用程序及其运行所需的依赖环境。镜像采用分层文件系统,每次修改都会以读写层形式添加到原只读模板上。内核bootfs用于加载Linux内核,根镜像相当于操作系统,上方为应用层。镜像在物理存储上是一系列文件的集合,默认存储路径为“/var/lib/docker”。
|
13天前
|
存储 监控 Linux
docker构建镜像详解!!!
本文回顾了Docker的基本命令和管理技巧,包括容器和镜像的增删改查操作,容器的生命周期管理,以及如何通过端口映射和数据卷实现容器与宿主机之间的网络通信和数据持久化。文章还详细介绍了如何使用Docker部署一个简单的Web应用,并通过数据卷映射实现配置文件和日志的管理。最后,文章总结了如何制作自定义镜像,包括Nginx、Python3和CentOS镜像,以及如何制作私有云盘镜像。
81 2
|
14天前
|
关系型数据库 MySQL Docker
docker环境下mysql镜像启动后权限更改问题的解决
在Docker环境下运行MySQL容器时,权限问题是一个常见的困扰。通过正确设置目录和文件的权限,可以确保MySQL容器顺利启动并正常运行。本文提供了多种解决方案,包括在主机上设置正确的权限、使用Dockerfile和Docker Compose进行配置、在容器启动后手动更改权限以及使用 `init`脚本自动更改权限。根据实际情况选择合适的方法,可以有效解决MySQL容器启动后的权限问题。希望本文对您在Docker环境下运行MySQL容器有所帮助。
28 1
|
16天前
|
存储 Java 开发者
成功优化!Java 基础 Docker 镜像从 674MB 缩减到 58MB 的经验分享
本文分享了如何通过 jlink 和 jdeps 工具将 Java 基础 Docker 镜像从 674MB 优化至 58MB 的经验。首先介绍了选择合适的基础镜像的重要性,然后详细讲解了使用 jlink 构建自定义 JRE 镜像的方法,并通过 jdeps 自动化模块依赖分析,最终实现了镜像的大幅缩减。此外,文章还提供了实用的 .dockerignore 文件技巧和选择安全、兼容的基础镜像的建议,帮助开发者提升镜像优化的效果。
|
21天前
|
Docker 容器
docker中查看已创建的数据卷
【10月更文挑战第16天】
34 3
|
20天前
|
存储 缓存 Java
Java应用瘦身记:Docker镜像从674MB优化至58MB的实践指南
【10月更文挑战第22天】 在容器化时代,Docker镜像的大小直接影响到应用的部署速度和运行效率。一个轻量级的Docker镜像可以减少存储成本、加快启动时间,并提高资源利用率。本文将分享如何将一个Java基础Docker镜像从674MB缩减到58MB的实践经验。
32 1
|
21天前
|
存储 缓存 Docker
docker中挂载数据卷到容器
【10月更文挑战第16天】
23 2