1. Hierarchical structure of image
- Share the kernel of the host;
- The base image provides the smallest Linux distribution;
- The same docker host supports running multiple Linux distributions;
- The biggest advantage of adopting hierarchical structure is: sharing resources;
- Copy on write writable container layer, equivalent to snapshot of virtual machine;
- All mirror layers below the container layer are read-only;
- docker searches for files from top to bottom;
- The container layer saves the changed part of the image without any modification to the image itself;
- One image can have 127 layers at most;
2. Construction of image
- docker commit build a new image Trilogy
Run container
Modify container
Save the container as a new image
Disadvantages:
Low efficiency, weak repeatability and error prone;
Users cannot audit the image, which is a potential safety hazard
- Build image
[root@server1 ~]# docker pull busybox ##Pull image Using default tag: latest latest: Pulling from library/busybox 92f8b3f0730f: Pull complete Digest: sha256:b5fc1d7b2e4ea86a06b0cf88de915a2c43a99a00b6b3c0af731e5f4c07ae8eff Status: Downloaded newer image for busybox:latest docker.io/library/busybox:latest [root@server1 ~]# docker images ##View mirror REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest d3cd072556c2 4 days ago 1.24MB yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB [root@server1 ~]# docker history busybox:latest ##View the construction history of the image to see its hierarchical structure; One layer is the official website information, and the other layer is to get a shell IMAGE CREATED CREATED BY SIZE COMMENT d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3... 1.24MB [root@server1 ~]# docker run -it --name demo busybox ##Open the container in interactive mode and get a shell / # uname -r 3.10.0-957.el7.x86_64 / # free -m total used free shared buff/cache available Mem: 3950 242 2977 0 730 3463 Swap: 2047 0 2047 /#
Use ctrl +d to exit, and the docker will be closed directly after exiting; Use ctrl+p+q to run it in the background;
[root@server1 ~]# docker run -it --name demo busybox / # ls bin dev etc home proc root sys tmp usr var / # touch zxk1 / # touch zxk2 / # ls bin dev etc home proc root sys tmp usr var zxk1 zxk2 / # ##After exiting with ctrl +d here, the container will be closed [root@server1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@server1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4c28320d96c6 busybox "sh" 27 seconds ago Exited (0) 11 seconds ago demo [root@server1 ~]# docker start demo ##You can use start to open the container; demo [root@server1 ~]# docker attach demo ##Then use attach to enter the container / # ls bin dev etc home proc root sys tmp usr var zxk1 zxk2 / #
After exiting with the parameter ctrl +p +q, put the container into the background to continue running;
[root@server1 ~]# docker attach demo / # ls bin dev etc home proc root sys tmp usr var zxk1 zxk2 / # touch zxkfile1 / # touch zckfile2 / # ls bin etc proc sys usr zckfile2 zxk2 dev home root tmp var zxk1 zxkfile1 / # read escape sequence [root@server1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4c28320d96c6 busybox "sh" 3 minutes ago Up 2 minutes demo
The running container can be assigned to IP. You can use the command docker inspect demo ` to view the IP of the running container; This IP is connected to the host by bridging;
[root@server1 ~]# docker inspect demo "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", [root@server1 ~]# ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.180 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.050 ms ^C --- 172.17.0.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.050/0.115/0.180/0.065 ms
You can download a tool package to view the bridging;
[root@server1 ~]# yum install bridge-utils.x86_64 -y ##Download to view the status of the bridge [root@server1 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.024226b06bff no veth8a55abb [root@server1 ~]# docker stop demo demo [root@server1 ~]# brctl show ##When the container is closed, the resources will be released. When other containers run again, they will obtain IP addresses in turn bridge name bridge id STP enabled interfaces docker0 8000.024226b06bff no
For container deletion:
Just stopped the container, but the container is still there; You can delete unnecessary containers;
[root@server1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@server1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4c28320d96c6 busybox "sh" 17 minutes ago Exited (137) 2 minutes ago demo [root@server1 ~]# docker rm demo ##Delete containers that are not running demo [root@server1 ~]# docker ps ##View running containers CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@server1 ~]# docker ps -a ##View all containers CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
After the container is deleted, when the newly created file is in the container layer, the image is opened again, but the previous information is not visible;
[root@server1 ~]# docker run -it --name demo busybox / # ls bin dev etc home proc root sys tmp usr var / # touch 111 ##Modify container / # touch 222 / # ls 111 222 bin dev etc home proc root sys tmp usr var / # [root@server1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4f26670e58f0 busybox "sh" 43 seconds ago Exited (0) 17 seconds ago demo [root@server1 ~]# docker commit --help Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] Create a new image from a container's changes Options: -a, --author string Author (e.g., "John Hannibal Smith <hannibal@a-team.com>") -c, --change list Apply Dockerfile instruction to the created image -m, --message string Commit message -p, --pause Pause container during commit (default true) [root@server1 ~]# docker commit -m "add file" demo busybox:v1 ##Save the container as a new image sha256:ec156da5008793b690ab6b9859daa4074e24d04bcc9302b27a2095f74e0e6182 [root@server1 ~]# docker images ##View mirror REPOSITORY TAG IMAGE ID CREATED SIZE busybox v1 ec156da50087 11 seconds ago 1.24MB busybox latest d3cd072556c2 6 days ago 1.24MB yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB [root@server1 ~]# docker history busybox:latest IMAGE CREATED CREATED BY SIZE COMMENT d3cd072556c2 6 days ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 6 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3... 1.24MB [root@server1 ~]# docker history busybox:v1 ##View construction history IMAGE CREATED CREATED BY SIZE COMMENT ec156da50087 33 seconds ago sh ##Others here do not know what they have done, and there are potential safety hazards 26b add file d3cd072556c2 6 days ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 6 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3... 1.24MB [root@server1 ~]# docker rm demo ##Delete previous container demo [root@server1 ~]# docker run -it --name demo busybox:v1 ##Run on a newly packaged image / # ls 111 222 bin dev etc home proc root sys tmp usr var / # [root@server1 ~]# docker rm demo demo [root@server1 ~]# docker run -it --name demo busybox / # ls bin dev etc home proc root sys tmp usr var / #
3. Dockerfile
The image built in the above way has certain security risks, because others cannot know what they have done from the construction history.
dockerfile common instructions
- FROM
Specify the base image. If it does not exist locally, it will be downloaded from the remote warehouse. - MAINTAINER
Set the author of the image, such as user mailbox. - COPY
Copy the file from build context to image
Two forms are supported: COPY src dest and COPY ["src", "dest"]
src must specify a file or directory in the build context - ADD
The usage is similar to that of COPY. The difference is that src can be an archive compressed file, which will be automatically decompressed to dest, or the URL can be automatically downloaded and copied to the image:
ADD html.tar /var/www
ADD http://ip/html.tar /var/www - ENV
Set environment variables, which can be used by subsequent instructions:
ENV HOSTNAME sevrer1.example.com - EXPOSE
If the application service is running in the container, the service port can be exposed:
EXPOSE 80 - VOLUME
Declare the data volume, which usually specifies the application data hanging point:
VOLUME ["/var/www/html"] - WORKDIR
Set the current working directory in the image for RUN, CMD, ENTRYPOINT, ADD and COPY instructions. If the directory does not exist, it will be created automatically. - RUN
Run the command in the container and create a new mirror layer, which is commonly used to install software packages:
RUN yum install -y vim
Create Dockerfile file
Create an empty directory, and then create Dockerfile files in the empty directory;
COPY: used for the current directory and cannot be specified as the root directory.
[root@server1 ~]# mkdir docker [root@server1 ~]# cd docker/ [root@server1 docker]# ls [root@server1 docker]# vim Dockerfile [root@server1 docker]# cat Dockerfile FROM busybox ##Specify the image. If it does not exist, it will be downloaded from the remote warehouse COPY index.html / ##Copy files from to image [root@server1 docker]# echo www.westos.org > index.html [root@server1 docker]# docker build -t busybox:v2 . ##Build image Sending build context to Docker daemon 3.072kB Step 1/2 : FROM busybox ---> d3cd072556c2 Step 2/2 : COPY index.html / ---> bac12c96f3cf Successfully built bac12c96f3cf Successfully tagged busybox:v2 [root@server1 docker]# docker history busybox:v2 ##There will be a detailed process for building images with Dockerfile files IMAGE CREATED CREATED BY SIZE COMMENT bac12c96f3cf About a minute ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73... 15B d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3... 1.24MB
RUN
[root@server1 docker]# vim Docker [root@server1 docker]# cat Dockerfile FROM busybox COPY index.html / RUN touch testfile ##Run the command in the container and create a new mirror layer, which is often used to install software packages [root@server1 docker]# docker build -t busybox:v3 . Sending build context to Docker daemon 3.072kB Step 1/3 : FROM busybox ---> d3cd072556c2 Step 2/3 : COPY index.html / ---> Using cache ---> bac12c96f3cf Step 3/3 : RUN touch testfile ---> Running in 1a97d38ee1dc Removing intermediate container 1a97d38ee1dc ---> af6759a259ae Successfully built af6759a259ae Successfully tagged busybox:v3 [root@server1 docker]# docker history busybox:v3 IMAGE CREATED CREATED BY SIZE COMMENT af6759a259ae 3 seconds ago /bin/sh -c touch testfile 0B bac12c96f3cf 2 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73... 15B d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3... 1.24MB
ADD
[root@server1 docker]# vim Dockerfile [root@server1 docker]# cat Dockerfile FROM busybox COPY index.html / RUN touch testfile ADD nginx-1.18.0.tar.gz / [root@server1 docker]# ls Dockerfile index.html nginx-1.18.0.tar.gz [root@server1 docker]# docker build -t busybox:v4 . Sending build context to Docker daemon 1.043MB Step 1/4 : FROM busybox ---> d3cd072556c2 Step 2/4 : COPY index.html / ---> Using cache ---> bac12c96f3cf Step 3/4 : RUN touch testfile ---> Using cache ---> af6759a259ae Step 4/4 : ADD nginx-1.18.0.tar.gz / ---> 4a5ec9658a0a Successfully built 4a5ec9658a0a Successfully tagged busybox:v4 [root@server1 docker]# docker history busybox:v4 IMAGE CREATED CREATED BY SIZE COMMENT 4a5ec9658a0a About a minute ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50... 6.25MB af6759a259ae 8 minutes ago /bin/sh -c touch testfile 0B bac12c96f3cf 10 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73... 15B d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3... 1.24MB [root@server1 docker]# docker run --rm busybox:v4 ls ##--rm means to recycle the container directly after running bin dev etc home index.html nginx-1.18.0 ##Generate decompressed files in the current directory proc root sys testfile tmp usr var
ENV,EXPOSE ,VOLUME
[root@server1 docker]# vim Dockerfile [root@server1 docker]# cat Dockerfile FROM busybox COPY index.html / RUN touch testfile ADD nginx-1.18.0.tar.gz /mnt ENV HOSTNAME server1 EXPOSE 22 VOLUME ["/data"] ##mount [root@server1 docker]# docker build -t busybox:v6 . Sending build context to Docker daemon 1.043MB Step 1/7 : FROM busybox ---> d3cd072556c2 Step 2/7 : COPY index.html / ---> Using cache ---> bac12c96f3cf Step 3/7 : RUN touch testfile ---> Using cache ---> af6759a259ae Step 4/7 : ADD nginx-1.18.0.tar.gz /mnt ---> Using cache ---> 2bd486599e5d Step 5/7 : ENV HOSTNAME server1 ---> Running in 585940a17fef Removing intermediate container 585940a17fef ---> 815841bf0454 Step 6/7 : EXPOSE 22 ---> Running in 020e1555035d Removing intermediate container 020e1555035d ---> bf1c448c8e88 Step 7/7 : VOLUME ["/data"] ---> Running in e752fadafca6 Removing intermediate container e752fadafca6 ---> 079d588ee2b0 Successfully built 079d588ee2b0 Successfully tagged busybox:v6 [root@server1 docker]# docker history busybox:v6 IMAGE CREATED CREATED BY SIZE COMMENT 079d588ee2b0 17 seconds ago /bin/sh -c #(nop) VOLUME [/data] 0B bf1c448c8e88 17 seconds ago /bin/sh -c #(nop) EXPOSE 22 0B 815841bf0454 17 seconds ago /bin/sh -c #(nop) ENV HOSTNAME=server1 0B 2bd486599e5d 3 minutes ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50... 6.25MB af6759a259ae 13 minutes ago /bin/sh -c touch testfile 0B bac12c96f3cf 15 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73... 15B d3cd072556c2 4 days ago /bin/sh -c #(nop) CMD ["sh"] 0B <missing> 4 days ago /bin/sh -c #(nop) ADD file:c423dc64e02718dd3... 1.24MB [root@server1 docker]# docker run -it --rm busybox:v6 env ##Query variable PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=server1 TERM=xterm HOME=/root [root@server1 docker]# docker run -it --rm busybox:v6 / # cd /data/ /data # ls /data # touch file1 /data # ls file1 /data # [root@server1 docker]# docker ps ##You can see the exposed port number CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 89b679669449 busybox:v6 "sh" 46 seconds ago Up 45 seconds 22/tcp quirky_buck [root@server1 docker]# docker inspect quirky_buck ##This name is the result seen after ps. you can see the mount with this command [root@server1 docker]# cd /var/lib/docker/volumes/f3890ceefa0cf175ba9477be8dc027fcbac07e83237ac0183e5cac034eafca8d/_data [root@server1 _data]# ls ##In the mount, you can see the newly created file in its container file1 [root@server1 _data]# rm -fr file1 [root@server1 _data]# ls [root@server1 _data]# touch file2 ##Modify files in this directory [root@server1 _data]# ls file2 [root@server1 _data]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 89b679669449 busybox:v6 "sh" 4 minutes ago Up 4 minutes 22/tcp quirky_buck [root@server1 _data]# docker attach 89b679669449 ##You can also add enterprise with ID, and you can see the modified file information /data # ls file2 /data #
WORKDIR
[root@server1 docker]# vim Dockerfile [root@server1 docker]# cat Dockerfile FROM busybox COPY index.html / RUN touch testfile ADD nginx-1.18.0.tar.gz /mnt ENV HOSTNAME server1 EXPOSE 22 VOLUME ["/data"] WORKDIR /nginx-1.18.0.tar.gz ##Specify the directory where the container is located [root@server1 docker]# docker build -t busybox:v7 . Sending build context to Docker daemon 1.043MB Step 1/8 : FROM busybox ---> d3cd072556c2 Step 2/8 : COPY index.html / ---> Using cache ---> bac12c96f3cf Step 3/8 : RUN touch testfile ---> Using cache ---> af6759a259ae Step 4/8 : ADD nginx-1.18.0.tar.gz /mnt ---> Using cache ---> 2bd486599e5d Step 5/8 : ENV HOSTNAME server1 ---> Using cache ---> 815841bf0454 Step 6/8 : EXPOSE 22 ---> Using cache ---> bf1c448c8e88 Step 7/8 : VOLUME ["/data"] ---> Using cache ---> 079d588ee2b0 Step 8/8 : WORKDIR /nginx-1.18.0.tar.gz ---> Running in 99fe5b85b0df Removing intermediate container 99fe5b85b0df ---> 469584a6752f Successfully built 469584a6752f Successfully tagged busybox:v7 [root@server1 docker]# docker run -it --rm busybox:v7 /nginx-1.18.0.tar.gz # ls /nginx-1.18.0.tar.gz #
-
CMD and ENTRYPOINT
These two instructions are used to set the commands to be executed after the container is started, but CMD will be overwritten by the command line after docker run, and ENTRYPOINT will not be ignored and will be executed.
The parameters after docker run can be passed to the ENTRYPOINT instruction as parameters.
Only one entry point can be specified in Dockerfile. If many are specified, only the last one is valid. -
Differences between Shell and exec formats
#cat Dockerfile
FROM busybox
ENV name world
CMD echo "hello, $name" -
The bottom layer of Shell format will call / bin/sh -c to execute the command, which can resolve variables, but the following exec format will not:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/echo", "hello, $name"] -
It needs to be rewritten into the following form:
#cat Dockerfile
FROM busybox
ENV name world
ENTRYPOINT ["/bin/sh", "-c", "echo hello, $name"] -
In Exec format, ENTRYPOINT can provide additional parameters through CMD, and the additional parameters of CMD can be dynamically replaced when the container is started. In shell format, ENTRYPOINT ignores any parameters provided by CMD or docker run.
#cat Dockerfile
FROM busybox
ENTRYPOINT ["/bin/echo", "hello"]
CMD ["world"] -
Look at the differences when running the container:
#docker run --rm busybox:v1
hello world
#docker run --rm busybox:v1 linux
hello linux
It is officially recommended to write in exec format
[root@server1 docker]# vim Dockerfile [root@server1 docker]# cat Dockerfile FROM busybox COPY index.html / RUN touch testfile ADD nginx-1.18.0.tar.gz /mnt ENV HOSTNAME server1 EXPOSE 22 VOLUME ["/data"] WORKDIR /nginx-1.18.0.tar.gz ENTRYPOINT ["/bin/echo","hello"] CMD ["world"] [root@server1 docker]# docker build -t busybox:v8 . Sending build context to Docker daemon 1.043MB Step 1/10 : FROM busybox ---> d3cd072556c2 Step 2/10 : COPY index.html / ---> Using cache ---> bac12c96f3cf Step 3/10 : RUN touch testfile ---> Using cache ---> af6759a259ae Step 4/10 : ADD nginx-1.18.0.tar.gz /mnt ---> Using cache ---> 2bd486599e5d Step 5/10 : ENV HOSTNAME server1 ---> Using cache ---> 815841bf0454 Step 6/10 : EXPOSE 22 ---> Using cache ---> bf1c448c8e88 Step 7/10 : VOLUME ["/data"] ---> Using cache ---> 079d588ee2b0 Step 8/10 : WORKDIR /nginx-1.18.0.tar.gz ---> Using cache ---> 469584a6752f Step 9/10 : ENTRYPOINT ["/bin/echo","hello"] ---> Running in 9eb5b2461081 Removing intermediate container 9eb5b2461081 ---> 3dd02e78d687 Step 10/10 : CMD ["world"] ---> Running in 4c2b4bf52610 Removing intermediate container 4c2b4bf52610 ---> 9e88acbedae1 Successfully built 9e88acbedae1 Successfully tagged busybox:v8 [root@server1 docker]# docker run -it --rm busybox:v8 hello world [root@server1 docker]# docker run -it --rm busybox:v8 zxk hello zxk [root@server1 docker]# docker run -it --rm busybox:v8 westos hello westos
4. Image optimization
- Select the thinnest basic image;
- Reduce the number of mirror layers;
- Clean up the intermediate products of image construction;
- Pay attention to optimizing network requests;
- Try to use to build cache;
- Use multi-stage to build images;
example:
Try to create an image of Nginx. Here, use the reduced version of RHEL7 as the base image;
[root@server1 ~]# ls docker rhel7.tar [root@server1 ~]# docker load -i rhel7.tar ##Import image e1f5733f050b: Loading layer 147.1MB/147.1MB [root@server1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 1ae02957d153 About an hour ago 7.49MB yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB rhel7 latest 0a3eb3fde7fd 6 years ago 140MB [root@server1 docker]# ls Dockerfile dvd.repo index.html nginx-1.18.0.tar.gz [root@server1 docker]# cat dvd.repo [dvd] name=rhel7.6 baseurl=http://172.25.25.250/rhel7.6 gpgcheck=0 [root@server1 docker]# cat Dockerfile FROM rhel7 COPY dvd.repo /etc/yum.repos.d/ ADD nginx-1.18.0.tar.gz /mnt/ WORKDIR /mnt/nginx-1.18.0 RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel RUN ./configure --prefix=/usr/local/nginx RUN make RUN make install COPY index.html /usr/local/nginx/html EXPOSE 80 CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] [root@server1 docker]# docker build -t rhel7:v1 . ##Build image [root@server1 docker]# docker images rhel7 ##You can see that the newly built image is relatively large REPOSITORY TAG IMAGE ID CREATED SIZE rhel7 v1 fffa388c2f85 45 seconds ago 296MB rhel7 latest 0a3eb3fde7fd 6 years ago 140MB [root@server1 docker]# docker run -d --name nginx rhel7:v1 ##Run container c518fc1078acf7a8bca3b2c2dede4a17c42c80b5c6ff83edce323044294f5e18 [root@server1 docker]# docker ps ##If it works, it means there is no problem CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 36b62af6ee1c rhel7:v1 "/usr/local/nginx/sb..." 11 seconds ago Up 10 seconds 80/tcp nginx [root@server1 docker]# docker inspect nginx ##After the container runs, it will get an IP address "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } [root@server1 docker]# curl 172.17.0.2 ##test www.westos.org
Optimization 1: reduce the number of image layers and clean up the intermediate products of image construction
[root@server1 docker]# docker history rhel7:v1 ##View its mirror layer before optimizing IMAGE CREATED CREATED BY SIZE COMMENT fffa388c2f85 4 minutes ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb... 0B bc7b1152962c 4 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B e4255b736ea2 4 minutes ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73... 15B f4372157f041 4 minutes ago /bin/sh -c make install 3.88MB c82e12550cac 4 minutes ago /bin/sh -c make 12.4MB 6d042420eb1d 4 minutes ago /bin/sh -c ./configure --prefix=/usr/local/n... 71.7kB 0a26b8674cb6 6 minutes ago /bin/sh -c rpmdb --rebuilddb && yum install ... 133MB 8c2017ec9956 7 minutes ago /bin/sh -c #(nop) WORKDIR /mnt/nginx-1.18.0 0B 4086ae26148a 7 minutes ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50... 6.25MB 18246b081767 7 minutes ago /bin/sh -c #(nop) COPY file:5ec2460d7fc0badb... 67B 0a3eb3fde7fd 6 years ago 140MB Imported from - [root@server1 docker]# vim Dockerfile [root@server1 docker]# cat Dockerfile FROM rhel7 COPY dvd.repo /etc/yum.repos.d/ ADD nginx-1.18.0.tar.gz /mnt/ WORKDIR /mnt/nginx-1.18.0 RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.18.0 && yum clean all COPY index.html /usr/local/nginx/html EXPOSE 80 CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] [root@server1 docker]# docker build -t rhel7:v2 . [root@server1 docker]# docker images rhel7 REPOSITORY TAG IMAGE ID CREATED SIZE rhel7 v2 45d788701ce8 35 seconds ago 255MB rhel7 v1 fffa388c2f85 48 minutes ago 296MB rhel7 latest 0a3eb3fde7fd 6 years ago 140MB [root@server1 docker]# docker history rhel7:v2 ##View its mirror layer after optimization IMAGE CREATED CREATED BY SIZE COMMENT 45d788701ce8 About a minute ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb... 0B 46a3d583baa3 About a minute ago /bin/sh -c #(nop) EXPOSE 80 0B 571b111ea252 About a minute ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73... 15B a4605bef525d About a minute ago /bin/sh -c rpmdb --rebuilddb && yum install ... 108MB 8c2017ec9956 52 minutes ago /bin/sh -c #(nop) WORKDIR /mnt/nginx-1.18.0 0B 4086ae26148a 52 minutes ago /bin/sh -c #(nop) ADD file:46b14d1c307d23f50... 6.25MB 18246b081767 52 minutes ago /bin/sh -c #(nop) COPY file:5ec2460d7fc0badb... 67B 0a3eb3fde7fd 6 years ago 140MB Imported from -
Optimization 2: use multi-stage to build images
When building nginx, we only need the binary files of nginx. The dependencies installed in the middle of compilation and the contents generated during compilation are not used in the service;
Using the method of multi-stage construction, create a temporary image for compilation, and copy the compiled binary file to the final image to be created.
[root@server1 docker]# vim Dockerfile [root@server1 docker]# cat Dockerfile FROM rhel7 as build COPY dvd.repo /etc/yum.repos.d/ ADD nginx-1.18.0.tar.gz /mnt/ WORKDIR /mnt/nginx-1.18.0 RUN rpmdb --rebuilddb && yum install -y gcc make pcre-devel zlib-devel && sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc && ./configure --prefix=/usr/local/nginx && make && make install && rm -fr /mnt/nginx-1.18.0 && yum clean all FROM rhel7 COPY --from=build /usr/local/nginx /usr/local/nginx COPY index.html /usr/local/nginx/html EXPOSE 80 CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"] [root@server1 docker]# docker build -t rhel7:v3 .
The size of the built image is 141M, which is only 1M larger than the base image.
[root@server1 docker]# docker images rhel7 ##View the newly built size REPOSITORY TAG IMAGE ID CREATED SIZE rhel7 v3 8c8a22458c17 25 seconds ago 141MB rhel7 v2 45d788701ce8 4 minutes ago 255MB rhel7 v1 fffa388c2f85 53 minutes ago 296MB rhel7 latest 0a3eb3fde7fd 6 years ago 140MB [root@server1 docker]# docker history rhel7:v3 IMAGE CREATED CREATED BY SIZE COMMENT 8c8a22458c17 50 seconds ago /bin/sh -c #(nop) CMD ["/usr/local/nginx/sb... 0B fa842e59a5ed 50 seconds ago /bin/sh -c #(nop) EXPOSE 80 0B 9ac15082bdda 50 seconds ago /bin/sh -c #(nop) COPY file:89a58ee0b2565a73... 15B bd2144a4860b 50 seconds ago /bin/sh -c #(nop) COPY dir:e5b2163c7ba7dfad7... 851kB 0a3eb3fde7fd 6 years ago 140MB Imported from -
Optimization 3: select the thinnest basic image
If further optimization is needed, here we choose a more streamlined basic image;
[root@server1 ~]# ls base-debian10.tar docker rhel7.tar [root@server1 ~]# docker load -i base-debian10.tar ##Import image [root@server1 ~]# docker images ##It can be seen that it is only 19.2M REPOSITORY TAG IMAGE ID CREATED SIZE rhel7 v3 8c8a22458c17 7 minutes ago 141MB rhel7 v2 45d788701ce8 12 minutes ago 255MB rhel7 v1 fffa388c2f85 About an hour ago 296MB <none> <none> 1ae02957d153 2 hours ago 7.49MB yakexi007/game2048 latest 19299002fdbe 4 years ago 55.5MB rhel7 latest 0a3eb3fde7fd 6 years ago 140MB gcr.io/distroless/base-debian10 latest d48fcdd54946 51 years ago 19.2MB
For the image just built, you can view its size and the resources called by the running procedure;
[root@server1 ~]# docker run -it --rm rhel7:v3 bash bash-4.2# cd /usr/local/nginx/ bash-4.2# ls conf html logs sbin bash-4.2# du -sh 876K . bash-4.2# cd sbin/ bash-4.2# ls nginx bash-4.2# ldd nginx ##Call the library function of the system linux-vdso.so.1 => (0x00007ffdbe7c2000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f9aabde3000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f9aabbc7000) libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f9aab990000) libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f9aab72f000) libz.so.1 => /lib64/libz.so.1 (0x00007f9aab519000) libc.so.6 => /lib64/libc.so.6 (0x00007f9aab158000) /lib64/ld-linux-x86-64.so.2 (0x00007f9aabfe7000) libfreebl3.so => /lib64/libfreebl3.so (0x00007f9aaaed9000) bash-4.2#
Use the Dockfile of the official image to build a new image;
[root@server1 ~]# cd docker/ [root@server1 docker]# mkdir new [root@server1 docker]# cd new/ [root@server1 new]# docker pull nginx ##Pull the latest version of the image [root@server1 new]# vim Dockerfile [root@server1 new]# cat Dockerfile ##The content is copied from the official FROM nginx as base #https://en.wikipedia.org/wiki/List_of_tz_database_time_zones ARG TIME_ZONE RUN mkdir -p /opt/var/cache/nginx && \ cp -a --parents /usr/lib/nginx /opt && \ cp -a --parents /usr/share/nginx /opt && \ cp -a --parents /var/log/nginx /opt && \ cp -aL --parents /var/run /opt && \ cp -a --parents /etc/nginx /opt && \ cp -a --parents /etc/passwd /opt && \ cp -a --parents /etc/group /opt && \ cp -a --parents /usr/sbin/nginx /opt && \ cp -a --parents /usr/sbin/nginx-debug /opt && \ cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libpcre.so.* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \ cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \ cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \ cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \ cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime FROM gcr.io/distroless/base-debian10 COPY --from=base /opt / VOLUME ["/usr/share/nginx/html"] ##To hook up the release directory; EXPOSE 80 443 ENTRYPOINT ["nginx", "-g", "daemon off;"] [root@server1 new]# docker build -t rhel7:v4 . ##Build image [root@server1 new]# docker run -d --name demo rhel7:v4 ##Run container 4a742f3593214fd518832e8a48928d8e94852df4823d4ddaf50f3c387c18d85c [root@server1 new]# docker images rhel7 ##It can be seen that it is only 31.9M, including the foundation of 19.2M, which has been established a lot compared with the previous one REPOSITORY TAG IMAGE ID CREATED SIZE rhel7 v4 e8c324efa2e0 About an hour ago 31.9MB rhel7 v3 8c8a22458c17 2 hours ago 141MB rhel7 v2 45d788701ce8 2 hours ago 255MB rhel7 v1 fffa388c2f85 2 hours ago 296MB rhel7 latest 0a3eb3fde7fd 6 years ago 140MB [root@server1 new]# docker history rhel7:v4 IMAGE CREATED CREATED BY SIZE COMMENT b3388a690329 5 minutes ago /bin/sh -c #(nop) ENTRYPOINT ["nginx" "-g" ... 0B 52d6aca444a9 5 minutes ago /bin/sh -c #(nop) EXPOSE 443 80 0B 55d6bb5728eb 5 minutes ago /bin/sh -c #(nop) VOLUME [/usr/share/nginx/... 0B 36cd5ddf7ad3 5 minutes ago /bin/sh -c #(nop) COPY dir:4b299d402b46c2983... 12.7MB d48fcdd54946 51 years ago bazel build ... 17.4MB <missing> 51 years ago bazel build ... 1.8MB
In addition to the volumes managed by the docker engine, you can also manually specify the mount;
[root@server1 new]# docker rm -f demo [root@server1 new]# docker run -d --name demo -v /data:/usr/share/nginx/html rhel7:v4 ##Manually specify the mount, -v the connected path, whether in the host or container, will be automatically created when it does not exist; The data in the host directory must overwrite the data in the container a8c1fcb30efd26b551caaea35d9c9cda37db7d357795e25d71bee3a3aa9739d0 [root@server1 new]# docker inspect demo ##View the IP assigned by the running container [root@server1 new]# curl 172.17.0.2 ##At this time, the access has been overwritten <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.19.10</center> </body> </html> [root@server1 new]# cd /data [root@server1 data]# echo www.westos.org > index.html [root@server1 data]# curl 172.17.0.2 www.westos.org [root@server1 data]# echo www.westos.org >> index.html [root@server1 data]# echo www.westos.org >> index.html [root@server1 data]# echo www.westos.org >> index.html [root@server1 data]# curl 172.17.0.2 www.westos.org www.westos.org www.westos.org www.westos.org [root@server1 data]# docker rm -f demo [root@server1 new]# cd /data/ [root@server1 data]# ls
At this time, even if the container is deleted, the data still exists. When another container is started, you can still see the data by hooking the data
5. Summary
- Learned the docker image, mastered the hierarchical structure of the image, learned how to build the image through the dockerfile, and finally practiced a variety of optimization methods of docker image.
- Mirror common subcommands
Images displays a list of images
History displays the mirror construction history
commit create image from container
Build build image from Dockerfile
tag label the image
Search search image
Pull to pull the image from the warehouse
push upload image to warehouse
rmi delete mirror