• Due to docker's hierarchical storage, the deleted files are always in the hierarchy, they are just marked as deleted
  • You can use the docker history [img_name] command to see the hierarchy of the target image
  • Use docker images [img_name] to see the image size
  • The solution is to use export/import to refactor the file hierarchy
  • Refactoring the filesystem will lose the meta information about cmd/port/etc.
  1. First prepare the dockerfile for testing

    # docker build -t t1 .
    
    FROM ubuntu
    # quick install, unattended mode
    ENV DEBIAN_FRONTEND=noninteractive
    # request port
    EXPOSE 22
    
    
    # Run the install script
    # RUN bash /tmp/run.sh
    RUN dd if=/dev/zero of=100M.bin count=1 bs=100MB
    RUN dd if=/dev/zero of=10M.bin count=1 bs=10MB
    RUN rm 100M.bin
    
    CMD ["bash"]
    • here use docker build -t t1 . command to build as image t1.
  2. volume calculation.:

    1. assume: ubuntu is known to have an initial size of 72.8MB.
    2. then the theoretical size of the image should be 72.8+100+10-100=82.8MB.
    3. but in reality it is 72.8+100+10=182.8M

      # docker images t1
      REPOSITORY TAG IMAGE ID CREATED SIZE
      t1 latest 7dc3c4768c6e 2 minutes ago 183MB
    4. and then look at the file hierarchy

      # docker history t1
      │IMAGE CREATED CREATED BY SIZE COMM
      │ENT
      │7dc3c4768c6e 3 minutes ago /bin/sh -c #(nop) CMD ["bash"] 0B
      │f7977abaef92 3 minutes ago /bin/sh -c rm 100M.bin 0B
      │847d68ab1484 3 minutes ago /bin/sh -c dd if=/dev/zero of=10M.bin count=... 10MB
      │62baa88f2d83 3 minutes ago /bin/sh -c dd if=/dev/zero of=100M.bin count... 100MB
      │2bbf0d43850b 3 minutes ago /bin/sh -c #(nop) EXPOSE 22 0B
      │a6e876477399 3 minutes ago /bin/sh -c #(nop) ENV DEBIAN_FRONTEND=nonin... 0B
      │ba6acccedd29 2 months ago /bin/sh -c #(nop) CMD ["bash"] 0B
      │<missing> 2 months ago /bin/sh -c #(nop) ADD file:5d68d27cc15a80653... 72.8MB
      
      • you can see that rm 100M.bin doesn't really delete the file
  3. the real solution is to initialize it as an instance first, then directly re-export it and then re-import it. This way you can refactor the file hierarchy

    # refactor the file hierarchy
    function mini_images()
    {
        # Original image name
        src=$1
        
        # Temporary container name, do not conflict with existing containers
        dk_tmp=cv.by.kms.app
        
        # Instantiate the container first
        docker create -it -P --name $dk_tmp $src
        
        # Then export the container
        docker export $dk_tmp -o $dk_tmp.tar
        # docker export $dk_tmp |gzip > $dk_tmp.tar.gz
        
        # Delete the original image and the temporary container
        docker rm $dk_tmp
        docker rmi $src
        # Reimport
        docker import $dk_tmp.tar $src
        rm $dk_tmp.tar
        # show the results
        docker images $src
    }
    
    # Parameters: Name of the original image (the image you want to refactor)
    mini_images t1
    • After refactoring and using docker images t1, you can see that the size is reduced to 82.8MB as expected

      # docker images t1
      REPOSITORY TAG IMAGE ID CREATED SIZE
      t1 latest 3f18764312ee 58 seconds ago 82.8MB
  4. reconstruct the file system will lose cmd and other information, you need to re-build with dockerfile. Only suitable as a base image
  5. you can also use inspect+jq to see the startup information of the original image/container

    docker inspect t1|jq
    docker inspect t1|jq . [0]|jq .Config.Cmd 
    docker inspect t1|jq . [0]|jq .Config.Entrypoint 
Last modification:January 7, 2022
如果觉得我的文章对你有用,请随意赞赏