Analysis of the Docker image construction principle (you can build an image without installing Docker)

Analysis of the Docker image construction principle (you can build an image without installing Docker)

Building an image is a very important process in the devops process. Generally, building an image means writing a dockerfile file and then building the image through the docker client.

The docker client will first check if there is an image locally, and if not, it will pull it from the image repository for you.

Then parse the Dockerfile you wrote to build a new image.

This article will help you understand

  • What does the pull command do behind the scenes?
  • What does the build command do behind the scenes?

The next article will explain:

How do I build an image if I don't use Docker?

We take Microsoft's aspnet2.2 as the basis to build an image of the aspnetcore project as an example

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

Get mainfest information according to the base image REGISTRY

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

The obtained content is as follows:

{
  "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"
    }
  ]
}

The mainfest file contains digest records

  • config information summary
  • A summary of each layer (4 in the example above)

Get config details based on the above config information summary

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"
    ]
  }
}

Download the corresponding layers according to diff_ids

After downloading, compare the summary to ensure the legitimacy of the image file.

Path rules:

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

Building our image

Add our custom configuration based on the configuration of the base image

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

In all the layers of the base image, we also make a layer to package the image

Unzip the generated image tarball

There is an extra tar.gz file. After decompression, it contains the files we packed in.

  • The original base image has 4 layers, plus ours, a total of 5
  • config.json
  • manifest.json

config.json comparison with base image

Let's review the process of building an image and pull the mainfest according to the image name.

  • Pull config according to mainfest
  • Pull layers according to config
  • Download each layer
  • Modify the configuration of the base image (config.json and mainfest.json)
  • Add the file layer we want to add

After knowing the principle, we can write a tool to implement the whole process

My open source docker image build allows you to quickly build container images without installing docker

Support the following image repositories as basic image building

  • docker hub
  • aliyun
  • Tencent Cloud

This concludes this article on the analysis of the principles of Docker image building (you can build images without installing Docker). For more information on Docker image building, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed steps for using jib for docker deployment in Spring Cloud
  • Using jib to package docker images
  • Detailed steps for building, running, publishing, and obtaining a Docker image for the first time
  • Analysis of two methods of building Docker images
  • Use GoogleContainerTools to containerize jib to build a docker image

<<:  W3C Tutorial (14): W3C RDF and OWL Activities

>>:  Detailed explanation of how to customize the style of CSS scroll bars

Recommend

Will CSS3 really replace SCSS?

When it comes to styling our web pages, we have t...

Detailed explanation of this reference and custom properties in JavaScript

Table of contents 1. this keyword 2. Custom attri...

js to realize a simple advertising window

This article shares the specific code of js to im...

How to configure path alias for react scaffolding

The react version when writing this article is 16...

MySQL full backup and quick recovery methods

A simple MySQL full backup script that backs up t...

A brief introduction to JavaScript arrays

Table of contents Introduction to Arrays Array li...

Analysis of the ideas of implementing vertical tables in two ways in Vue project

Problem Description In our projects, horizontal t...

MySQL 5.7.15 version installation and configuration method graphic tutorial

This article shares with you a detailed tutorial ...

Dynamically add tables in HTML_PowerNode Java Academy

Without further ado, I will post the code for you...

JavaScript to achieve simple provincial and municipal linkage

This article shares the specific code for JavaScr...

Detailed explanation of Vue life cycle functions

Table of contents Lifecycle Functions Common life...

A brief analysis of event bubbling and event capture in js

Table of contents 01-Event Bubbling 1.1- Introduc...

How to install Mysql5.7 in Centos6

environment Centos 6.6 MySQL 5.7 Install If the s...

Tips on HTML formatting and long files for web design

<br />Related articles: 9 practical suggesti...

MySQL slow query and query reconstruction method record

Preface What is a slow query and how to optimize ...