云原生制品那些事(1):容器镜像

2024-01-11 03:59
文章标签 镜像 云原生 容器 制品

本文主要是介绍云原生制品那些事(1):容器镜像,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题图摄于北京颐和园

(未经授权,请勿转载本公众号文章)

上篇文章和大家说到 Kubernetes 无法根本性移除 Docker的影响,原因是 Docker 发明的镜像格式极具革命性,无可替代。不管 Kubernetes 那边风吹浪打,Docker 我自巍然不动。从本篇开始和大家说说镜像那些事,共分四次连载,从《Harbor权威指南》一书节选的纯技术干货,敬请关注、转发和收藏。

第一篇:容器镜像的结构

第二篇:OCI 镜像规范

第三篇:OCI 制品

第四篇:Registry 的作用原理

《Harbor权威指南》目前当当网低于半价优惠中,点击下图直接购买。

相关活动:

2020云原生生态大会,最值得期待的技术盛会!

容器镜像的结构

容器有不可改变性(immutability)和可移植性(portability)。容器把应用的可执行文件、依赖文件及操作系统文件等打包成镜像,使应用的运行环境固定下来不再变化;同时,镜像可在其他环境下重现同样的运行环境。这些特性给运维和应用的发布带来极大的便利,这要归功于封装应用的镜像。

1.1  镜像的发展

2013 年,Docker推出容器管理工具,同时发布了封装应用的镜像。这是 Docker与之前各种方案的重大区别,也是 Docker 得以胜出和迅速流传的主要原因。可以说,镜像体现了 Docker 容器的核心价值。

2014年,Docker 把其镜像格式归纳和定义为 Docker 镜像规范v1。在这个规范中,镜像的每个层文件(layer)都包含一个存放元数据的 JSON 文件,并且用父ID来指明上一层镜像。这个规范有两个缺点:镜像的 ID 是随机生成的,可近似认为具有唯一性,可以用来标识镜像,但是用相同内容构建出来的层文件的ID并不一样,通过ID无法确认完全相同的层,不利于层的共享;每层都绑定了父层,紧耦合的结构不利于独立存放层文件。(本文来自公众号:亨利笔记)

2016年,Docker 制定了镜像规范v2,并在 Docker 1.10 中实现了这个规范。镜像规范v2分为 Schema 1和 Schema 2。Schema 1主要兼容使用 v1 规范的 Docker 客户端,如 Docker 1.9 及之前的客户端。Schema 2 主要实现了两个功能:支持多体系架构的镜像和可通过内容寻址的镜像,其中最大的改进就是根据内容的SHA256 摘要生成 ID,只要内容相同,ID 就是一样的,可区分相同的层文件(即可内容寻址)。从2017年2月起,镜像规范v1不再被 Registry 支持,用户需要把已有的v1镜像转化为v2镜像才能推送到Registry中。

OCI 在 2017 年 7 月发布了 OCI 镜像规范1.0。因为 Docker v2 的镜像规范已经成为事实上的标准,OCI 镜像规范实质上是以 Docker 镜像规范v2为基础制定的,因此二者在绝大多数情况下是兼容或相似的。

1.2  Docker 镜像的结构

Docker 容器镜像主要包含的内容是应用程序所依赖的根文件系统(rootfs)。这个根文件系统是分层存储的,基础层通常是操作系统的文件,然后在基础层上不断叠加新的层文件,最终将这些层组合起来形成一个完整的镜像。当通过镜像启动容器时,镜像所有的层都转化成容器里的只读(read only)文件系统。同时,容器会额外增加一个读写层,给应用程序运行时读写文件使用。这样的层文件结构可由联合文件系统(UnionFS)实现。(本文来自公众号:亨利笔记)

Docker容器镜像通常由 “docker build” 命令依照 Dockerfile 构建的,Dockerfile 描述了镜像包含的所有内容和配置信息(如启动命令等)。下面是一个简单的Dockerfile 例子:

FROM ubuntu:20.04

RUN apt update && apt install -y python

RUN apt install -y python-numpy

ADD myApp.py /opt/

在这个例子中,容器镜像的基础镜像是操作系统 Ubuntu 20.04,然后安装Python 软件包,再安装 Python 库 NumPy,最后增加应用程序 myApp。在镜像构建完成之后会有4个层文件,如下图所示。

图中的镜像层在容器创建时作为只读文件系统加载到容器中,此外,容器运行时会为每个容器实例都创建一个可读写层,叠加在文件系统的最上层,用于应用读写文件。容器的不可改变性就是通过镜像的镜像层(只读)实现的。另外,无论镜像在哪种环境下启动,始终有相同的镜像层,从而实现了应用的可移植性。

Docker使用分层来管理镜像,有以下好处。(本文来自公众号:亨利笔记)

(1)方便基础层和依赖软件层的共享(如包含操作系统文件、软件包等),不同的镜像可以共享基础层或软件层,在同一台机器上存放公共层的镜像时只需保存一份层文件,可以大大减少文件存储空间。

(2)在构建镜像时,已构建过的层会被保存在缓存中,再次构建时如果下面的层不变,则可以通过构建缓存来缩短构建时间。

(3)因为很多时候同一个应用的镜像更新时变化的只是最上层(应用层),所以分层可以减少同种镜像的分发时间。

(4)分层可以更加方便地跟踪镜像的变化,因为每一层都是和构建命令关联的,所以可以更好地管理镜像的变化历史。

Docker容器的文件系统分层机制主要靠联合文件系统(UnionFS)来实现。联合文件系统保证了文件的堆叠特性,即上层通过增加文件来修改依赖层文件,在保证镜像的只读特性时还能实现容器文件的读写特性。

1.3  Docker镜像的仓库存储结构

Docker 容器镜像的存储分为本地存储和镜像仓库(Registry)存储。其中,本地存储指镜像下载到本地后是如何在本地文件系统中存储的;镜像仓库存储指镜像以什么方式存储在远端的镜像仓库中。

镜像存储的本质还是分层存储,但是本地存储和镜像仓库存储的方式不完全一样,最大的区别是,镜像仓库存储的核心是方便镜像快速上传和拉取,所以镜像存储使用了压缩格式,并且按照镜像层独立压缩和存储,然后使用镜像清单(manifest)包含所有的层,通过镜像摘要(digest)和Tag关联起来;镜像在本地存储的核心是快速加载和启动容器,镜像层存储是非压缩的(即源文件)。另外,容器在启动时需要将镜像层按照顺序堆叠作为容器的运行环境,所以镜像在本地存储中需要使用非压缩形式存放。(本文来自公众号:亨利笔记)

在说明镜像的存储格式之前,先介绍拉取同一个 Docker 镜像时可使用的两种不同命令格式。如下所示,latest 是镜像的 Tag,“sha256:46d659…a3ee9a”是镜像的摘要,在支持 Docker 镜像规范 v2 Schema 2 的镜像仓库中,二者都标识同一个镜像:

$ docker pull debian:latest

$ docker pull \ debian:@sha256:46d659005ca1151087efa997f1039ae45a7bf7a2cbbe2d17d3dcbda632a3ee9a

在镜像仓库上存储容器镜像的简化结构如下图所示,主要由三部分组成:清单文件(manifest)、镜像配置(configuration)和层文件(layers)。上面命令中的镜像摘要就是依据镜像清单文件内容计算 SHA256 哈希值而来的,在镜像清单文件中存放了配置文件的摘要和层文件的摘要,这些摘要都是通过具体的文件内容计算而来的,所以镜像存储也叫作内容寻址。

这样做的好处是,除了可以唯一标识不同的文件,还可以在传输过程中通过摘要做文件校验。在文件下载完成后,计算所下载文件的摘要值,然后与下载时的摘要标识进行对比,如果二者一致,即可判断下载的文件是正确的。需要指出的是,由于文件在镜像仓库端是以压缩形式存放的,所以摘要值也是基于压缩文件计算而来的。

最后简单说明镜像的 Tag 的作用。镜像的 Tag 主要用于对镜像赋予一定的标记,格式是 “<repository>:<Tag>”,可以标识镜像的版本或其他信息,也可以标识一个镜像,如 ubuntu:20.0、centos:latest 等。(本文来自公众号:亨利笔记)

Tag 在镜像仓库中可与镜像清单或者镜像索引关联,多个 Tag 可以对应同一个镜像清单或镜像索引,由镜像仓库维护着它们的映射关系,可参考上图(图中未包含镜像索引)。当客户端拉取镜像时,既可用 Tag,也可用镜像摘要获取同样的镜像。

1.4  Docker镜像的本地存储结构

Docker客户端从镜像仓库拉取一个镜像并存储到本地文件系统的过程大约如下。

(1)向镜像仓库请求镜像的清单文件。

(2)获取镜像ID,查看镜像ID是否在本地存在。

(3)若不存在,则下载配置文件 config,在 config 文件中含有每个层文件未压缩的文件摘要DIFF_ID。

(4)检查层文件是否在本地存在,若不存在,则从镜像仓库中拉取每一层的压缩文件。

(5)拉取时,使用镜像清单中压缩层文件的摘要作为内容寻址下载。

(6)下载完一层的文件后,解压并按照摘要校验。

(7)当所有层文件都拉取完毕时,镜像就下载完成了。

下载镜像后,在本地查看镜像 debian:latest 的信息,结果如下:

$ docker images debian:latest

REPOSITORY        TAG          IMAGE ID          CREATED          SIZE

debian            latest      1b686a95ddbf     2 weeks ago        114MB

在 IMAGE ID(镜像ID)列显示的 1b686a95ddbf 是本地镜像的唯一标识ID,可以在“Docker”命令中使用。这个 ID 和镜像仓库中镜像摘要(sha256:46d659…a3ee9a)的形式类似,但是数值不一样,这是因为该ID是镜像配置文件的摘要,所以和镜像仓库使用的清单文件摘要不同。(本文来自公众号:亨利笔记)

使用配置文件的摘要作为本地镜像的标识,主要是因为本地镜像存放的文件都是非压缩的文件,而镜像仓库存放的是压缩文件,因此层文件在本地和镜像仓库中有不同的摘要值。因为压缩文件的内容会受到压缩算法等因素的影响,所以同样内容的层无法保证压缩后摘要的唯一性,而镜像清单文件包含压缩层文件的摘要(参考上文示例),因此通过镜像清单文件的摘要(即镜像摘要)无法确定镜像的唯一性。配置文件则不同,其中包含的层信息是未压缩的摘要值,因此相同镜像的各层内容必然相同,配置文件的摘要值是唯一确定的。

(未完待续,欢迎点“再看”或转发、分享、收藏)

《Harbor权威指南》目前当当网低于半价优惠中,点击上图直接购买。

要想了解云原生、区块链和人工智能等技术原理,请立即长按以下二维码,关注本公众号亨利笔记 ( henglibiji ),以免错过更新。

这篇关于云原生制品那些事(1):容器镜像的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/593091

相关文章

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么? K8s的架构原理  控制平面(Control plane)         kube-apiserver         etcd         kube-scheduler         kube-controller-manager         cloud-controlle

【Kubernetes】K8s 的安全框架和用户认证

K8s 的安全框架和用户认证 1.Kubernetes 的安全框架1.1 认证:Authentication1.2 鉴权:Authorization1.3 准入控制:Admission Control 2.Kubernetes 的用户认证2.1 Kubernetes 的用户认证方式2.2 配置 Kubernetes 集群使用密码认证 Kubernetes 作为一个分布式的虚拟

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节,Flexus X实例的促销力度非常大,特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求,一定不要错过这个机会。赶紧去看看吧! 什么是华为云Flexus X实例 华为云Flexus X实例云服务是新一代开箱即用、体

云原生之高性能web服务器学习(持续更新中)

高性能web服务器 1 Web服务器的基础介绍1.1 Web服务介绍1.1.1 Apache介绍1.1.2 Nginx-高性能的 Web 服务端 2 Nginx架构与安装2.1 Nginx概述2.1.1 Nginx 功能介绍2.1.2 基础特性2.1.3 Web 服务相关的功能 2.2 Nginx 架构和进程2.2.1 架构2.2.2 Ngnix进程结构 2.3 Nginx 模块介绍2.4

用Cri-O,Sealos CLI,Kubeadm方式部署K8s高可用集群

3.6 Cri-O方式部署K8s集群 注意:基于Kubernetes基础环境 3.6.1 所有节点安装配置cri-o [root@k8s-all ~]# VERSION=1.28[root@k8s-all ~]# curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable.repo https://download.opensu

OpenStack镜像制作系列5—Linux镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录 CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作

OpenStack镜像制作系列4—Windows Server2019镜像

本系列文章主要对如何制作OpenStack镜像的过程进行描述记录  CSDN:OpenStack镜像制作教程指导(全) OpenStack镜像制作系列1—环境准备 OpenStack镜像制作系列2—Windows7镜像 OpenStack镜像制作系列3—Windows10镜像 OpenStack镜像制作系列4—Windows Server2019镜像 OpenStack镜像制作系