一、Docker镜像简介

Docker镜像可以理解为停止运行的容器。

镜像由多个层组成,每层叠加之后,从外部来看是一个独立的对象。镜像内部是一个经精简的操作系统,同时包含应用运行的文件和依赖包。

二、Docker镜像详解

2.1 镜像和容器

从某个镜像启动一个或多个容器,一旦容器从镜像启动后,二者互相依赖;并且在镜像上启动的容器全部停止之前,镜像是无法删除的。

2.2 镜像命名和标签

从官方仓库拉取镜像时,需要注意以下两点: 1、如果没有在仓库名称后指定具体的镜像标签,则Docker会假设用户希望拉取标签为latest的镜像; 2、标签为latest的镜像并不保证说仓库中最新的镜像。通常使用latest标签时需要谨慎。

2.3 镜像和分层

Docker镜像由一些松藕合的只读镜像层组成。

Docker负责堆叠这些镜像层,并将它们表示为单个统一的对象。

所有Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前的镜像层之上,创建新的镜像层。

2.4 共享镜像层

多个镜像之间可以并且确实会共享镜像层。Docker可以识别出要拉取的镜像中,哪几层已经在本地存在。

2.5 多架构镜像

为实现一个镜像标签之下可以支持多个平台和架构,镜像仓库服务API支持两种重要的结构:Manifest列表(新)和Manifest。其中Manifest列表是指某个镜像标签支持的架构列表。

下面基于在Raspberry Pi(基于ARM架构的Linux)上运行Docker进行原理描述: 1、Docker客户端调用Docker Hub镜像仓库服务相应的API完成拉取镜像; 2、如果该镜像有Manifest列表,并且存在Linux on ARM这一项,则Docker客户端就会找到ARM架构对应的Manifest并解析出组成该镜像的镜像层加密ID;如果该镜像没有Manifest列表,镜像仓库服务会返回普通的Manifest。 3、从Docker Hub二进制存储中拉取每个镜像层。 说明:选择当前平台和架构所需的正确镜像版本是由Docker完成!!!

三、Docker镜像相关操作

3.1 官方仓库拉取镜像

1、执行docker image pull ubuntu:latest命令下载镜像。

root@zq-virtual-machine:/home/zq/Desktop# docker image pull ubuntu:latest

2、执行docker image ls命令查看刚才下载的镜像。

root@zq-virtual-machine:/home/zq/Desktop# docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       latest    2dc39ba059dc   4 weeks ago   77.8MB

3.2 非官方仓库拉取镜像

1、执行docker image pull nigelpoultion/tu-demo:v2命令下载镜像,此命令意思是从Docker Hub账户为nigelpoultion中名为tu-demo库中下载标签为v2的镜像。

root@zq-virtual-machine:/home/zq/Desktop# docker image pull nigelpoultion/tu-demo:v2

2、执行docker image ls命令查看刚才下载的镜像。

3.3 第三方仓库(非docker仓库)拉取镜像

1、执行docker pull gcr.io/nigelpoultion/tu-demo:v2命令下载镜像,此命令意思是从谷歌容器镜像仓库服务中且Docker Hub账户为nigelpoultion中名为tu-demo库中下载标签为v2的镜像。

root@zq-virtual-machine:/home/zq/Desktop# docker  pull gcr.io/nigelpoultion/tu-demo:v2

2、执行docker image ls命令查看刚才下载的镜像。

3.4 为镜像打多个标签

1、执行docker image pull -a nigelpoultion/tu-demo命令拉取仓库中的全部镜像。

root@zq-virtual-machine:/home/zq/Desktop# docker image pull -a nigelpoultion/tu-demo

2、执行docker image ls命令查看刚才下载的镜像。

3.5 过滤docker image ls输出内容

1、执行docker image ls --filter dangling=true命令返回悬虚(dangling)镜像,一般在列表展示为<none>:<none>。

root@zq-virtual-machine:/var/lib/docker# docker image ls --filter dangling=true
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

2、执行docker image ls --filter dangling=false命令返回非悬虚(dangling)镜像。

root@zq-virtual-machine:/var/lib/docker# docker image ls --filter dangling=false
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       latest    2dc39ba059dc   4 weeks ago   77.8MB

3、执行docker image ls --filter=reference="*:latest"命令完成过滤并且仅显示标签为latest。

root@zq-virtual-machine:/var/lib/docker# docker image ls --filter=reference="*:latest"
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ubuntu       latest    2dc39ba059dc   4 weeks ago   77.8MB

4、执行docker image ls --format "{{.Size}}"命令只返回Docker主机上镜像的大小属性。

root@zq-virtual-machine:/var/lib/docker# docker image ls --format "{{.Size}}"
77.8MB

5、执行docker image ls --format "{{.Size}} : {{.Tag}} : {{.Size}}"命令返回全部镜像,但是只显示仓库、标签和大小信息。

root@zq-virtual-machine:/var/lib/docker# docker image ls --format "{{.Size}} : {{.Tag}} : {{.Size}}"
77.8MB : latest : 77.8MB

3.6 CLI方式搜索Docker Hub

1、执行docker search nigelpoulton命令查找所有"NAME"包含"nigelpoulton"的仓库。

root@zq-virtual-machine:/var/lib/docker# docker search nigelpoulton
NAME                                 DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
nigelpoulton/pluralsight-docker-ci   Simple web app used in my Pluralsight video    27                   [OK]
nigelpoulton/tu-demo                 Voting web server used for various Pluralsig   16                   
nigelpoulton/getting-started-k8s     Node.js web app                                 9                    
nigelpoulton/gsd                     Getting Started with Docker -- Pluralsight v   6                    
nigelpoulton/k8sbook                 Simple web app used for demos in The Kuberne   4                    
nigelpoulton/ctr-demo                Web server for simple Docker demos              3                    
nigelpoulton/nginxadapter            Slightly modified NGINX image for use in Plu   1                    
nigelpoulton/ps-web                  Simple web app used in Pluralsight courses.     1                    
nigelpoulton/vote                    Fork of dockersamples Voting App for *Docker   1                    
nigelpoulton/hello-cloud             Quick hello-world container image used for D   0                    
nigelpoulton/msb-hello                                                               0                    
nigelpoulton/web-app                 Web app for use in Pluralsight multi-contain   0                    
nigelpoulton/acg-web                 Simple web app for A Cloud Guru Kubernetes D   0                    
nigelpoulton/msb-web                                                                 0                    
nigelpoulton/web-fe1                 Web front end                                   0                    
nigelpoulton/workshop101             Kubernetes 101 Workshop.                        0                    
nigelpoulton/lke-nodebalancer        Node.js webserver for Linode LKE demos          0                    
nigelpoulton/curl                    Simple *curl* container for use in demos and   0                    
nigelpoulton/k8s-deep-dive           Images for use in Kubernetes Deep Dive book     0                    
nigelpoulton/dockerbook              Repo for examples used in Docker Deep Dive b   0                    
nigelpoulton/ddd-web                 Web server for use in Docker Deep Dive partn   0                    
nigelpoulton/qsk-book                Images for use in *Quick Start Kubernetes* b   0                    
nigelpoulton/web                     Demo Node.js web app used in Docker Deep Div   0                    
nigelpoulton/k8s101-sksh             Images for Kubernetes 101 course on Skillsha   0                    
nigelpoulton/k8s-api-proxy                                                           0 

说明:关于docker search,默认情况下,只返回25行结果;可以指定--limit参数来增加返回内容行数,最多为100行!!! 2、执行docker search alpine命令列出所有仓库名称中包含"alpine"的镜像。

root@zq-virtual-machine:/var/lib/docker# docker search alpine
NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
alpine                             A minimal Docker image based on Alpine Linux   9256      [OK]       
alpinelinux/docker-cli             Simple and lightweight Alpine Linux image wi   5                    
alpinelinux/gitlab-runner          Alpine Linux gitlab-runner (supports more ar   3                    
alpinelinux/alpine-gitlab-ci       Build Alpine Linux packages with Gitlab CI      3                    
alpinelinux/gitlab-runner-helper   Helper image container gitlab-runner-helper    1                    
grafana/alpine                     Alpine Linux with ca-certificates package in   1                    
alpinelinux/package-builder        Container to build packages for a repository    1                    
rancher/alpine-git                                                                 1                    
alpinelinux/golang                 Build container for golang based on Alpine L   1                    
alpinelinux/build-base             Base image suitable for building packages wi   0                    
alpinelinux/docker-abuild          Dockerised abuild                               0                    
alpinelinux/darkhttpd                                                              0                    
alpinelinux/docker-compose         docker-compose image based on Alpine Linux      0                    
alpinelinux/unbound                                                                0                    
alpinelinux/docker-alpine                                                          0                    
alpinelinux/mqtt-exec                                                              0                    
alpinelinux/apkbuild-lint-tools    Tools for linting APKBUILD files in a CI env   0                    
alpinelinux/mirror-status                                                          0                    
alpinelinux/git-mirror-syncd                                                       0                    
alpinelinux/alpine-docker-gitlab   Gitlab running on Alpine Linux                  0                    
alpinelinux/rsyncd                                                                 0                    
alpinelinux/alpine-drone-ci        Build Alpine Linux packages with drone CI       0                    
alpinelinux/ansible                Ansible in docker                               0                    
alpinelinux/secdb                                                                  0                    
alpinelinux/aports-qa-bot          A Gitlab bot that gives feedback on aports m   0                    

说明:关于docker search,默认情况下,只返回25行结果;可以指定--limit参数来增加返回内容行数,最多为100行!!! 3、执行docker search alpine --filter "is-official=true"命令列出官方alpine的镜像。

root@zq-virtual-machine:/var/lib/docker# docker search alpine --filter "is-official=true"
NAME      DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
alpine    A minimal Docker image based on Alpine Linux   9256      [OK] 

说明:关于docker search,默认情况下,只返回25行结果;可以指定--limit参数来增加返回内容行数,最多为100行!!! 4、执行docker search alpine --filter "is-automated=true"命令只显示自动创建的仓库。

root@zq-virtual-machine:/var/lib/docker# docker search alpine --filter "is-automated=true"
NAME      DESCRIPTION   STARS     OFFICIAL   AUTOMATED

说明:关于docker search,默认情况下,只返回25行结果;可以指定--limit参数来增加返回内容行数,最多为100行!!!

3.7 查看镜像分层

1、执行docker image inspect ubuntu:latest命令查看镜像分层方式。这里观察到"Layers"后面只有一个SHA256散列值来标识镜像层。代表该镜像只包含一个镜像层。

root@zq-virtual-machine:/var/lib/docker# docker image inspect ubuntu:latest
[
    {
        "Id": "sha256:2dc39ba059dcd42ade30aae30147b5692777ba9ff0779a62ad93a74de02e3e1f",
        "RepoTags": [
            "ubuntu:latest"
        ],
        "RepoDigests": [
            "ubuntu@sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2022-09-01T23:46:35.375057619Z",
        "Container": "b0df58d0a952d2cb3b35163ac557fe1886c0fe5cf73a82a16491a22089aadb8c",
        "ContainerConfig": {
            "Hostname": "b0df58d0a952",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"bash\"]"
            ],
            "Image": "sha256:1f88c721b49061df8bcee6398193b3642df4f089f9343e138302473c3d58fc06",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {}
        },
        "DockerVersion": "20.10.12",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
            ],
            "Cmd": [
                "bash"
            ],
            "Image": "sha256:1f88c721b49061df8bcee6398193b3642df4f089f9343e138302473c3d58fc06",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": null
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 77830458,
        "VirtualSize": 77830458,
        "GraphDriver": {
            "Data": {
                "DeviceId": "2",
                "DeviceName": "docker-8:5-1065834-64b7546962b390b4619e08ed872bf043fa8afe203860c2298207a62080170efa",
                "DeviceSize": "10737418240"
            },
            "Name": "devicemapper"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:7f5cbd8cc787c8d628630756bcc7240e6c96b876c2882e6fc980a8b60cdfa274"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

3.8 根据摘要拉取镜像

下面先在Docker主机上删除ubuntu:latest镜像,然后根据摘要再次拉取ubuntu:latest镜像。 1、执行docker image ls --digests ubuntu命令查看在本地查看镜像摘要-基于其内容的密码散列值。这里观察到DIGEST值为sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1。

root@zq-virtual-machine:/var/lib/docker# docker image ls --digests ubuntu
REPOSITORY   TAG       DIGEST                                                                    IMAGE ID       CREATED       SIZE
ubuntu       latest    sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1   2dc39ba059dc   4 weeks ago   77.8MB

2、执行docker image rm ubuntu:latest命令删除ubuntu:latest镜像。

root@zq-virtual-machine:/var/lib/docker# docker image rm ubuntu:latest
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1
Deleted: sha256:2dc39ba059dcd42ade30aae30147b5692777ba9ff0779a62ad93a74de02e3e1f
Deleted: sha256:7f5cbd8cc787c8d628630756bcc7240e6c96b876c2882e6fc980a8b60cdfa274

3、执行docker image ls命令查看镜像是否成功删除,这里观察到,已成功删除。

root@zq-virtual-machine:/var/lib/docker# docker image ls
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

4、执行docker image pull ubuntu@sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1命令根据摘要再次拉取ubuntu:latest镜像。

root@zq-virtual-machine:/var/lib/docker# docker image pull ubuntu@sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1
docker.io/library/ubuntu@sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1: Pulling from library/ubuntu
2b55860d4c66: Pull complete 
Digest: sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1
Status: Downloaded newer image for ubuntu@sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1

3.9 删除镜像

1、执行docker image pull ubuntu:latest命令下载一组镜像-ubuntu:latest。

root@zq-virtual-machine:/var/lib/docker# docker image pull ubuntu:latest
latest: Pulling from library/ubuntu
2b55860d4c66: Pull complete 
Digest: sha256:20fa2d7bb4de7723f542be5923b06c4d704370f0390e4ae9e1c833c8785644c1
Status: Downloaded newer image for ubuntu:latest

2、执行docker image ls -q命令获取镜像ID。

root@zq-virtual-machine:/var/lib/docker# docker image ls -q
2dc39ba059dc

3、执行docker image rm $(docker image ls -q) -f命令删除本地系统中的全部镜像。

root@zq-virtual-machine:/var/lib/docker# docker image rm $(docker image ls -q) -f

4、执行docker image ls命令验证镜像是否删除,这里观察到,镜像已成功删除。

root@zq-virtual-machine:/var/lib/docker# docker image ls 
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

3.10 查看构建镜像执行历史指令

1、执行docker image history web:latest命令查看构建镜像执行了哪些历史指令。

root@zq-virtual-machine:/home/zq/Desktop/psweb# docker image history web:latest
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
683c55e54235   2 hours ago   /bin/sh -c #(nop)  ENTRYPOINT ["node" "./app…   0B        
4f4a2d392749   2 hours ago   /bin/sh -c #(nop)  EXPOSE 8080                  0B        
a622f45f36d3   2 hours ago   /bin/sh -c npm install                          27MB      
f73bb626a9b7   2 hours ago   /bin/sh -c #(nop) WORKDIR /src                  0B        
29d1736dc769   2 hours ago   /bin/sh -c #(nop) COPY dir:310d2a161b2d2b7a1…   42.1kB    
20d2ab48de19   2 hours ago   /bin/sh -c apk add --update nodejs npm curl     54.3MB    
2e2dc063771c   2 hours ago   /bin/sh -c #(nop)  LABEL maintainer=nigelpou…   0B        
9c6f07244728   8 weeks ago   /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      8 weeks ago   /bin/sh -c #(nop) ADD file:2a949686d9886ac7c   5.54MB 

2、针对以上内容,有几点需要注意: (1)每行内容对应一条指令,顺序是自下而上,CREATED BY 具体展示了当前行具体对应Dockerfile中哪些指令。 (2)SIZE不为零的指令会新建镜像层,对应FROM、RUN和COPY指令。SIZE为零的指令只是新增了元数据信息,不会新建镜像层。

3.11 镜像打标签(不覆盖原来的标签)

命令格式为docker image tag <当前的标签> <新标签> 1、执行docker image tag web:latest jeckjohn/web:latest命令为当前镜像重新打一个标签。

zq@zq-virtual-machine:~/Desktop/psweb$ docker image tag web:latest jeckjohn/web:latest

2、继续执行docker image ls命令查看标签重打是否成功。这里观察到,标签重打成功。

zq@zq-virtual-machine:~/Desktop/psweb$ docker image ls
REPOSITORY     TAG       IMAGE ID       CREATED          SIZE
jeckjohn/web   latest    683c55e54235   37 minutes ago   87MB
web            latest    683c55e54235   37 minutes ago   87MB

3.12 推送镜像到镜像库

1、继续执行docker image push jeckjohn/web:latest命令将该镜像推送到Docker Hub上。

zq@zq-virtual-machine:~/Desktop/psweb$ docker image push jeckjohn/web:latest
The push refers to repository [docker.io/jeckjohn/web]
32afb898c296: Pushed 
7b222b64804f: Pushed 
e0eb8cd31e9f: Pushed 
994393dc58e7: Mounted from library/alpine 
latest: digest: sha256:0d02bf3f3a6a16c98235f3d1e6d3e2501f34665e009dea3b0fd69cfb592a519d size: 1161

3.13 构建新镜像

1、在Dockerfile所在文件夹视图执行docker image build -t web:latest . 命令构建生成一个名为web:latest的镜像,其中命令最后的点代表Docker在进行构建的时候,使用当前目录作为构建上下文。其中-t参数指的是给镜像打标签,使用-f参数指定Dockfile的路径和名称。

zq@zq-virtual-machine:~/Desktop/psweb$ docker image build -t web:latest . 

2、执行docker image ls命令查看镜像是否下载成功。这里观察到,镜像已成功下载。

zq@zq-virtual-machine:~/Desktop/psweb$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
web          latest    683c55e54235   2 minutes ago   87MB

3、构建新镜像过程如下: (1)运行临时容器 (2)在该容器运行Dockerfile中的指令 (3)将指令运行的结果保存为一个新的镜像层 (4)删除临时容器

3.14 合并镜像

1、执行docker image build ubuntu:latest--squash命令创建一个合并的镜像。

root@zq-virtual-machine:~# docker image build ubuntu:latest--squash