镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象,镜像内部是一个精简的OS,同时还包含应用运行所必须的文件和依赖包,因为容器的设计初衷就是快速和小巧,所以镜像通常都比较小。镜像可以理解为一种构建时(build-time)结构,而容器可以理解为是一种运行时(run-time)结构。
Docker镜像由一些松耦合的只读镜像层组成,采用docker pull imageName:tag ,可以看出以Pull complete结尾的每一行都是一个镜像层。可以采用docker image inspect查看到Layers信息。
$ docker image ls inspect centos:7
"Layers": [
"sha256:d69483a6face4499acb974449d1303591fcbb5cdce5420f36f8a6607bda11854"
]
所有的Docker镜像都起始于一个基础镜像层,当进行修改或者增加新的内容时,就会在当前镜像层之上,创建新的镜像层,比如,一个centos:7的镜像,添加了Python包,那么就会在基础镜像层上添加一个镜像层,比如再打了一个安全补丁,又会创建一个新的镜像层。
通常使用docker container run和docker service create命令从某个镜像启动一个或多个容器,一旦容器从镜像启动后,二者之间就有依赖关系,并且在镜像启动的容器全部停止之前,镜像是无法被删除的。
启动时,docker daemon会试图从本地获取相关的镜像;本地镜像不存在时,其将从Registry中下载该镜像并保存到
$ docker pull ubuntu:latest
# 其中 ubuntu为拉取的镜像名,latest为镜像的tag,一般以版本号标识。
# 采用非Docker Hub的镜像仓库
$ docker pull quay.io/coreos/flannel:v0.11.0-amd64
# 推送到Docker Hub的个人账号下,首先需要登录。
$ docker login -u gezr17
$ docker push gezr17/httpd
# 打包并压缩
$ docker save -o myimg.tar.gz gezr17/httpd:v0.1-1 gezr17/httpd:v0.2
# 可以传到另外一台主机上测试
$ scp myimg.tar.gz [email protected]:/root/
$ docker load -i myimg.tar.gz
Sponsor Registry
:第三方的registry,供客户和Docker社区使用
Mirror Registry
:第三方的registry,只让客户使用
Vendor Registry
:由发布docker镜像的供应商提供的registry
Private Registry
:通过设有防火墙和额外的安全层的私有实体提供的registry
(1)Dockerfile
(2)基于容器制作
# 选择基础镜像,然后生成容器
$ docker run -it --name b1 busybox
# 对容器做一系列操作,比如
mkdir -p /data/html
vi index.html
# 并在index.html中写入你自己的东西,并封装成镜像,并打上tag
$ docker commit -p b1
$ docker tag e252c35dccef gezr17/httpd:v0.1-1
# 如若想创建时把容器的默认情况进行修改,比如以busybox为例
$ docker commit -a "gzr " -c 'CMD ["/bin/httpd", "-f","-h","/data/html"]' -p b1 gezr17/httpd:v0.2
# -a 表示作者信息,-c 表示启动时进入的命令,-p表示暂停容器的运行状态。
# 查看容器的具体信息
$ docker inspect containername
$ curl 172.17.0.5 # 172.17.0.5为容器的IP
(3)Docker Hub automated builds
Docker Hub是Docker默认的镜像仓库,所谓镜像仓库就是存储镜像的地方,可以包含多个镜像。
可以通过过滤,只搜索官方仓库,如:
$ docker search ubuntu --filter "is-official=true"
关于docker search 需要注意的最后一点是,默认情况下,Docker只返回25行结果,但是用户可以指定**–limit** 参数来增加返回的内容行数。
注意:镜像是静态的,而容器是动态的,有生命周期的。
那些没有标签的镜像被称为"悬虚镜像",可能的原因是:构建了一个新镜像,然后为该镜像打上了一个已经存在的标签,这样Docker会移除旧镜像上的标签,将该标签标在新镜像之上,而旧镜像就会成为"悬虚镜像"。
可以采用以下命令查看和移除悬虚镜像
$ docker image ls --filter dangling=true
$ docker image prune
Docker 目前支持的如下过滤器:
dangling : 可以指定true或者false,来过滤悬虚镜像
before:需要镜像名称或者ID作为参数,返回在之前被创建的全部镜像
$ docker image ls --filter=before="9f38484d220f"
REPOSITORY TAG IMAGE ID CREATED SIZE
since:与before类似,可以返回镜像之后的创建的镜像
label:根据标注label的值或名称,对镜像过滤,如docker image ls 命令输出中不显示标注的内容。
reference:除上述过滤方式,都可以采用reference来过滤。
比如采用reference完成过滤并且仅显示标签为latest的示例
$ docker image ls --filter=reference="*:latest"
也可以采用format参数来通过对Go模板对输出内容进行格式化,例如只返回Docker主机上镜像大小属性
$ docker image ls --format "{{.Size}}"
# 或者只显示仓库,标签,和大小信息
$ docker image ls --format"{{.Repository}: {{.Tag}}: {{.Size}}"
# 或者采用更复杂的过滤,如用grep和awk命令。