在第一个笔记中我们已经说过了 Docker 三大核心概念, 其中镜像是最为重要的, 因为 Docker 运行容器前需要本地存在对应的镜像, 如果镜像没有保存在本地, Docker 会尝试从默认镜像仓库下载, 用户也可以通过配置, 使用自定义镜像仓库.
查询镜像
由于容器的创建需要镜像, 那么我们就先说说如何查询镜像
我们使用 docker search
命令可以搜索远程仓库共享的镜像.
例如
docker search nginx
//输出如下信息
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 6267 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker c... 1054 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable ... 392 [OK]
webdevops/php-nginx Nginx with PHP-FPM 82 [OK]
million12/nginx-php Nginx + PHP-FPM 5.5, 5.6, 7.0 (NG), CentOS... 77 [OK]
h3nrik/nginx-ldap NGINX web server with LDAP/AD, SSL and pro... 38 [OK]
bitnami/nginx Bitnami nginx Docker Image 30 [OK]
evild/alpine-nginx Minimalistic Docker image with Nginx 16 [OK]
funkygibbon/nginx-pagespeed nginx + ngx_pagespeed + openssl on docker-... 11 [OK]
webdevops/nginx Nginx container 8 [OK]
webdevops/php-nginx-dev PHP with Nginx for Development (eg. with x... 7 [OK]
blacklabelops/nginx Dockerized Nginx Reverse Proxy Server. 5 [OK]
1science/nginx Nginx Docker images that include Consul Te... 4 [OK]
frekele/nginx docker run --rm --name nginx -p 80:80 -p 4... 3 [OK]
ixbox/nginx Nginx on Alpine Linux. 3 [OK]
dock0/nginx Arch container running nginx 2 [OK]
xataz/nginx Light nginx image 2 [OK]
servivum/nginx Nginx Docker Image with Useful Tools 2 [OK]
drupaldocker/nginx NGINX for Drupal 2 [OK]
tozd/nginx Dockerized nginx. 1 [OK]
xutongle/nginx nginx http 1 [OK]
c4tech/nginx Several nginx images for web applications. 0 [OK]
unblibraries/nginx Baseline non-PHP nginx container 0 [OK]
funkygibbon/nginx nginx + openssl automated build, customisa... 0 [OK]
watsco/nginx nginx:1.11-alpine 0 [OK]
可以看到返回了很多包含关键字的镜像, 其中包括镜像名字, 描述, 星级(表示该镜像的欢迎程度), 是否官方创建, 是否自动创建.
注意: 默认的输出结果将按照星级评价进行排序.
用的人越多星级就越高, 所以我们如果不想查看低的星级怎么办呢?
我们可以通过 search
命令的参数-s, --stars=X
来进行指定.
docker search -s 300 nginx
//输出如下信息
Flag --stars has been deprecated, use --filter=stars=3 instead
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 6267 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker c... 1054 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable ... 392 [OK]
这样就会输出星级大于或等于300的镜像.
可以看到我们查询的镜像中的描述信息被截断显示了, 这样我们不是很方便了解这个镜像, 所以我们需要将所有的描述进行显示; 我们可以使用--no-trunc=true|false
来输出详细的描述信息.
docker search --no-trunc=true -s 300 nginx
//输出如下信息
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 6267 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker containers 1054 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable of pulling application code from git 392 [OK]
还有一个参数的作用是仅显示自动创建的镜像, --automated=true|false
当然我们也可以从 Docker Hub 网站搜索镜像
获取镜像
本笔记前面, 我们已经说过了, 容器运行前提需要本地存在对应的镜像, 如果本地没有保存镜像, 那么就需要在仓库下载.
可以使用docker pull
命令直接从 Docker Hub镜像源来下载镜像, 该命令的格式为docker pull NAME[:TAG]
.
其中, NAME 是镜像仓库的名称(用来区分镜像), TAG 是镜像的标签(往往用来表示版本信息). 通常情况下, 描述一个镜像需要包括 "名称+标签" 信息.
我们来实战获取一个镜像
docker pull centos:6.8
//输出如下信息
6.8: Pulling from library/centos
67f15db7c18f: Pull complete
Digest: sha256:37ee2dcd9a3a430136b566efb4aa1111ed332bfdef8b0de51a25d26891689fd7
Status: Downloaded newer image for centos:6.8
这样我们就已经下载下来了我们需要的镜像.
如果不显示指定 TAG, 则默认会选择 latest 标签, 这会下载仓库中最新版本的镜像.
docker pull centos
//输出如下信息
Using default tag: latest
latest: Pulling from library/centos
d5e46245fe40: Pull complete
Digest: sha256:aebf12af704307dfa0079b3babdca8d7e8ff6564696882bcb5d11f1d461f9ee9
Status: Downloaded newer image for centos:latest
下面的截图是我在 Docker Hub 查找的 CentOS 镜像截图, 方便大家理解.
可以看到有一个 TAG 为 latest 的.
注意: 一般来说, 镜像的 latest 标签意味着该镜像的内容会跟踪最新的非稳定版本而发布, 内容是不稳定的.
从稳定性上考虑, 不要在生产环境中忽略镜像的标签信息或使用默认的 latest 标签中的镜像.
我们再下载一个镜像 ubuntu 镜像
docker pull ubuntu
//输出如下信息
Using default tag: latest
latest: Pulling from library/ubuntu
75c416ea735c: Pull complete
c6ff40b6d658: Pull complete
a7050fc1f338: Pull complete
f0ffb5cf6ba9: Pull complete
be232718519c: Pull complete
Digest: sha256:a0ee7647e24c8494f1cf6b94f1a3cd127f423268293c25d924fbe18fd82db5a4
Status: Downloaded newer image for ubuntu:latest
下载过程中可以看出, 镜像文件一般由若干层(layer)组成, 75c416ea735c这样的串是层的唯一 id(实际上完整的 id 包括256比特, 由64个十六进制字符串组成).
使用 docker pull
命令下载时会获取输出镜像的各层信息. 当不同的镜像包括相同的层时, 本地仅存储,层的一份内容, 这样减少了需要的存储空间.
我们查询镜像的时候发现, 查询出了很多镜像
docker search -s 300 nginx
//输出如下信息
Flag --stars has been deprecated, use --filter=stars=3 instead
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 6267 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker c... 1054 [OK]
richarvey/nginx-php-fpm Container running Nginx + PHP-FPM capable ... 392 [OK]
例如jwilder/nginx-proxy, jwilder 属于用户名, nginx-proxy 属于镜像名.
当你想将这些镜像全部下载下来的时候, 可以使用-a
参数, 来下载我们查询到的所有镜像.
docker pull -a ubuntu
查看镜像信息
当我们电脑上的镜像越来越多的时候, 我们怎么能知道我们的本地主机上有多少镜像呢? 我们可以使用docker images
命令来列出本地主机上的所有镜像信息.
docker images
//输出如下信息
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest d355ed3537e9 4 days ago 119 MB
hello-world latest 1815c82652c0 10 days ago 1.84 kB
centos latest 3bee3060bfc8 2 weeks ago 193 MB
centos 6.8 0cd976dc0a98 9 months ago 195 MB
REPOSITORY: 来自于哪个仓库, 比如centos仓库用来保存centos系列的基础镜像.
TAG: 镜像的标签信息, 比如6.8 latest用来标注不同的版本信息. 标签只是标志, 并不能标识镜像内容.
IMAGE ID: 镜像的 ID.
CREATED: 创建时间
SIZE: 镜像大小, 优秀的镜像往往体积都非常小.
images
命令支持的参数
-a, --all=true|false: 显示所有图像(默认不显示中间图像图层). 默认值为false
--digests=true|false: 显示镜像摘要. 默认值为false.
还有其它的 大家可以使用docker images --help
或 man docker-images
命令查看
使用 inspect 命令查看详细信息
使用docker inspect
命令可以获取该镜像的详细信息, 包括制作者 适应架构 各层的数字摘要等.
docker inspect centos:6.8
//输出信息
[
{
"Id": "sha256:0cd976dc0a9881f77d054ca36c8700c3d66ac77121a1869ad8223a53edf123e9",
"RepoTags": [
"centos:6.8"
],
"RepoDigests": [
"centos@sha256:37ee2dcd9a3a430136b566efb4aa1111ed332bfdef8b0de51a25d26891689fd7"
],
"Parent": "",
"Comment": "",
"Created": "2016-08-30T18:20:34.565935321Z",
"Container": "4a66b6a87804820f367b575e18d52e7227b8d3cb40fbe55e05871b70bd091641",
"ContainerConfig": {
"Hostname": "75ac91db8d44",
"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 [\"/bin/bash\"]"
],
"Image": "sha256:bfcabb206d5af74961b49d4584c4b16ef3658b05d5c969ed0f038a5c49d3296f",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"build-date": "2016-06-02",
"license": "GPLv2",
"name": "CentOS Base Image",
"vendor": "CentOS"
}
},
"DockerVersion": "1.12.1",
"Author": "The CentOS Project <cloud-ops@centos.org>",
"Config": {
"Hostname": "75ac91db8d44",
"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/bash"
],
"Image": "sha256:bfcabb206d5af74961b49d4584c4b16ef3658b05d5c969ed0f038a5c49d3296f",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"build-date": "2016-06-02",
"license": "GPLv2",
"name": "CentOS Base Image",
"vendor": "CentOS"
}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 194545356,
"VirtualSize": 194545356,
"GraphDriver": {
"Name": "devicemapper",
"Data": {
"DeviceId": "7",
"DeviceName": "docker-253:1-256921-57c4711bc6f1fbc6d91e79ffa7e1428bd57c55001d905d7734a7e028dddd5f81",
"DeviceSize": "10737418240"
}
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:b1b065555b8aba5ae83d5d59d611a6b0cc470e9c14b7e4bee081398309e474a5"
]
}
}
]
如果我们只要其中一项内容时, 可以使用-f
来指定, 例如,获取镜像的Architecture:
docker inspect centos:6.8 -f {{".Architecture"}}
//输出信息
amd64
**使用 history 命令查看镜像历史
既然镜像由多个层组成, 那么怎么知道各个层的具体内容是什么呢? 可以使用history
命令, 该命令列出各个层的创建信息.
docker history centos:6.8
//输出信息
IMAGE CREATED CREATED BY SIZE COMMENT
0cd976dc0a98 9 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
<missing> 9 months ago /bin/sh -c #(nop) LABEL name=CentOS Base ... 0 B
<missing> 9 months ago /bin/sh -c #(nop) ADD file:beeefa390db7bc0... 195 MB
<missing> 9 months ago /bin/sh -c #(nop) MAINTAINER The CentOS P... 0 B
删除镜像
使用 docker rmi
命令可以删除镜像, 命令格式为docker rmi IMAGE [IMAGE...]
, 其中IMAGE可以为标签或 ID.
docker rmi ubuntu:latest
//输出信息
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:a0ee7647e24c8494f1cf6b94f1a3cd127f423268293c25d924fbe18fd82db5a4
Deleted: sha256:d355ed3537e94e76389fd78b77241eeba58a11b8faa501594bc82d723eb1c7f2
Deleted: sha256:dd864b96a38e849779c42a04159bbb39c7ab47253bf222049b471d8f26b60d14
Deleted: sha256:80e85c818fa0447c96a42501ca7457ad83e5834aa76f22c366342106889b7411
Deleted: sha256:11a2a269cf6ec2cefcb4e24370b8b2d7a4875450bafd3a70bd42eb787481d798
Deleted: sha256:1118f33a0ee7a874a04318248a886b2bdaf44cba286644ab7ded870aefe64b62
Deleted: sha256:cb11ba6054003d39da5c681006ea346e04fb3444086331176bf57255f149c670
创建镜像
创建镜像的方法主要有三种: 基于已有镜像的容器创建 基于本地模板导入 基于 Dockerfile 创建
基于已有镜像的容器创建
该方法主要是使用 docker commit
命令. 命令格式为 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
主要选项包括:
-a, --author="": 作者信息.
-c, --change=[]: 提交的时候执行 Dockerfile 指令, 包括 CMD|ENTRYPOINT|ENV|EXPOSE|LABEL|ONBUILD|USER|VOLUME|WORKDIR等.
-m, --message="": 提交消息
-p, --pause=true: 提交时暂停容器运行.
我们使用centos 来创建或启动一个容器, 并在容器中创建一个文件夹之后推出
docker run -it centos:6.8
[root@080ce2211b8a /]# mkdir test
[root@080ce2211b8a /]# exit
此刻该容器跟原 centos:6.8 镜像相比, 已经发生改变, 可以使用docker commit
命令来提交为一个新的镜像.
docker commit 的语法格式为:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
容器名是 启动容器时通过--name
所指定
容器ID是 root@080ce2211b8a
中的 080ce2211b8a
docker commit \
> --author "作者" \
> --message "说明" \
> 080ce2211b8a \
> test:0.1
sha256:bfc1e916eb6e787afab5be9e3b25ea29e799d2bcd7b461e22d666b0ec406606a
顺利的话, 会返回新创建的镜像的 ID 信息, 例如bfc1e916eb6e787afab5be9e3b25ea29e799d2bcd7b461e22d666b0ec406606a
基于本地模板导入
用户也可以直接从一个操作系统模板文件导入一个镜像, 主要使用 docker import
命令. 命令格式为 docker import [OPTIONS] file|URL|-[REPOSITORY[:TAG]]
要直接导入一个镜像, 可以使用 OpenVZ 提供的模板来创建, 或者用其他已导出的镜像模板来创建.
例如, 下载了 ubuntu-14.04 的模板压缩包, 之后使用以下命令导入:
$ cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - ubuntu:14.04
然后查看新导入的镜像, 会发现她们已经在本地存在了.
导出和导入镜像
用户可以使用 docker save
和 docker load
命令来导出和导入镜像.
docker save -o ubuntu_14.04.tar ubuntu:14.04
docker load --input ubuntu_14.04.tar
或:
docker load < ubuntu_14.04.tar
上传镜像
可以使用 docker push
命令上传镜像到仓库, 默认上传到Docker Hub官方仓库.
docker push NAME[:TAG] | [REGISTRY_HOST[:REGISTRY_PORY]/]NAME[:TAG]
在第一次上传时, 会提示输入登录信息或进行注册.