The Build principle of Docker's in-depth article

Source: Internet
Author: User
Tags base64 docker ps docker run

When using Docker, the most commonly used commands are nothing more than the docker container docker image associated subcommands, and of course, when there is no management class command (or grouping), the most frequently used commands are nothing more than docker run docker commit docker build docker images these.

Today, let's talk about important commands related to the core concepts in Docker, image docker build or docker image build , for simplicity's sake, use all of the commands below docker build .

Docker Image

Let's start with a brief introduction to the Docker image, which we typically call mirroring, which is a file of multiple layers used to execute code (commands) inside a container. Each image is basically built from the full executable version of the application, and it is important to note that it relies on the host's system kernel. This creates one or more container instances when the user is running the image.

Dockerd

Dockerd is the service side of Docker, which provides Unix Domain sockets by default and, of course, listens to a port for external service. So sometimes we can also use the Docker daemon on the server to provide services to speed up construction and solve some network problems.

OK, the basic concept is understood, then we start to get to the point.

Using Dockerfile

We know that there are several ways to build images, and in this article we only describe docker build how to build mirrors using Dockerfile.

For simplicity, let's start with a simple Dockerfile. Build a KUBECTL tool for use within a container (of course, the reason for choosing it is that kubectl is large enough and does not consider usability , which is explained later)

FROM scratchLABEL maintainer='Jintao Zhang <moelove.info>'ADD kubectl /kubectlENTRYPOINT [ "/kubectl" ]

The Dockerfile is simple enough to simply copy the Kubectl binaries and set the entrypoint to Kubectl.

Dockerd in Docker

I personally generally in order to avoid environmental pollution, most of the things are done in the container. Including the Dockerd I also set the container inside. The principle is no longer introduced, you can refer to my previous article or share. It's easy to use:

docker run --privileged -d -P docker:stable-dind

Note that this is used here -P so the local will randomly map a port, and of course you can directly specify the map to the 2375 port within the container.

(Tao) ➜  build git:(master) docker ps                                                       CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS                     NAMESb56f6483614d        docker:stable-dind          "dockerd-entrypoint.…"   9 hours ago         Up 9 hours          0.0.0.0:32769->2375/tcp   trusting_babbage

Build

We built it directly using the dockerd that started in the container, and by the above docker ps command we could see that it was mapped to a local 32769 port. So we use the following command to build:

(Tao) ➜kubectl git: (master) docker-h 0.0.0.0:32769 Images                                      REPOSITORY TAG IMAGE ID CREATED SIZE                                            (Tao) ➜kubectl git: (master) docker-h 0.0.0.0:32769 build-t local/kubectl. Sending build context to Docker daemon 55.09MBStep: From scratch--->step 2/4: LABEL maintainer= ' Jintao Zhang & Lt;moelove.info> '---> Running in ebcf44071bf0removing Intermediate container ebcf44071bf0---> Eb4ea1725ff2step 3/4: ADD kubectl/kubectl---> 1aad06c4dbb4step 4/4: entrypoint ["/KUBECTL"]---> Running in 2f C78fe974e3removing Intermediate container 2fc78fe974e3---> 457802d4bf3esuccessfully built                  457802d4bf3esuccessfully tagged local/kubectl:latest (Tao) ➜kubectl git: (master) docker-h 0.0.0.0:32769 Images REPOSITORY TAG IMAGE ID CREated Sizelocal/kubectl latest 457802d4bf3e 3 seconds ago 55.1MB 

Looking at the logs and the results, we can see that we have successfully built the image we need. Having said so much, the content of our today is only just beginning.

In-depth principle

Dockerd Service

At the beginning of this article, I have mentioned that Dockerd is the backend service of Docker, through the above

docker -H 0.0.0.0:32769 images                                                              

This command can be seen by -H specifying the local 32679 port of the Dockerd service, which is actually an HTTP service, which we have to verify.

(Tao) ➜  kubectl git:(master) curl -i   0.0.0.0:32769/_pingHTTP/1.1 200 OKApi-Version: 1.37Docker-Experimental: falseOstype: linuxServer: Docker/18.03.1-ce (linux)Date: Tue, 04 Sep 2018 17:20:51 GMTContent-Length: 2Content-Type: text/plain; charset=utf-8OK%                  

You can see a few key information api-version:1.37 This shows the current API version, the content of this article is described in 1.37 as an example, this is the current stable version. We can also docker version check it out.

(Tao) ➜  kubectl git:(master) docker -H 0.0.0.0:32769 version                                                             Client: Version:           18.06.0-ce API version:       1.37 (downgraded from 1.38) Go version:        go1.10.3 Git commit:        0ffa825 Built:             Wed Jul 18 19:11:45 2018 OS/Arch:           linux/amd64 Experimental:      falseServer: Engine:  Version:          18.03.1-ce  API version:      1.37 (minimum version 1.12)  Go version:       go1.9.5  Git commit:       9ee9f40  Built:            Thu Apr 26 07:23:03 2018  OS/Arch:          linux/amd64  Experimental:     false

You can see that I have a high version of the Docker CLI in use locally, and when connecting to the lower version of Dockerd, the API version is downgraded to the same version as the Dockerd.

Of course, you might ask, what if the Dockerd version is high? In fact, my daily development environment is like this, most of the API has no impact, but this is not the focus of today.

root@bdcdac73ee20:/# docker versionClient: Version:      17.06.0-ce API version:  1.30 Go version:   go1.8.3 Git commit:   02c1d87 Built:        Fri Jun 23 21:15:15 2017 OS/Arch:      linux/amd64Server: Version:      dev API version:  1.39 (minimum version 1.12) Go version:   go1.10.3 Git commit:   e8cc5a0b3 Built:        Tue Sep  4 10:00:36 2018 OS/Arch:      linux/amd64 Experimental: false

Build context

Back to the build process above us. We can see the first line of the log content:

...Sending build context to Docker daemon  55.09MB

From this log, we can get two messages:

    • The build process sends the build context to dockerd, and the actual build pressure is on the Dockerd
    • Sent a 55.09 MB

The first conclusion, which we have already discussed in the previous section, is to focus on the second conclusion.

(Tao) ➜  kubectl git:(master) ls -al 总用量 53808drwxrwxr-x. 2 tao tao     4096 9月   5 01:00 .drwxrwxr-x. 3 tao tao     4096 9月   5 00:57 ..-rw-rw-r--. 1 tao tao      109 9月   5 01:00 Dockerfile-rwxrwxr-x. 1 tao tao 55084063 9月   5 00:53 kubectl(Tao) ➜  kubectl git:(master) du -sh .53M     .(Tao) ➜  kubectl git:(master) du -sh kubectl Dockerfile 53M     kubectl4.0K    Dockerfile

According to our Dockerfile, we need to put the Kubectl binary package into the mirror, so the build context, although more than 2M of the size of the binary file you will not be very surprised.

But I've done another example here, and not much to repeat, the code can be found in my [GitHub] (). Posted here Results:

(Tao) ➜  text git:(master) ls -al                                                                                          总用量 16                                                                                                                  drwxrwxr-x. 2 tao tao 4096 9月   5 01:45 .                                                                                drwxrwxr-x. 4 tao tao 4096 9月   5 01:44 ..                             -rw-rw-r--. 1 tao tao   77 9月   5 01:45 Dockerfile                       -rw-rw-r--. 1 tao tao   61 9月   5 01:45 file  (Tao) ➜  text git:(master) du -b Dockerfile file77      Dockerfile61      file                                                                                                              (Tao) ➜  text git:(master) docker -H 0.0.0.0:32769 build --no-cache=true -t local/file .                                  Sending build context to Docker daemon  3.072kB...

I believe you see this result already understand I want to express the meaning, we continue to explore the next process.

/build Request

As we've said earlier, this is a normal HTTP request, so we can certainly grab the bag and see what's going on.

Very simply, through the Dockerd address, the use of POST methods, Access /build interface, of course, the actual situation is to increase the prefix, that is, I mentioned in the above version number, in the current environment is used in /v1.37/build this interface.

And this request carries some very useful parameters, and the header information. Here I will briefly say:

Header

Build request header, mainly has the following two

    • Content-TypeThe default value is to application/x-tar indicate that you are an archive.
    • X-Registry-ConfigThis header information contains the address and authentication information of the registry, and is encoded in base64. Friends who are familiar with Docker or who have read my previous article should know that the Docker CLI will save the authentication information to the local after login succeeds, and the password does base64. The build will then encode the information again base64. As can be seen here, when using remote Dockerd, you should try to configure TLS to prevent man-in-the-middle attacks, resulting in password leaks and so on.

Parameters

In the request parameter, there are several more meaningful columns:

    • tThis is actually docker build -t the parameter we specify at the time, and we can specify multiple -t mirrors that simultaneously build multiple different names at the same time.
    • memorycpusetcpusThese are primarily used for resource constraints
    • buildargsIf you want to understand this parameter, you can recall the use of the instructions in the Dockerfile ARG

Of course, the process we want to explore actually focuses on the request header, the entire requested input stream, must be a tar compressed package, and support identity (not compressed),, gzip , and bzip2 xz so on compression algorithm.

Realize

Let's take a look at the basic implementation:

func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {    query, err := cli.imageBuildOptionsToQuery(options)    if err != nil {        return types.ImageBuildResponse{}, err    }    headers := http.Header(make(map[string][]string))    buf, err := json.Marshal(options.AuthConfigs)    if err != nil {        return types.ImageBuildResponse{}, err    }    headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf))    headers.Set("Content-Type", "application/x-tar")    serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers)    if err != nil {        return types.ImageBuildResponse{}, err    }    osType := getDockerOS(serverResp.header.Get("Server"))    return types.ImageBuildResponse{        Body:   serverResp.body,        OSType: osType,    }, nil}

Summarize

This article focuses on the process of Docker build and its rationale, why write this first, mainly because the mirror is closely related to us, and is the first step we use. In many cases, the promotion of business containerized is also faced with performance optimization and other specifications.

In fact there is a lot of details about build, if available, I will update the next article.

The following QR code can be used to subscribe to my article "Moelove" of the public number

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.