在devops流程里面 构建镜像是一个非常重要的过程,一般构建镜像是写dockerfile文件然后通过docker client来构建的image。

docker client 会先检查本地有没有image,如果没有帮你 从镜像仓库 pull 下来

然后解析你写的dockerfile构建新的image。

本文带你了解

  • pull 命令 背后是怎么做的?
  • build 命令 背后是怎么做的?

下篇文章带你解析:

  • 如果我不用docker 我如何构建一个镜像?

我们以微软的aspnet2.2为基础构建一个aspnetcore项目的镜像为例子

mcr.microsoft.com/dotnet/core/aspnet:2.2

根据基础镜像REGISTRY去获取mainfest信息

https://mcr.microsoft.com/v2/dotnet/core/aspnet/manifests/2.2
Accept:
application/vnd.oci.image.manifest.v1+json,application/vnd.docker.distribution.manifest.v2+json,application/vnd.docker.distribution.manifest.v1+json

获取到的内容如下:

{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 4039,
"digest": "sha256:e7e3b238011ce0f2b9350153535fe273caa01f0e7188d0b91f965b3802ddc600"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 22524609,
"digest": "sha256:804555ee037604c40de144f9f8da0d826d38db82f15d74cded32790fe279a8f6"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 17692725,
"digest": "sha256:970251047358aea56ba6db6975b14ff12470b75de0c2477f4445240ddd727fd4"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 2978257,
"digest": "sha256:f3d4c41a4fd13f35c0b46f19a4e27845f4695163cc7174d908ff84836bbc2f5a"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 62145592,
"digest": "sha256:bd391c46585f9f8d84992bbaa9087189148c1601968eaaf097d5b3ed60840e5e"
}
]
}

mainfest文件里面都是摘要(digest)记录

  • config信息摘要
  • 每个layer的摘要 (上面的例子有4个)

根据上面的config信息摘要获取config详情

GET:https://mcr.microsoft.com/v2/dotnet/core/aspnet/blobs/sha256:e7e3b238011ce0f2b9350153535fe273caa01f0e7188d0b91f965b3802ddc600

{
"architecture": "amd64",
"config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"ASPNETCORE_URLS=http://+:80",
"DOTNET_RUNNING_IN_CONTAINER=true",
"ASPNETCORE_VERSION=2.2.8"
],
"Cmd": [
"bash"
],
"ArgsEscaped": true,
"Image": "sha256:5ecfe4016ac8e911a94aa601a675f7204e9ccab00cbb08e7067c184ad40f34e9",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"container": "14196c2f9c327d41e26682d32c7c89c4e7c78aa32f8b7501a23192035a9f4844",
"container_config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"ASPNETCORE_URLS=http://+:80",
"DOTNET_RUNNING_IN_CONTAINER=true",
"ASPNETCORE_VERSION=2.2.8"
],
"Cmd": [
"/bin/sh",
"-c",
"curl -SL --output aspnetcore.tar.gz https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$ASPNETCORE_VERSION/aspnetcore-runtime-$ASPNETCORE_VERSION-linux-x64.tar.gz && aspnetcore_sha512='954072376698be69acb7e277df2c243f931e10529def21dcbf9ce277609b30d462126bf8b8b3cab36476bec3d63a927b8e44e59e4d4cade23eef45956fba1ffd' && echo \"$aspnetcore_sha512 aspnetcore.tar.gz\" | sha512sum -c - && mkdir -p /usr/share/dotnet && tar -zxf aspnetcore.tar.gz -C /usr/share/dotnet && rm aspnetcore.tar.gz && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet"
],
"Image": "sha256:5ecfe4016ac8e911a94aa601a675f7204e9ccab00cbb08e7067c184ad40f34e9",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"created": "2019-12-28T08:12:05.676492579Z",
"docker_version": "3.0.8",
"history": [
{
"created": "2019-12-28T04:23:47.4966447Z",
"created_by": "/bin/sh -c #(nop) ADD file:90a2c81769a336bed3f731f44a385f2a65b0916f517a0b77c06c224579bf9a9a in / "
},
{
"created": "2019-12-28T04:23:47.719507596Z",
"created_by": "/bin/sh -c #(nop) CMD [\"bash\"]",
"empty_layer": true
},
{
"created": "2019-12-28T08:11:05.607009582Z",
"created_by": "/bin/sh -c apt-get update && apt-get install -y --no-install-recommends ca-certificates libc6 libgcc1 libgssapi-krb5-2 libicu57 liblttng-ust0 libssl1.0.2 libstdc++6 zlib1g && rm -rf /var/lib/apt/lists/*"
},
{
"created": "2019-12-28T08:11:07.64336022Z",
"created_by": "/bin/sh -c #(nop) ENV ASPNETCORE_URLS=http://+:80 DOTNET_RUNNING_IN_CONTAINER=true",
"empty_layer": true
},
{
"created": "2019-12-28T08:11:16.475068844Z",
"created_by": "/bin/sh -c apt-get update && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*"
},
{
"created": "2019-12-28T08:11:43.814078508Z",
"created_by": "/bin/sh -c #(nop) ENV ASPNETCORE_VERSION=2.2.8",
"empty_layer": true
},
{
"created": "2019-12-28T08:12:05.676492579Z",
"created_by": "/bin/sh -c curl -SL --output aspnetcore.tar.gz https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/$ASPNETCORE_VERSION/aspnetcore-runtime-$ASPNETCORE_VERSION-linux-x64.tar.gz && aspnetcore_sha512='954072376698be69acb7e277df2c243f931e10529def21dcbf9ce277609b30d462126bf8b8b3cab36476bec3d63a927b8e44e59e4d4cade23eef45956fba1ffd' && echo \"$aspnetcore_sha512 aspnetcore.tar.gz\" | sha512sum -c - && mkdir -p /usr/share/dotnet && tar -zxf aspnetcore.tar.gz -C /usr/share/dotnet && rm aspnetcore.tar.gz && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet"
}
],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": [
"sha256:814c70fdae62bc26c603bfae861f00fb1c77fc0b1ee8d565717846f4df24ae5d",
"sha256:0cf75cb98eb2e0a82631d4aff71b40ba79ff7f83e0361f696875e592a1a4cefc",
"sha256:15e45d99c92686fb1fd61a41431d8400d7a0e8381595d09d666b0809c4f5d993",
"sha256:579a8f1d6a123f98095c0b1a1395079f7504391fd2a8bc529dede305a2072a36"
]
}
}

根据diff_ids里面去下载对应layers

下载完后对比摘要一致,确保镜像文件合法性

路径规则:

https://mcr.microsoft.com/v2/dotnet/core/aspnet/blobs/sha256:XXXXXX

构建我们的镜像

在基础镜像的配置基础上加入我们的自定义配置

  • Entrypoint
  • Cmd
  • Ports
  • Environment
  • ImageWorkingDirectory
  • Volumes
  • Labels

在基础镜像的所有的layers把我们要打包到镜像也做成一个layer

生成的镜像tar包解压出来

多了一个 tar.gz文件,解压之后 就是我们打包放进去的文件

  • 原来基础镜像有4个layer 加上我们的 共5个
  • config.json
  • manifest.json
manifest.json对比与基础镜像

config.json对比与基础镜像

我们来复习下构建镜像的过程

    1. 根据镜像名称拉取mainfest
    1. 根据mainfest拉取config
    1. 根据config拉取layers
    1. 下载各个layer
    1. 修改到基础镜像的配置(config.json和mainfest.json)
    1. 加入我们要加入的文件layer

知道原理后我们可以自己写一个工具来实现整个过程

我开源的docker镜像构建,让你不用装docker也能快速构建容器镜像

支持以下镜像仓库作为基础镜像构建

  • docker hub
  • aliyun
  • 腾讯云

Docker镜像构建原理解析(不装docker也能构建镜像)的更多相关文章

  1. [原][Docker]特性与原理解析

    Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...

  2. Docker网络管理机制实例解析+创建自己Docker网络

    实例解析Docker网络管理机制(bridge network,overlay network),介绍Docker默认的网络方式,并创建自己的网络桥接方式,将开发的容器添加至自己新建的网络,提高Doc ...

  3. 一篇不一样的docker原理解析

    转自:https://zhuanlan.zhihu.com/p/22382728 https://zhuanlan.zhihu.com/p/22403015 在学习docker的过程中,我发现目前do ...

  4. 8天入门docker系列 —— 第三天 使用aspnetcore小案例熟悉对镜像的操控

    上一篇我们聊到了容器,现在大家应该也知道了,没有镜像就没有容器,所以镜像对docker来说是非常重要的,关于镜像的特性和原理作为入门系列就不阐 述了,我还是通过aspnetcore的小sample去熟 ...

  5. Docker 基本核心原理

    Docker内核知识 namespace资源隔离 namespace的6项隔离 NameSpace 系统调用参数 隔离内容 UTS CLONE_NEWUTS 主机名与域名 IPC CLONE_NEWI ...

  6. Docker学习笔记之Docker的Build 原理

    0x00 概述 使用 Docker 时,最常用的命令无非是 docker container 和 docker image 相关的子命令,当然最初没有管理类命令(或者说分组)的时候,最常使用的命令也无 ...

  7. 操作系统-容器-Docker:如何将应用打包成为 Docker 镜像?

    ylbtech-操作系统-容器-Docker:如何将应用打包成为 Docker 镜像? 1.返回顶部 1. 虽然 DockerHub 提供了大量的镜像,但是由于企业环境的多样性,并不是每个应用都能在 ...

  8. Docker容器的原理与实践(上)

    本文来自网易云社区. 虚拟化 是一种资源管理技术,将计算机的各种资源予以抽象.转换后呈现出来, 打破实体结构间的不可切割的障碍,使用户可以比原本更好的方式来应用这些资源. Hypervisor 一种运 ...

  9. Docker容器的原理与实践 (下)

    欢迎访问网易云社区,了解更多网易技术产品运营经验. Docker原理分析 Docker架构 镜像原理 镜像是一个只读的容器模板,含有启动docker容器所需的文件系统结构及内容Docker以镜像和在镜 ...

随机推荐

  1. hdu5726 GCD(gcd +二分+rmq)

    Problem Description Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). ...

  2. 2020牛客暑期多校训练营(第二场) Boundary

    传送门:Boundary  题意:给你n个点的坐标,问最多有多少个点可以在同一个圆上,(0,0)必须在这个圆上. 题解:三个点确定一个圆,所以暴力枚举两个点和(0,0)组成的圆,如果三个点不共线的话, ...

  3. 【bzoj 2339】[HNOI2011]卡农(数论--排列组合+逆元+递推)

    题意:从编号为 1~N 的音阶中可选任意个数组成一个音乐片段,再集合组成音乐篇章.要求一个音乐篇章中的片段不可重复,都不为空,且出现的音符的次数都是偶数个.问组成 M 个片段的音乐篇章有多少种.答案取 ...

  4. 7.PowerShell DSC之模式

    DSC两种模式 DSC有两种模式,Push模式和Pull模式 Push模式 基本流程 写配置--编译生成mof--推送到目标服务器,由目标服务器LCM执行mof并进行指定的配置 优点 架构简单.成本低 ...

  5. 自动化将 word 转为 pdf,再将pdf转为图片!

    参考: https://blog.csdn.net/ynyn2013/article/details/49120731 https://www.jianshu.com/p/f57cc64b9f5e 一 ...

  6. java 提供了哪些IO方式

    今天听了杨晓峰老师的java 36讲,感觉IO这块是特别欠缺的,所以讲义摘录如下: 欢迎大家去订阅: 本文章转自:https://time.geekbang.org/column/article/83 ...

  7. vue中子组件更新父组件

    当在子组件里更改了某些信息且关闭子组件后,需要父组件更新修改后的内容,该如何操作 1.$emit触发 父组件 @add="add(val)" 子组件 this.$emit('add ...

  8. Linux的进程权限控制

    Linux系统的安全性得益于其进程权限和文件权限的控制机制.今天抽空梳理下Linux下的进程权限控制相关的文件权限涉及一点.首先明确四个名词:真实用户ID(real ID).有效用户ID(effect ...

  9. 018-019 NET5_内置容器支持依赖注入+IServiceCollection的生命周期

    概念: DI依赖注入: IServiceCollection仅支持构造函数注入 什么是依赖注入? 如果对象A依赖对象B,对象B依赖对象C,就可以先构造对象C,然后传递给对象B,再把对象B传递给A.得到 ...

  10. Shell 编程快速上手

    Shell 编程快速上手 test.sh #!/bin/sh cd ~ mkdir shell_tut cd shell_tut for ((i=0; i<10; i++)); do touch ...