When I first used Docker, everyone was talking about how easy it was to use, how good its internal mechanism was and how much time it saved us. But as soon as I used it, I found that almost all the pictures were bloated and unsafe (without using package signature, I blindly believed that the upstream picture library was
| sh & lt/code & gt; Moreover, no image can achieve the original intention of Docker: isolation, single process, easy distribution and simplicity.
Docker image was not originally designed to replace complex virtual machines. It has a complete log, monitoring, alarm and resource management module. Docker, on the other hand, tends to take advantage of the kernel's
In a physical machine environment, once the kernel is initialized,
That's why when you're in Dockerfile
Now please check your process list and use the
How to start?
Nowadays, most applications are large and complex systems, which usually require many dependent libraries, such as scheduling, compilation and many other related tool applications. Their architectures are usually well encapsulated, and the underlying details are hidden in abstract layers and interfaces. To some extent, this is also a container, but from the perspective of system architecture, we need a simpler solution than the previous virtual environment.
Take Java for example.
From the beginning, think about the basic container that you want to build. Think about your application itself. What does it need to run?
There are many possibilities. If you want to run a Java application, it needs a Java runtime. If you run a Rails application, it needs a Ruby interpreter, and so does a Python application. Go is a little different from some other compilation languages, which I will mention below.
In the Java example, the next step is to consider: What dependencies does JRE need to run? Because it is the most important component to make the application run, the natural next step is to figure out what JRE depends on.
In fact, JRE does not have much dependence. It was originally an abstract layer of the operating system, which made the code run independently of the host system, so it was basically ready when JRE was installed.
(In fact, the independence of the operating system is not taken for granted. There are many system-specific APIs and proprietary system extensions, but for the sake of example, we will focus on simple cases. )
On Linux, the JVM mainly calls the C language library of the system, and the official JRE of Oracle uses libc, which means that if you want to run any Java program, you need to install glibc first. In addition, you may need some kind of shell to manage the environment and have an interface to communicate with the outside world, such as the interface between the network and resources.
Let's summarize the minimum configuration required for the Java application sample:
In the example, we use Oracle JRE.
Glibc, JRE dependency
Basic environment (including network, memory, file system and other resource management tools)
# Into the Alps Linux ##
Alpine Linux has received a lot of attention recently, mainly because it encapsulates a series of verified trusted dependencies and still maintains a size of 2MB! At the time of publication, other mirror distributions are as follows:
Ubuntu: Latest: 66MB (much thinner, some previous versions exceeded 600MB)
Debian: Latest: 55MB (same as above, it was more than 200 MB at first).
Arch: latest: 145MB
Busybox: Latest: 676KB (Yes! KB, I'll discuss it later)
Alpine: Latest: 2MB (2MB, Linux system with package management tool)
** Busybox is the smallest competitor? **
From the above comparison, we can see that the only thing that can beat Alpine Linux in size is Busybox, so almost all embedded systems are using it now, and it is applied to routers, switches, ATMs, or your toaster. As the most basic environment, it provides an easy-to-maintain shell interface.
There are many articles on the Internet explaining why people choose Alpine Linux instead of Busybox. Let me summarize here:
An Open and Active Software Package Warehouse: Alpine
Linux uses the apk package management tool and integrates it into the Docker image, while Busybox needs to install another package manager, such as opkg. More importantly, you need to find a stable source of storage (there is almost no such source). Alpine's package warehouse provides a large number of commonly used dependency packages. For example, if you still need to compile code such as nodejs or ruby in the container, you can directly run apk to add NodeJS and Ruby.
Volume is really important, but when you measure it between functionality, flexibility, ease of use and 1.5MB, volume is not so important. The package added on Alpine greatly enhances these aspects.
Extensive support: Docker has hired the author of Alpine Linux for maintenance, and all official images in the future will be built based on Alpine Linux. There is no more compelling reason for you to use it in your own container.
Yun Xi cSphere realized the increasingly serious problem of mirroring very early, so it launched micro-mirroring last year, which is also to guide you how to better build and understand mirroring. Mirroring is just a software package format.
* * Building a Java-based environment image * *
As I just explained, Alpine Linux is a good choice when building your own image, so we will use it here to build a simple and efficient Docker image. Let's get started!
Combination: Alps +bash
The first instruction of each Dockerfile is to specify its parent container, which is usually used for inheritance in our example.
hush
From the Alps: the latest
Defender docker@csphere.cn
We also declare who is responsible for the image, and this information is necessary for the image uploaded to Docker Hub.
In this way, your next operation will have a foundation. Next, install the shell of our choice and add the following command:
hush
Run apkadd-no-cache-update-cachebash.
CMD ["/bin/bash"]
The final docker file is as follows:
`` shh!
From the Alps: the latest
Maintainer CSP Here & ltdocker@csphere.cn >
Run apkadd-no-cache-update-cachebash.
CMD ["/bin/bash"]
```
Ok, now let's build the container:
hush
$ docker build-t my-Java-base-image。
Send build context to Docker daemon 2.048kb.
Step 1: From Alps: Latest
-& gt; 23 14ad3eeb90
Step 2: Maintainer CSP HERE docker@csphere.cn
-& gt; Run in 634333 12d77e.
-& gt; bfe947 13797a
Disassemble the intermediate container 634333 12d77e.
... omit a few lines
Step 4: CMD /bin/bash
-& gt; Run in d229 1684b797.
-& gt; ecc443d68f27
Disassemble the intermediate container d229 1684b797.
Ecc443d68f27 was successfully built.
And run it:
hush
$ docker run-RM-ti my-Java-base-image
bash-4.3#