docker image of enterprise operation and maintenance container

Posted by mike97gt on Tue, 08 Feb 2022 11:47:28 +0100

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

  1. 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

  1. 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

Topics: Operation & Maintenance Docker