知识点8--Docker镜像的秘密

news2024/12/23 9:04:19

前面的知识点我们介绍了docker的日常使用,但其实docker存在的核心意义是交付环境,也就是镜像,本片知识点带大家了解一下镜像的秘密。

镜像本身是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,包括系统内核、代码、运行时库、环境变量和配置文件。

有意思是docker镜像的本身,用的是unionfs,也就是联合文件系统,这导致docker的镜像,它底层是按层级来打包的,我们下载镜像的时候也可以看到,下载过程中日志输出了中间层的下载,只是下载完成后,我们只能看到一个最终层。在老版本的时候,通过参数可以将中间程也查询出来,但是在前面介绍命令的时候说了,新版本这个好像有点问题,查不出来了。

UnionFS(联合文件系统)也叫Union文件系统,是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交的方式,把文件系统一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。使得镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。它的特性也很明显,加载的时候一次同时加载多个文件系统,从结果来看只能看到一个,应为UnionFS会把所有的文件系统叠加起来,最终的结果就包含了所有中间层的底层文件和目录。

知道了docker镜像的生成原理,我们再了解一下镜像的加载原理。docker镜像加载主要靠两个东西,第一个是bootfs(boot file system),主要包含bootloader和kernel,bootloader主要是引导加载kernel(内核),Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层同样是bootfs,这一层与我们典型的Linux/Unix系统是一样的,这就让docker的镜像在加载时,和普通系统启动类似,同样拥有boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。第二个是rootfs (root file system),在bootfs之上,包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。当这两个东西都加载完成后,docker镜像中该有的应用服务也就跟随着被启动。用tomcat镜像举例,如下图解。
在这里插入图片描述

前面知识点说过的一个话题就是docker使用的时候都是在linux上,很少在WINDOWS或者其他支持的发行系统上运行,这一点的原因就出在镜像加载上,上面说了,镜像加载有一个rootfs不同系统的发行版,但是这个root fs很小,可以去看一下vmware使用的完整版镜像文件,普遍都是好几个g,但是我们前面介绍命令的时候,我们下载过一个centos的docker镜像向却只有几百兆。这就说明docker镜像中的系统是一个精简的OS,只需要包括最基本的命令工具和程序库就可以,说句大白话,无论这个OS是什么系统WINDOWS也好,Linux系统也好,它都是不完整的,而doctor的生态环境就是运行在我们IT界,IT界都是linux,也就是说大部分的镜像,它的OS就是Linux系统,可是里面的精简linuxOS又不完整,那怎么办?此时docker会调用宿主机的资源。这就是docker的日常使用也会在linux上的原因。

说到这里,再提一嘴镜像前面镜像命令知识点提到的两个ID,Image ID是在下载每一层时的一个对应ID,最终我们用命令看到的其实就是最终层的image ID,而digest ID是你要下载的这个镜像,完整的ID,这个ID在docker的镜像生态圈里全网唯一。

如果有人问你,docker镜像底层为什么采用这种一层一层的文件结构时,你要告诉他这样做的好处就是共享资源、减少开发成本,就和我们写代码封装类和方法一样,如有多个镜像都从相同的一个base镜像构建而来,那么宿主机只需要在磁盘上保留一份base镜像,同时内存中也只需加载一份base镜像,其他的镜像添加一层base镜像做为中间层就可以了。

我们还要知道两个概念词,首先docker的镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层就是我们操作的容器,官方叫“容器层”,下面的都叫“镜像层”

有了这两个概念词之后,前面在容器命令中,交互式和守护进程两种创建容器方式,就需要补充一个概念了,所有的容器层,他本质上只是为了某一种服务而存在,就意味着如果他所承载的那个服务停止时,这个容器也就跟随着停止了。


上面我们说了一堆理论,主要是让大家知道镜像的概念,不要学空中楼阁的技术,现在我们说怎么自己做一个镜像,把我们自己的环境打镜像包。如果跟着前面知识点看过来的朋友,应该知道在容器命令那一篇里面没有介绍-P和-p的用法,就是留在这里的,这里先说明一下-p是自定义指定端口映射,-P是容器会把内部的端口随机映射给宿主机的任意端口。同时介绍打包镜像,我们以tomcat为基础镜像,没有的先下载一个。

docker pull tomcat

首先我们要知道一个概念,自己打包镜像的原理是把某一个已有的镜像做基础镜像,对其生成的容器做修改,并以此为模板打包为镜像。在操作上和git很类似,也是用commitpush命令。

第一步我们需要一个tomcat的容器,并且把端口映射到宿主机上,使用的参数为-p 宿主机端口:docker容器端口,如果你需要映射多个端口,你就需要添加多个-p,或者去修改配置文件,配置文件的位置下面会提到。

docker run -it -p 8888:8080 tomcat
或者
docker run -it -P tomcat

在这里插入图片描述
因为我们是交互式创建了一个容器,所以会保持启动,并开始运行tomcat,此时我们用外部电脑的浏览器访问宿主机的端口,看一下是否能访问tomcat。

可以拿到响应结果,而不是访问不到就行,下载的docker镜像可能没有默认的ROOT-webapp

在这里插入图片描述


如果你用的是老版本的docker很可能映射不生效,这里和大家说一下这个情况的原因,docker是一个虚拟化的技术,虚拟化出来的容器,虽然是一个简易的OS,但它本质上人家也不是姥姥不疼舅舅不爱的,所以它也需要有个虚拟网卡并拥有一个ip,但是整个问题就出老版本docker官方有一个对于我们开发者来说是个BUG的特点,容器在创建的时候,容器的网卡用的docker自己的默认模式,也叫Bridge模式,这个模式在我们不另行指定容器虚拟网络相关配置的时候,不会自己去向宿主机申请ip并生成虚拟网卡,而是直接跳过这个过程,只创建一块lo的回环网卡,这就导致在宿主机上能够知道有该容器的存在,但是其他终端访问容器时就找不到这个容器了。

早些年我在刚使用docker的时候,也不理解为什么官方要开发成这样,但最后用的多了,发现容器的ip有些尴尬,说重要没有它外部访问不到容器,说不重要没有IP也不影响本身容器的运行,不过新版本docker修复了这个问题,默认的网络模式为default,不会出现上述问题,但不管怎么说解决老版本这个问题的方法有两个。

方法一:对于已有的容器,先关闭容器,去你的本地镜像仓库里找containers文件夹,在这个文件夹下找到对于容器下的网络配置文件,比如containers/a77c1xxx/hostconfig.json,修改容器的网络模式为host。最后一定要重启docker服务。这个配置文件路径新版本没有变,任然在使用,不要以为只是用来解决该问题的

修改网络模式:
"NetworkMode":"host"

如果你后期需要修改容器的端口映射,也可以在该配置文件中找到如下配置
"PortBindings":{
	"3306/tcp": [{				//内部端口
		"HostIp": "",
		"HostPort": "3309"		//外部访问端口
	}]
}

方法二:通过修改docker的配置文件,使得在创建容器的时候,给一个网络IP配置。

所有宿主机修改docker的配置文件,声明容器可以自动占有的ip资源
{
"bip": "172.17.0.1/16"
}

注意:如果你用的是docker-compose,那就用下面这个配置
{
"default-address-pools": [
    {
        "base": "172.17.0.1/16",
        "size": "255.255.255.0"
    }
] 
}

修改完配置后运行下面的三条命令
systemctl restart docker
#所有宿主机删除不再使用的网络 ,不然重建网络后ip不变
docker network prune
#所有宿主机添加一条ip策略,意思是访问docker容器所在网段的ip时,宿主机使用一个ip进行转发,192.168.1.200每个宿主机都要改成符合宿主机网络策略的IP同时不能都用一个啊!!!
ip route add 172.19.0.0/16 via 192.168.1.200

随后我们要进入这个容器,进入的时候注意必须使用exec,这里顺便再说明一个知识点,我前面在介绍容器命令的时候,关于如何进入一个已启动容器的命令,我介绍了两个,exec和attach,他们两个的区别在于,exec是以一个全新的会话进入容器执行操作,attach是使用一个你登录过的会话进入,就比如在本例中,在运行的容器中运行着前台tomcat,如果你使用attach则进入之后,你会发现没有任何输出,其实他本质不是没有任何输出,他只是连接到了你上一个使用的会话,也就是目前仍然在运行tomcat前台日志输出的那个会话,所以你需要用exec 以一个全新的绘画登录进去

下图就是我专程新建了另一个容器,用attach进去的结果,没有任何的输出,只是保持tomcat的会话,ctrl+c强制退出,看输出则证实了我上面说的
在这里插入图片描述
抛开进入命令不说,我们接着案例走,查询容器,确定IP映射没有问题,并进入容器

[root@hdp3 containers] docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS         PORTS                                       NAMES
0fff686e8de0   tomcat    "catalina.sh run"   10 seconds ago   Up 9 seconds   0.0.0.0:8888->8080/tcp, :::8888->8080/tcp   wizardly_payne

[root@hdp3 containers] docker exec -it 0fff686e8de0 /bin/bash
root@0fff686e8de0:/usr/local/tomcat# 

现在我们要删除确保tomcat中的webapps没有任何东西,这里注意应用在你自己实操的时候,进入容器后,就应该做你自己的开发环境了,只是本案例的目的就是做一个tomcat没有任何webapp且端口不一样的镜像

root@0fff686e8de0:/usr/local/tomcat/webapps# pwd
/usr/local/tomcat/webapps
root@0fff686e8de0:/usr/local/tomcat/webapps# ls -l
total 0

接着重点来了,用快捷键退出,并使用commit生成一个我们自己的镜像,atguigu/是命名空间,工作中随着项目走

[root@hdp3 containers]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                       NAMES
0fff686e8de0   tomcat    "catalina.sh run"   34 minutes ago   Up 34 minutes   0.0.0.0:8888->8080/tcp, :::8888->8080/tcp   wizardly_payne

[root@hdp3 containers] docker commit -a="wy" -m="我自己的tomcat" 0fff686e8de0 atguigu/mytomcat:1.2
sha256:4f6fc450f49cbcb4be69d29904104f265d57627c823bbd9381e01c24233aa011

[root@hdp3 containers] docker images
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
atguigu/mytomcat   1.2       4f6fc450f49c   14 seconds ago   680MB
tomcat             latest    fb5657adc892   11 months ago    680MB
centos             latest    5d0da3dc9764   14 months ago    231MB

最后我们要使用自己的镜像,实例化一个容器,确保commit成功,但是你用自己的镜像实例化容器的时候要注意,标签一定要写,因为你不写则定死latest,就会出现下面的问题

[root@hdp3 containers] docker run -it atguigu/mytomcat
Unable to find image 'atguigu/mytomcat:latest' locally
docker: Error response from daemon: pull access denied for atguigu/mytomcat, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
See 'docker run --help'.

所以如果你的镜像标签不是latest,就要带上,不要以为是随着最新版本变的
在这里插入图片描述
这个时候你可以去浏览器访问tomcat了,但是问题有来了我们访问那个端口?8080?8888?
在这里插入图片描述

在这里插入图片描述
你会发现都访问不到。这是由于commit,不会受容器运行数据的影响!!!!!它任然遵守着容器中承载着的服务的配置,即便你去改对应的配置,也只是修改了默认配置而已,依然不会有运行数据的影响。因此你在实例化容器的时候任然需要运行如下命令

docker run -it -p 8888:8080 atguigu/mytomcat:1.2

此时你再去访问就可以了
在这里插入图片描述
本篇的最后,再给大家说一点,上面的案例,我们用的都是交互式启动,这个是不合适的,不可能每次新建一个容器就手动退出一次,所以我们用的最多的启动方式其实是守护进程启动

[root@hdp3 ~] docker run -d -p 8889:8080 atguigu/mytomcat:1.2
d0d498fffdb783741cd9ae95eecf7a25ca5cda7aeac418c3c2cd4022b1fe64b0

[root@hdp3 ~] docker ps
CONTAINER ID   IMAGE                  COMMAND             CREATED              STATUS              PORTS                                       NAMES
d0d498fffdb7   atguigu/mytomcat:1.2   "catalina.sh run"   About a minute ago   Up About a minute   0.0.0.0:8889->8080/tcp, :::8889->8080/tcp   nervous_driscoll
83579336d8a2   atguigu/mytomcat:1.2   "catalina.sh run"   12 minutes ago       Up 12 minutes       0.0.0.0:8888->8080/tcp, :::8888->8080/tcp   hardcore_satoshi

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/67169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Tensorflow学习二】神经网络优化方法学习率、激活函数、损失函数、正则化

文章目录预备知识tf.wheretf.random.RandomState.rand() 返回一个[0,1)之间的随机数np.vstack() 将数组按照垂直方向叠加np.mgrid[ ] np.ravel( ) np.c_[ ] 一起使用可以生成网格坐标点复杂度、学习率复杂度指数衰减学习率激活函数Sigmoid激活函数Tanh激活函数ReLu激活函数Leak…

今天面了个00后测试员,让我见识到了内卷届的天花板

深耕IT行业多年,我们发现,对于一个程序员而言,能去到一线互联网公司,会给我们以后的发展带来多大的影响。 很多人想说,这个我也知道,但是进大厂实在是太难了,简历投出去基本石沉大海&#xff0…

Linux安装KVM

一、虚拟化技术 1、全虚拟化和半虚拟化技术 如果给KVM、XEN简单归类的话,KVM是完全虚拟化技术又叫硬件辅助虚拟化技术(Full Virtualization)。相反,XEN是半虚拟化技术(paravirtualization),也叫做准虚拟化…

线上环境内存溢出-OutOfMemoryError

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 线上环境内存溢出-OutofMemoryError前言一、OutOfMemoryError是什么?二、实际情况(参考)解决方案1.实战总结前言 公司线上环境&#xff0…

getBoundingClientRect属性研究

getBoundingClientRect属性研究 概念 getBoundingClientRect 返回 width、height和下图中的6个属性 实测总结: 抓住一个核心点,就是height、width的值: box-sizing 是 content-box时,width和height 内容borderpaddingbox-siz…

国家级专新特精“小巨人”「皖仪科技」携手企企通,打造采购数字化平台成功上线

近日,安徽皖仪科技股份有限公司(以下简称“皖仪科技”)携手企企通共同打造的数字化采购管理系统成功上线。基于皖仪科技的采购业务流程和规则,形成全新的数字化采购体系,在推动企业降本增效的同时,实现企业…

单商户商城系统功能拆解42—应用中心—商城公告

单商户商城系统,也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法,例如拼团,秒杀,砍价,包邮…

冠状病毒疾病优化算法 (COVIDOA)附matlab代码

​✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。 🍎个人主页:Matlab科研工作室 🍊个人信条:格物致知。 更多Matlab仿真内容点击👇 智能优化算法…

npp各个平台npp数据比较

文章目录1GEE中的npp数据2 与其他数据的比较1GEE中的npp数据 在GEE上查阅npp,可以看到有连个数据集,一个是Terra的,另一个是Aqua的。 我比较了两个的不同,发现Terra是2000-目前的,而Aqua是2002-目前的,都是…

2022吴恩达机器学习课程——第一课

注:参考B站视频教程 视频链接:【(强推|双字)2022吴恩达机器学习Deeplearning.ai课程】 文章目录第一周一、监督学习与无监督学习二、线性回归三、梯度下降第二周一、向量化二、特征缩放第三周一、逻辑回归二、训练逻辑回归模型三、逻辑回归中的梯度下降四…

[运维]如何快速压缩一个数据库的硬盘占用大小(简单粗暴但有效)

文章目录前言一、数据库文件为什么会那么大?1.数据空间2.日志空间3.索引空间4.其他二、我的解决方案总结前言 在维护网站时我们经常会遇到数据库占用服务器磁盘空间的问题。高端的食材往往只需要采用最朴素的烹饪方式。本文我讲一个简单粗暴但有效的方法。本文以Sq…

RabbitMQ快速上手以及RabbitMQ交换机的四种模式

Win10安装&#xff1a; ​win10下安装 RabbitMQ​_柚几哥哥的博客-CSDN博客 Linux安装&#xff1a; Linux下载安装 RabbitMQ​_柚几哥哥的博客-CSDN博客 一、基础使用 1、导入依赖 <!--RabbitMQ--><dependency><groupId>org.springframework.boot</g…

JAVA12_06学习总结(JDBC,工具类优化)

今日内容 1. PreparedStatement PreparedStatement--预编译步骤1)注册驱动2)获取数据库连接对象3)准备sql语句--不需要拼接--需要的参数全部使用 ? 占位符4)通过数据库连接对象,获取预编译对象,同时将sql语句房费数据库,将参数和参数类型都存储在预编译中Connection中的方法…

均匀传输线的串扰和饱和长度

下图为串扰的电路模型&#xff0c;动态线与静态线之间通过互容与互感联系&#xff0c;这样也说明了动态线的信号耦合到静态线上的条件是存在di/dt或者dv/dt时&#xff0c;也就是说只在信号边沿上产生串扰&#xff0c;当电压或者电流为常数的时候静态线上就不会有串扰的信号。 信…

扩散模型:Diffusion models as plug-and-play priors作为即插即用先验的扩散模型

扩散模型&#xff1a;Diffusion models as plug-and-play priors作为即插即用先验的扩散模型0.摘要1.概述2.方法2.1.问题设置2.2.将去噪扩散概率模型作为先验3.实验&#xff1a;图像生成3.1.MNIST的简单说明3.2.使用现成组件条件生成脸部图像4.实验&#xff1a;语义分割附录B&a…

Ubuntu 20.04 系统最快安装WRF软件手册

前言 天气研究和预报&#xff08;WRF&#xff09;模型是一种中尺度数值天气预报系统&#xff0c;在全球范围内用于业务预报和研究目的。 这是在基于Intel的i7&#xff08;12核&#xff09;Linux Ubuntu 20.04 LTS系统上安装WRF 4.2.1的版本。这将有助于初学者在普通台式机上实现…

树莓派4b+mcp2515实现CAN总线通讯和系统编程(一.配置树莓派CAN总线接口)

文章目录前言硬件连线树莓派环境准备启用树莓派ssh启用mcp2515驱动下载can-utils工具测试CAN通讯开启CAN网卡测试发送和接收前言 树莓派本身是没有CAN通讯能力的&#xff0c;但他有mcp2515模块的驱动&#xff0c;可以通过SPI来控制mcp2515进行CAN的通讯。 本章主要讲,如何使能…

基于卡尔曼滤波的二维目标跟踪(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

双十二选哪个品牌led灯好一点?国产led灯这些品牌护眼好

现在绝大部分人造灯光都是使用led灯珠作为发光源了&#xff0c;所以led灯普遍的质量都比较好&#xff0c;也能护眼&#xff0c;特别是习惯晚上熬夜工作、学习、看书的人群&#xff0c;也都会选择led台灯来辅助照明&#xff0c;因为相比传统的家用室内顶灯&#xff0c;led护眼灯…

【小游戏】Unity游戏愤怒的足球(小鸟)

目录 1.弹弓逻辑 2.鸟的逻辑 3.GameManager主逻辑 文末有源工程地址 难度系数: ★★★★☆ 游戏玩法: 愤怒的足球,其实就是经典的愤怒的小鸟换图 项目简介: 功能完善,主要代码逻辑完整 本文内容: 记录一下这个工程,对内部代码逻辑没有深入了解有待以后发掘 1.弹弓逻…