docker image layering

Posted by Madatan on Mon, 31 Jan 2022 19:26:33 +0100

1, Layering of Docker image

(1) Overview

docker image

  • Apply published standard formats
  • Support the operation of a docker container

Creating method of docker image

  • Create based on existing image
  • Create based on local template
  • Create based on Dockerfile

Mirror layering principle

  1. Each instruction in Dockerfile creates a new mirror layer
  2. The mirror layer will be cached and consumed
  3. When the Dockerfile instruction is modified, the copied file changes, or the specified variables for constructing the image are different, the corresponding image layer will become invalid
  4. After the image cache of a certain layer fails, the image cache after it will fail
  5. The mirror layer is immutable. If a file is added in one layer and then deleted in the next layer, the file will still be included in the mirror

Mirror hierarchy

1. (kernel layer): it is composed of AUFS, LXC and Bootfs (boot file system), which provides kernel kernel support for the image of the upper layer

  • AUFS is a federated file system. It uses multiple directories on the same Linux host and stacks them one by one to present a unified file system. AUFS uses this feature to realize the layered idea of Docker image
  • Bootfs: it is responsible for interacting with the kernel, mainly booting and loading the kernel. When linux starts, it will load the bootfs file system. At the bottom of Docker image, bootfs. This layer is the same as the classic Linux/Unix system, including boot loader and kernel. After the boot is loaded, the whole kernel is in memory. At this time, the right to use the memory has been transferred from bootfs to the kernel. At this time, the system will unload bootfs
  • rootfs (root file system) belongs to base images. For example, the linux system contains standard directories and files such as / dev, / proc, / bin, / etc, and some necessary components for creating and starting the operating system. rootfs is the distribution version of different operating systems, such as Ubuntu, CentOS, etc
  • lxc's Early Kernel engine interacted with docker engine, which provided some library files and boot files. Now docker has built-in lib library

2.base image (base / system image layer): build the operating system environment in which the image runs

3.add image (image layer of run instruction): for example, the yum installation module of nginx image, or the instructions compiled and installed by nginx, use the image to encapsulate each run execution command

4.Container (read / write execution layer): provide the following image combination operation to docker client
summary
1. The docker image layer is above the bootfs
2. Each layer of image becomes a base image / base package (operating system environment variable), such as centos dbian
3. Container layer (readable and writable), at the top. It is provided by docker server to docker client
4. All the layers below the container layer are read-only. docker changes the FS layer of readonly to image

The reason why the centos image of docker is only 200M is that a simplified os, rootfs can be very small. Maybe you can just use the basic commands, tools and program libraries, because the underlying layer directly uses the kernel of the host, and you only need to provide rootfs to continue. It can be seen that bootfs are basically the same for different linux discovery versions, and rootfs will be different. Different discovery versions can share bootfs

supplement

Each time the map is sent to the docker hub public warehouse, only the incremental part will be pushed (after all, the base package is relatively large, and the incremental push / update part is relatively small). Therefore, in the production environment, as long as the incremental part is controlled to a relatively small range when the image is pushed again

(2) dockerfile structure

1. Basic image information (specify the image and version of the operating system image)
2. Maintainer information
3. Mirror operation instruction
4. Commands executed when the container is started
dockerfile supports one instruction per line, and each instruction can carry multiple parameters. Comments starting with "#" are supported

(3) dockerfile operation instruction

instructionsmeaning
FROM imageSpecify the operating system image on which the new image is based. The first instruction must be a FROM instruction. Each image creation requires a FROM instruction
MAINTAINER + nameDescribe the maintainer information of the new image
RUN + commandExecute the command on the image based on and submit it to the new image (each instruction will create a mirror layer)
CMD + ["program to run", "parameter 1", "parameter 2"]The command or script to be run when the container is started (for example, CMD ["run.sh"). Dockerfile can only have one CMD command. If multiple commands are specified, only the last one can be executed
Export + port numberSpecify the port to open when the new image is loaded into Docker
ENV + environment variable + variable valueSetting the value of an environment variable will be used by the following RUN
ADD + source file / directory + target file / directoryCopy the source file to the target file. The source file should be located in the same directory as the Dockerfile or a URL. If the source file is a compressed package, it will be decompressed
COPY + source file / directory + target file / directoryCopy the file / directory on the local host to the destination, and the source file / directory should be in the same directory as the Dockerfile
VOLUME + [directory]Create a mount point (VOLUME ["/ directory"]) in the container
USER + username / UIDSpecify the user who runs the container (you may need to authorize the user when writing the mysql es mg database image file)
WORKDIR + pathSpecify the working directory for RUN, CMD and ENTRYPOINT in the next step, which is equivalent to a temporary "CD". Otherwise, the absolute path needs to be used
ONBUILD + commandSpecifies the command to run when the generated image is used as a base image
HEALTHCHECKhealth examination

Difference between CMD and ENTRYPOINT
ENTRYPOINT is similar to CMD instruction, but it will not be overwritten by the instruction specified by the command line parameters that docker run runs the container and executes, and these command line parameters will be sent to the program specified by ENTRYPOINT instruction as parameters. On the contrary, CMD will be overwritten by the command specified by docker run
CMD and ENTRYPOINT can be used together
The difference between COPY and ADD

  1. When the source file > is compressed as tar file, the compressed format is gzip, bzip2 and xz. It will be automatically copied and decompressed to the target path. The disadvantage of ADD is that the tar compressed file cannot be copied without decompressing. Will invalidate the mirror build cache, which may make the mirror build slow. Whether to use it or not can be determined according to whether it needs automatic decompression

2, Write ssh dockerfile

mkdir ssh
cd sshd

vim Dockerfile
FROM centos:7
RUN yum -y update
RUN yum -y install openssh* net-tool lsof telnet passwd
RUN echo '123456' | passwd --stdin root
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]

#Generate image
docker build -t sshd: v1 . 

#Start the container and change the root password
dockers run -d -P sshd: v1
ssh localhost -p port

3, dockerfile of tomcat

FROM centos:7
ADD apache-tomcat-9.0.16.tar.gz /opt
ADD jdk-8u201-linux-x64.rpm /opt

WORKDIR /opt
RUN rpm -ivh jdk-8u201-linux-x64.rpm
ENV JAVA_HOME /usr/java/jdk1.8.0_201-amd64
ENV CLASSPATH $JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar
ENV PATH /usr/java/jdk1.8.0_201-amd64/bin:$PATH
RUN mv apache-tomcat-9.0.16 /opt/tomcat

CMD ["/opt/tomcat/bin/catalina.sh","run"]

docker -d run -p 8080:8080 tomcat:v1	#Open container



4, dockerfile of nginx and its optimization (reduce the size of image)

(1) Conventional writing

Method 1:
[root@localhost ~]#cd nginx
[root@localhost nginx]#ls
Dockerfile  nginx-1.12.0.tar.gz
[root@localhost nginx]#vim Dockerfile 

FROM centos:7
ADD nginx-1.12.0.tar.gz /opt

RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null

RUN useradd -M -s /sbin/nologin nginx
WORKDIR /opt/nginx-1.12.0

RUN ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx

RUN make &> /dev/null && make install &> /dev/null

EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]


Method 2:
FROM centos:7
MAINTAINER gt

RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.0.tar.gz /opt/
WORKDIR /opt/nginx-1.12.0
WORKDIR nginx-1.12.0
RUN ./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf

ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]		#Call script

#Write nginx startup command script in CMD
[root@localhost nginx1]#ls
Dockerfile  nginx-1.12.0.tar.gz  run.sh
[root@localhost nginx1]#vim run.sh

#!/bin/bash
/usr/local/nginx/sbin/nginx                         


(2) nginx - dockerfile optimization

1. Put the instructions that do not need to be output into the / dev/null file
2. Reduce RUN instruction
3. Multi-stage construction

[root@localhost ~]#cd nginx3
[root@localhost nginx3]#ls
Dockerfile  nginx-1.12.0.tar.gz
[root@localhost nginx3]#vim Dockerfile 
[root@localhost nginx3]#vim Dockerfile 

FROM centos:7
ADD nginx-1.12.0.tar.gz /opt
WORKDIR /opt/nginx-1.12.0

RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null \
&& yum clean all &>/dev/null \
&& useradd -M -s /sbin/nologin nginx &> /dev/null \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx  &> /dev/null \
&& make &> /dev/null && make install &> /dev/null \
&& rm -rf /mnt/nginx-1.12.0

EXPOSE 80
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]



Multistage construction

FROM centos:7 as build
ADD nginx-1.12.0.tar.gz /opt
WORKDIR /opt/nginx-1.12.0

RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make &> /dev/null \
&& yum clean all &>/dev/null \
&& useradd -M -s /sbin/nologin nginx &> /dev/null \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx  &> /dev/null \
&& make &> /dev/null && make install &> /dev/null \
&& rm -rf /mnt/nginx-1.12.0

FROM centos:7
EXPOSE 80
COPY --from=build /usr/local/nginx /usr/local/nginx		#Use the previously built environment
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]                                                      

Topics: Docker