docker镜像管理

本文最后更新于:2023年12月5日 晚上

镜像结构和原理

镜像就是创建容器的模板,含有启动容器所需要的文件系统及所需要的内容,因此镜像主要用于方便和快速的创建并启动容器

镜像理由是一层一层的文件系统:Union FS(联合文件系统),可以将几层目录挂载到一起(类似俄罗斯套娃),形成一个虚拟文件系统,虚拟文件系统的目录结构就像普通 linux 目录结构一样,镜像通过这些文件,再加上宿主机的内核共同构成了一个 linux 的虚拟环境,每一层文件系统叫做一层 layer,联合文件系统可以对每一层文件系统设置三种权限:readonly、readwrite、writeout-able。但是镜像中每一层文件系统都是只读的,构建镜像的时候,从一个最基本的操作系统开始,每个构建提交的操作都相当与做一层的修改,增加了一层文件系统,一层层往上叠加,上层的修改会覆盖底层该位置的可见性,当使用镜像的时候,我们只会看见一个整体,并不知道里面有几层,实际上也不需要知道

一个典型的 Linux 文件系统由 bootfs 和 rootfs 两部分组成

bootfs(boot file system)主要包含 bootloader 和 kernel,bootloader 主要用于引导加载 kernel。系统刚启动时会加载 bootfs 文件系统,kernel 加载到内存后,接管系统的控制权,bootfs 就会被 umount 掉

rootfs(root file system)就是我们看到的/dev、/proc、/bin、/etc 等目录和文件,不同的 linux 发行版本(如 ubuntu 和 centos)主要在 rootfs 这一层会有所区别

一般的镜像通常都比较小,镜像直接调用宿主机的内核,镜像中只提供 rootfs,也就是只需包括最基本的命令、配置文件和程序库等相关文件就可以了

容器、镜像和父镜像关系

alpine 介绍

Alpine 操作系统是一个面向安全的轻型 Linux 发行版。它不同于通常 Linux 发行版,Alpine 采用了 musl libc 和 busybox 以减小系统的体积和运行时资源消耗,但功能上比 busybox 又完善的多,因此得到开源社区越来越多的青睐。在保持瘦身的同时,Alpine 还提供了自己的包管理工具 apk,可以通过https://pkgs.alpinelinux.org/packages 网站上查询包信息,也可以直接通过 apk 命令直接查询和安装各种软件。

Alpine 由非商业组织维护的,支持广泛场景的 Linux 发行版,它特别为资深/重度 Linux 用户而优化,关注安全,性能和资源效能。Alpine 镜像可以适用于更多常用场景,并且是一个优秀的可以适用于生产的基础系统/环境。

Alpine Docker 镜像也继承了 Alpine Linux 发行版的这些优势。相比于其他 Docker 镜像,它的容量非常小,仅仅只有 5 MB 左右(对比 Ubuntu 系列镜像接近 200 MB),且拥有非常友好的包管理机制。官方镜像来自 docker-alpine 项目。

目前 Docker 官方已开始推荐使用 Alpine 替代之前的 Ubuntu 做为基础镜像环境。这样会带来多个好处。包括镜像下载速度加快,镜像安全性提高,主机之间的切换更方便,占用更少磁盘空间等。

#修改源替换成阿里源:将/etc/apk/repositories中的 dl-cdn.alpinelinux.org 改成 mirrors.aliyun.com
sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories
#更新源
apk update
# 查找可用软件包
apk search [vim]
# 列出软件信息
apk info [vim]
#安装软件
apk add vim
#删除软件
apk del openssh openntp vim

搜索镜像

如果联网下载,一般不会使用命令搜索,而是去官网搜索

docker 镜像加速

登录阿里云 –> 容器镜像服务 –> 镜像中心 –> 镜像加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://3417nt4m.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

docker image

# docker help image
Usage: docker image COMMAND

Commands:
  build       # 从Dockerfile中构建镜像
  history     # 显示镜像分层历史
  import      # 从tar包中的内容创建一个新的文件系统映像[对应 container export]
  inspect     # 显示容器详细信息
  load        # 从一个tar包中加载一个镜像[对应save]
  ls          List images
  prune       # 移除未使用的镜像
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rm          # 移除一个或多个镜像
  save        # 保存一个镜像为一个tar包[对应load]
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

下载镜像 pull

# docker help pull
docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Options:
  -a,  --all-tags                 Download all tagged images in the repository
    --disable-content-trust    Skip image verification (default true)
    --platform string          Set platform if server is multi-platform capable
  -q,  --quiet                    Suppress verbose output

NAME  镜像名,仓库服务器:端口/项目名称/镜像名称
:TAG  版本号,如果不指定:TAG,则下载最新版镜像
@DIGEST  摘要
[root@ubuntu1804 ~]#docker pull hello-world
Using default tag: latest      # tag 默认下载tag为latest
latest: Pulling from library/hello-world
1b930d010525: Pull complete      # 分层下载
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f  # 摘要
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest   # 下载的完整地址
$ docker pull nginx:stable-alpine
stable-alpine: Pulling from library/nginx
97518928ae5f: Pull complete
a15dfa83ed30: Pull complete
acae0b19bbc1: Pull complete
fd4282442678: Pull complete
b521ea0d9e3f: Pull complete
b3282d03aa58: Pull complete
Digest: sha256:74694f2de64c44787a81f0554aa45b281e468c0c58b8665fafceda624d31e556
Status: Downloaded newer image for nginx:stable-alpine
docker.io/library/nginx:stable-alpine

下载后的镜像位于:

/var/lib/docker/overlay2/镜像ID

查看镜像分层历史 history

$ docker image history nginx:latest
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
605c77e624dd   11 months ago   /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…   0B
<missing>      11 months ago   /bin/sh -c #(nop)  STOPSIGNAL SIGQUIT           0B
<missing>      11 months ago   /bin/sh -c #(nop)  EXPOSE 80                    0B
<missing>      11 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["/docker-entr…   0B
<missing>      11 months ago   /bin/sh -c #(nop) COPY file:09a214a3e07c919a…   4.61kB
<missing>      11 months ago   /bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7…   1.04kB
<missing>      11 months ago   /bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b0…   1.96kB
<missing>      11 months ago   /bin/sh -c #(nop) COPY file:65504f71f5855ca0…   1.2kB
<missing>      11 months ago   /bin/sh -c set -x     && addgroup --system -…   61.1MB
<missing>      11 months ago   /bin/sh -c #(nop)  ENV PKG_RELEASE=1~bullseye   0B
<missing>      11 months ago   /bin/sh -c #(nop)  ENV NJS_VERSION=0.7.1        0B
<missing>      11 months ago   /bin/sh -c #(nop)  ENV NGINX_VERSION=1.21.5     0B
<missing>      11 months ago   /bin/sh -c #(nop)  LABEL maintainer=NGINX Do…   0B
<missing>      11 months ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B
<missing>      11 months ago   /bin/sh -c #(nop) ADD file:09675d11695f65c55…   80.4MB

查看容器详细信息 inspect

$ docker image inspect nginx:latest
[
    {
        "Id": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85",
        "RepoTags": [
            "nginx:latest"
        ],
        "RepoDigests": [
            "nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31"
        ],
        "Parent": "",
        "Comment": "",
        "Created": "2021-12-29T19:28:29.892199479Z",
        "Container": "ca3e48389f7160bc9d9a892d316fcbba459344ee3679998739b1c3cd8e56f7da",
        "ContainerConfig": {
            "Hostname": "ca3e48389f71",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.5",
                "NJS_VERSION=0.7.1",
                "PKG_RELEASE=1~bullseye"
            ],
            "Cmd": [
                "/bin/sh",
                "-c",
                "#(nop) ",
                "CMD [\"nginx\" \"-g\" \"daemon off;\"]"
            ],
            "Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGQUIT"
        },
        "DockerVersion": "20.10.7",
        "Author": "",
        "Config": {
            "Hostname": "",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": false,
            "AttachStderr": false,
            "ExposedPorts": {
                "80/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "NGINX_VERSION=1.21.5",
                "NJS_VERSION=0.7.1",
                "PKG_RELEASE=1~bullseye"
            ],
            "Cmd": [
                "nginx",
                "-g",
                "daemon off;"
            ],
            "Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": [
                "/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
            },
            "StopSignal": "SIGQUIT"
        },
        "Architecture": "amd64",
        "Os": "linux",
        "Size": 141479488,
        "VirtualSize": 141479488,
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/7e01f99d0c11ed39e85b19c848a5593a5e9ebc65d339a266c07cd1f7bd7431ba/diff:/var/lib/docker/overlay2/d74f65dcbc4304207be8a4591b8c83f1d7faa4659da1612d0468e34f507902af/diff:/var/lib/docker/overlay2/ee3d6bfb887a97e99debff027624cc44f7e927852f10ad685c07468175b2f50b/diff:/var/lib/docker/overlay2/9589ebb2cd873d1a650ef2f9d540505edccbb13f838b13b660f1d49a060be769/diff:/var/lib/docker/overlay2/c81f555278e6da337860aebbe14978402627d46d4beb3ad5eaed34ec2b9264fe/diff",
                "MergedDir": "/var/lib/docker/overlay2/efe3607d46ef55d39a59cf896b34e8e186d657969a48b121f89dca639f8541f4/merged",
                "UpperDir": "/var/lib/docker/overlay2/efe3607d46ef55d39a59cf896b34e8e186d657969a48b121f89dca639f8541f4/diff",
                "WorkDir": "/var/lib/docker/overlay2/efe3607d46ef55d39a59cf896b34e8e186d657969a48b121f89dca639f8541f4/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f",
                "sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8",
                "sha256:b8d6e692a25e11b0d32c5c3dd544b71b1085ddc1fddad08e68cbd7fda7f70221",
                "sha256:f1db227348d0a5e0b99b15a096d930d1a69db7474a1847acbc31f05e4ef8df8c",
                "sha256:32ce5f6a5106cc637d09a98289782edf47c32cb082dc475dd47cbf19a4f866da",
                "sha256:d874fd2bc83bb3322b566df739681fbd2248c58d3369cb25908d68e7ed6040a6"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

查看本地镜像 ls

等同于 docker images

# docker image ls --help
docker image ls [OPTIONS] [REPOSITORY[:TAG]]

Options:
  -a,  --all              Show all images (default hides intermediate images)
    --digests          Show digests
  -f,  --filter filter    Filter output based on conditions provided
    --format string    Pretty-print images using a Go template
    --no-trunc         # 不截断输出,即展示完整的容器ID
  -q,  --quiet            # 只展示容器ID

REPOSITORY  # 镜像所属的仓库名称
TAG    # 镜像版本号(标识符),默认为latest
$ docker image ls
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        latest    605c77e624dd   11 months ago   141MB

$ docker image ls -q
605c77e624dd

$ docker image ls --no-trunc
REPOSITORY   TAG       IMAGE ID                                                                  CREATED         SIZE
nginx        latest    sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85   11 months ago   141MB


IMAGE ID  # 镜像唯一ID标识,如果ID相同,说明是同一个镜像有多个名称

REPOSITORY 仓库:

  • 由某特定的 docker 镜像的所有迭代版本组成的镜像仓库
  • 一个 Registry 中可以存在多个 Repository
  • Repository 可分为“顶层仓库”和“用户仓库”
  • Repository 用户仓库名称一般格式为“用户名/仓库名”
  • 每个 Repository 仓库可以包含多个 Tag(标签),每个标签对应一个镜像

镜像导出 save

将本地镜像导出为一个文件(tar 格式),然后复制到其他服务器,导入使用

# docker help image save
Usage: docker image save [OPTIONS] IMAGE [IMAGE...]

Options:
  -o, --output string   Write to a file, instead of STDOUT

常见用法:以下两种用法等价

docker save -o /path/file.tar IMAGE1 IMAGE2 ...
docker save IMAGE1 IMAGE2 ... > /path/file.tar

镜像导入 load

save 导出的镜像 tar 文件,使用load导入

# docker help image load

Usage: docker image load [OPTIONS]

Options:
  -i, --input string   Read from tar archive file, instead of STDIN
  -q, --quiet          Suppress the load output

常见用法:以下两种用法等价

docker load -i /data/myimages.tar
docker load < /data/myimages.tar

删除镜像 rm

删除本地镜像

# docker help image rm
Usage: docker image rm [OPTIONS] IMAGE [IMAGE...]

Aliases:
  rm, rmi, remove

Options:
  -f,  --force        Force removal of the image  # 强制删除
    --no-prune        Do not delete untagged parents
alias rmi='docker image ls -aq | xargs -n1 docker image rm'

镜像打标签 tag

给镜像打标签,类似于起别名,但通常要遵守一定的命名规范,才可以上传到指定的仓库

docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

# TARGET_IMAGE[:TAG] 格式一般为
1.仓库主机FQDN或IP[:端口]
2.项目名(或用户名)
3.image名字:版本  # docker tag alpine alpine:3.11

tag 默认为 latest

先 tag 给镜像打标签,然后再 save 导出镜像,拷贝到其他机器,其他机器可以 load 导入


docker镜像管理
http://blog.lujinkai.cn/运维/Docker/1.2.docker镜像管理/
作者
像方便面一样的男子
发布于
2021年1月8日
更新于
2023年12月5日
许可协议