Docker进阶-构建镜像最佳实践

在真正实践之前,我们需要先搞明白几个问题:

  • Docker 镜像是什么
  • Docker 镜像的作用
  • 容器和镜像的区别及联系

Docker 镜像是什么

这里,我们以一个 Debian 系统的镜像为例。通过 docker run --it debian 可以启动一个 debian 的容器,终端会有如下输出:

/ # docker run -it debian
Unable to find image 'debian:latest' locally
latest: Pulling from library/debian
c5e155d5a1d1: Pull complete 
Digest: sha256:75f7d0590b45561bfa443abad0b3e0f86e2811b1fc176f786cd30eb078d1846f
Status: Downloaded newer image for debian:latest
root@dc7d057f7014:/# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
root@dc7d057f7014:/# 

看终端的日志,首先会查找本地是否有 debian 的镜像,如果没有则从镜像仓库(若不指定,默认是 docker.io)pull;pull 镜像成功后,再以此镜像来启动容器。

我们可以先退出此容器,来看看 Docker 镜像到底是什么。用 docker image ls 来查看已下载好的镜像:

/ # docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
debian              latest              8d31923452f8        4 days ago          101MB

docker image save 命令将镜像保存成一个 tar 文件:

/ # mkdir debian-image
/ # docker image save -o debian-image/debian.tar debian
/ # ls debian-image/
debian.tar

将镜像文件进行解压:

/ # tar -C debian-image/ -xf debian-image/debian.tar 
/ # tree -I debian.tar debian-image/
debian-image/
├── 8d31923452f8b79ae91b01568d28c90e7d667a9eaff9734c6faeb017b0efa8d0.json
├── b50334e3be68f82d0b94bb7d3cfe1789119c040c6c159759f57a19ad34547af3
│   ├── VERSION
│   ├── json
│   └── layer.tar
├── manifest.json
└── repositories

1 directory, 6 files

可以看到将镜像文件解压后,包含的内容主要是一些配置文件和 tar 包。

接下来我们来具体看看其中的内容,并通过这些内容来理解镜像的组成。

manifest.json

/debian-image # cat manifest.json  | jq
[
  {
   
    "Config": "8d31923452f8b79ae91b01568d28c90e7d667a9eaff9734c6faeb017b0efa8d0.json",
    "RepoTags": [
      "debian:latest"
    ],
    "Layers": [
      "b50334e3be68f82d0b94bb7d3cfe1789119c040c6c159759f57a19ad34547af3/layer.tar"
    ]
  }
]

注意:在实际存储时,是不包含空格的,这里为了便于展示所以使用了 jq 工具进行格式化。

manifest.json 包含了镜像的顶层配置,它是一系列配置按顺序组织而成的;以现在我们的 debian 镜像为例,它至包含了一组配置,这组配置中包含了 3 个主要的信息,我们由简到繁进行说明。

RepoTags

RepoTags 表示镜像的名称和 tag ,这里简要的对此进行说明:RepoTags 其实分为两部分:

  • Repo: Docker 镜像可以存储在本地或者远端镜像仓库内,Repo 其实就是镜像的名称。 Docker 默认提供了大量的官方镜像存储在 Docker Hub 上,对于我们现在在用的这个 Docker 官方的 debian 镜像而言,完整的存储形式其实是 docker.io/library/debian,只不过 docker 自动帮我们省略掉了前缀。
  • Tag: 我们可以通过 repo:tag 的方式来引用一个镜像,默认情况下,如果没有指定 tag (像我们上面操作的那样),则会 pull 下来最新的镜像(即:latest)

Config

Config 字段包含的内容是镜像的全局配置。我们来看看具体内容:

/debian-image # cat 8d31923452f8b79ae91b01568d28c90e7d667a9eaff9734c6faeb017b0efa8d0.json  | jq
{
   
  "architecture": "amd64",
  "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"
    ],
    "ArgsEscaped": true,
    "Image": "sha256:913ee5b96cb28ad1d43f11df4aeceee963fa07b53edccb3052a21939cae4a041",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "OnBuild": null,
    "Labels": null
  },
  "container": "e896ef8effcc3a696087509347ad072bf1ccfbd88e2e9e7a59d20293196bafa3",
  "container_config": {
   
    "Hostname": "e896ef8effcc",
    "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\"]"
    ],
    "ArgsEscaped": true,
    "Image": "sha256:913ee5b96cb28ad1d43f11df4aeceee963fa07b53edccb3052a21939cae4a041",
    "Volumes": null,
    "WorkingDir": "",
    "Entrypoint": null,
    "OnBuild": null,
    "Labels": {
   }
  

你可能感兴趣的:(Docker,docker,linux,运维)