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-Type
The default value is to application/x-tar
indicate that you are an archive.
X-Registry-Config
This 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:
t
This 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.
memory
cpusetcpus
These are primarily used for resource constraints
buildargs
If 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