Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to write elegant Dockerfile

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/02 Report--

Guide reading

Since Kubernetes needs to be portable and containers need to start with Dockerfile, this article shows you how to write an elegant Dockerfile file.

The main contents of the article include:

Docker container

Dockerfile

Use multi-step build

I would like to thank the company for providing a lot of machine resources and time for us to practice, and for the support of some projects and personnel who have been practicing on this topic.

1. The characteristics of Docker containers

We all know that a container is a standard software unit with the following characteristics:

Run anywhere: the container can package code with configuration files and related dependent libraries to ensure that it runs consistently in any environment.

High resource utilization: containers provide process-level isolation, so you can set CPU and memory usage more finely, thus making better use of the server's computing resources.

Rapid expansion: each container can be run as a separate process and can share the system resources of the underlying operating system, thus speeding up the start and stop efficiency of the container.

1.2 Docker Container

At present, the mainstream container engines on the market are Docker, Rocket/rkt, OpenVZ/Odin and so on, while the dominant container engine is the most frequently used Docker container engine.

The Docker container is a series of processes isolated from the rest of the system, all the files needed to run these processes are provided by another image, and the Linux container is portable and consistent throughout the process from development to testing to production. Containers run much faster than development channels that rely on repetitive traditional test environments and support deployment on a variety of mainstream cloud platforms (PaaS) and local systems. The Docker container well solves the embarrassment that "the development environment can run normally and collapse as soon as it is online".

Features of the Docker container:

Lightweight: the container is process-level resource isolation, while the virtual machine is operating system-level resource isolation, so the Docker container can save more resource overhead than the virtual machine, because the Docker container no longer needs the GuestOS operating system.

Fast: container startup and creation do not need to start GuestOS, you can achieve seconds or even millisecond startup.

Portability: Docker container technology is to transform the application and dependent library and runtime environment technology into a container image, which can be run on different platforms.

Automation: container orchestration in the container ecology (such as Kubernetes) can help us automate the management of containers.

II. Dockerfile

Dockerfile is a text document used to describe the composition of the file, which contains all the commands that the user can use line call to combine Image, and the user can also use Docker build to implement the automatic construction of multiple commands referring to the current line.

By writing Dockerfile magnetogenic images, we can provide a basically consistent environment for development and testing teams, so as to improve the efficiency of development and testing teams, so that we no longer have to worry about the disunity of the environment. At the same time, operation and maintenance can also manage our images more easily.

The syntax of Dockerfile is very simple, with only 11 commonly used:

2.1 write elegant Dockerfile

The following are the main points to note when writing an elegant Dockerfile:

Dockerfile files should not be too long, and the more levels you have, the larger the final image will be.

The constructed image should not contain unwanted content, such as logs, installation temporary files, etc.

Use the underlying image of the runtime as much as possible, and there is no need to put the build-time process into the runtime Dockerfile.

You can write a good Dockerfile as long as you remember the above three points.

To make it easier for you to understand, let's make a simple comparison with two Dockerfile instances:

FROM ubuntu:16.04RUN apt-get updateRUN apt-get install-y apt-utils libjpeg-dev\ python-pipRUN pip install-- upgrade pipRUN easy_install-U setuptoolsRUN apt-get cleanFROM ubuntu:16.04RUN apt-get update & & apt-get install-y apt-utils\ libjpeg-dev python-pip\ & & pip install-- upgrade pip\ & & easy_install-U setuptools\ & & apt-get clean

When we look at the first Dockerfile, at first glance, it seems that it is well organized and well-structured. Look at the second Dockerfile, compact, not easy to read, why write like this?

The advantage of the first Dockerfile is that when an error occurs at one of the layers of the process that is being executed, it is corrected and Build again, and the layers that have been executed before will not be executed again. This will greatly reduce the time of the next Build, and its problem is that the mirror will take up more space due to more levels.

The second Dockerfile solves all the components in one layer, which can reduce the space occupied by the image to a certain extent, but when making a basic image, if one of the groups makes a compilation error, Build after correction is tantamount to starting all over again.

You can see the image size compiled by the two Dockerfile from the following table:

$docker images | grep ubuntu REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 16.04 9361ce633ff1 1 days ago 422MBubuntu 16.04-1 3f5b979df1a9 1 days ago 412MB

Uh. . There seems to be no special effect, but if the Dockerfile is very long, you can consider reducing the hierarchy, because the Dockerfile can only have a maximum of 127layers.

Third, use multi-level construction

Docker can support multi-level build after upgrading to Docker 17.05. in order to make the image smaller, we use multi-level build to package the image. Before the emergence of multi-level builds, we usually use one Dockerfile or multiple Dockerfile to build images.

3.1 single file construction

To build with a single file before a multi-staged build comes out, a single file contains all the build processes (including project dependencies, compilation, testing, packaging) under one Dockerfile:

FROM golang:1.11.4-alpine3.8 AS build-envENV GO111MODULE=offENV GO15VENDOREXPERIMENT=1ENV BUILDPATH=github.com/lattecake/helloRUN mkdir-p / go/src/$ {BUILDPATH} COPY. / / go/src/$ {BUILDPATH} RUN cd / go/src/$ {BUILDPATH} & & CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install-vCMD [/ go/bin/hello]

This approach will cause some problems:

The Dockerfile file will be very long, and the maintainability index will decline as more and more things are needed.

If there are too many layers of mirrors, the volume of the images will gradually increase, and the deployment will become slower and slower.

The code is at risk of leakage.

Take Golang as an example, its runtime does not depend on any environment, only needs a compilation environment, then the compilation environment in the actual run time is not a task, after the compilation is completed, the source code and compiler are no longer useful, so there is no need to stay in the image.

As you can see in the table above, single-file builds end up taking up 312MB space.

3.2 Multi-file construction

Is there a good solution before multi-stage construction? Yes, for example, using a multi-file build or installing a compiler on the build server, but installing a compiler on the build server is not recommended, because installing a compiler on the build server will cause the build server to become very bloated. Need to adapt to multiple versions of various languages, dependencies, error-prone, high maintenance costs. So we only introduce how to build multiple files.

To build multiple files is to use multiple Dockerfile and then combine them through scripts. Suppose there are three files: Dockerfile.run, Dockerfile.build, and build.sh.

Dockerfile.run is the Dockerfile of some of the components that a runtime program must require. It contains the most concise libraries.

Dockerfile.build is only used to build, but it is useless after building.

The function of build.sh is to compose Dockerfile.run and Dockerfile.build, take out what Dockerfile.build has built, and then execute Dockerfile.run, which can be regarded as a scheduling role.

Dockerfile.build

FROM golang:1.11.4-alpine3.8 AS build-envENV GO111MODULE=offENV GO15VENDOREXPERIMENT=1ENV BUILDPATH=github.com/lattecake/helloRUN mkdir-p / go/src/$ {BUILDPATH} COPY. / / go/src/$ {BUILDPATH} RUN cd / go/src/$ {BUILDPATH} & & CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install-v

Dockerfile.run

FROM alpine:latestRUN apk-no-cache add ca-certificatesWORKDIR / rootADD hello .CMD [". / hello"]

Build.sh

#! / bin/shdocker build-t-rm hello:build. -f Dockerfile.builddocker create-name extract hello:builddocker cp extract:/go/bin/hello. / hellodocker rm-f extractdocker build-no-cache-t-rm hello:run. -f Dockerfile.runrm-rf. / hello

Execute build.sh to complete the project construction.

As you can see from the table above, the multi-file build greatly reduces the footprint of the image, but it has three files to manage and is more expensive to maintain.

3.3 Multi-stage construction

Finally, let's take a look at the much-anticipated multi-level build.

To complete the multi-phase build, we only need to use the FORM declaration multiple times in Dockerfile. Each FROM instruction can use a different underlying image, and each FROM instruction will start a new build. We can choose to copy the build result of one phase to another, leaving only the result of the last build in the final image, so that the problems mentioned above can be easily solved. And you only need to write a Dockerfile file. It is worth noting here that you need to make sure that the version of Docker is 17.05 or above. Let's talk about the specific operation.

In Dockerfile, you can use as to give a phase an alias "build-env":

FROM golang:1.11.2-alpine3.8 AS build-env

Then copy the file from the image in the previous stage, or you can copy the file in any image:

COPY-from=build-env / go/bin/hello / usr/bin/hello

Look at a simple example:

FROM golang:1.11.4-alpine3.8 AS build-envENV GO111MODULE=offENV GO15VENDOREXPERIMENT=1ENV GITPATH=github.com/lattecake/helloRUN mkdir-p / go/src/$ {GITPATH} COPY. / / go/src/$ {GITPATH} RUN cd / go/src/$ {GITPATH} & & CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go install-vFROM alpine:latestENV apk-no-cache add ca-certificatesCOPY-- from=build-env / go/bin/hello / root/helloWORKDIR / rootCMD ["/ root/hello"]

Execute docker build-t-rm hello3. Then perform docker images, and then let's look at the size of the image:

Multi-level build brings us a lot of convenience, and the biggest advantage is that it reduces the maintenance burden of Dockerfile while ensuring that the running image is small enough, so we highly recommend using multi-level build to package your code into a Docker image.

Author: Wang Cong

Content source: Yixin Institute of Technology

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report