赞
踩
远程镜像仓库
Docker Hub分为官方仓库和非官方仓库
本地镜像仓库
// 搜索带 nginx 关键字的镜像 $ docker search nginx NAME DESCRIPTION STARS OFFICIAL AUTOMATED nginx Official build of Nginx. 16924 [OK] linuxserver/nginx An Nginx container, // 搜索官方提供的带 nginx 关键字的镜像 $ docker search --filter=is-official=true nginx NAME DESCRIPTION STARS OFFICIAL AUTOMATED nginx Official build of Nginx. 16924 [OK] // 搜索所有收藏数超过4的带 nginx 关键字的镜像 $ docker search --filter=stars=4 nginx // 搜索自动创建的仓库(镜像) $ docker search nginx --filter "is-automated=true"
可以看到返回了很多包含关键字的镜像,其中
默认的输出结果将按照星级评价进行排序。
默认值只返回前25行,可以通过--limit
参数来增加内容行数,最多100行
使用 docker images 或 docker image ls 命令可以列出本地主机上已有镜像的基
本信息。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
gb28181 latest e2bb49fceade 6 hours ago 880MB
images 子命令主要支持如下选项:
可以通过–format参数来过滤docker image ls
的输出内容。
(1)仅显示镜像的大小属性:
$ docker image ls --format "{{.Size}}"
880MB
880MB
(2)仅显示镜像的仓库和标签属性:
$ docker image ls --format "{{.Repository}}:{{.Tag}}"
gb28181:latest
可以通过–filter参数来过滤docker image ls
的输出内容。其支持的过滤器如下
(1)仅显示标签为latest的镜像
docker image ls --filter=reference="*:latest"
REPOSITORY TAG IMAGE ID CREATED SIZE
gb28181 latest e2bb49fceade 6 hours ago 880MB
(2)仅会显示悬虚镜像
$ docker image ls --filter dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 5d1686b1730f 6 months ago 880MB
那什么叫做悬虚镜像呢?
<none:none>
移除全部的悬虚镜像(这个命令没有起作用):
$ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
使用docker image inspect命令可以获取该镜像的详细信息,包括制作者、适应
架构、各层的数字摘要等:
$ docker image inspect ubuntu
[
{
"Id": "sha256:27941809078cc9b2802deb2b0bb6feed6c236cde01e487f200e24653533701ee",
"RepoTags": [
"myubuntu:lastest",
"ubuntu:latest"
],
"RepoDigests": [
"ubuntu@sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac"
上面代码返回的是一个 JSON 格式的消息,如果我们只要其中一项内容时,可以使用f 来指定,例如:
docker image inspect -f {{".Metadata"}} ubuntu
既然镜像文件由多个层组成,那么怎么知道各个层的内容具体是什么呢?这时候可以使
用 history 子命令,该命令将列出各层的创建信息。
$ docker image history ubuntu
IMAGE CREATED CREATED BY SIZE COMMENT
27941809078c 34 hours ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 34 hours ago /bin/sh -c #(nop) ADD file:11157b07dde10107f… 77.8MB
注意,过长的命令被自动截断了,可以使用–no-trunc选项来输出完整命令
docker image history ubuntu --no-trunc
:
分隔)从拉取镜像的命令格式如下:
docker image pull <repository>:<tag>
(1)从官方仓库拉取镜像实例:
$ docker image pull ubuntu:18.04 // 从官方ubuntu库中拉取标签为18.04的镜像
$ docker image pull ubuntu:latest // 从官方ubuntu库中拉取标签为latest的镜像
$ docker image pull ubuntu // 从官方ubuntu库中拉取标签为latest的镜像
注意:
下载过程中可以看出,镜像文件一般由若干层 (layer) 组成, 6c953ac5d795 这样的
串是层的唯一 id (实际上完整的 id 包括 256 比特, 64 个十六进制字符组成)。使用 docker pull 命令下载中会获取并输出镜像的各层信息。当不同的镜像包括相同的层时,本地仅存储了层的一份内容,减小了存储空间。
(2) 从非官方仓库拉取镜像
docker pull docker hub账户名/仓库名:镜像名
(3) 从第三方镜像仓库服务中拉取镜像
docker pull 第三方镜像仓库服务地址/docker hub账户名/仓库名:镜像名
pull 子命令支持的选项主要包括:
关于-a
选项:一个镜像可能有多个标签,我们可以用docker image pull -a
参数来拉取仓库中的全部镜像
docker image pull -a <repository>
另外,有时需要使用镜像代理服务来加速 Docker镜像获取过程,可以在 Docker 服务
启动配置中增加 --registry-mirror==proxy_URL 来指定镜像代理服务地址
下载镜像到本地后,即可随时使用该镜像了,例如利用该镜像创建一个容器,在其中运
行 bash 应用,执行打印 “Hello World" 命令:
问题:如果有两个镜像,它们的标签和名字都是一样的,但是内容不一样,怎么区分它们呢?
答案
通过摘要区别,每一个镜像都有一个摘要,只要镜像内容变更了散列值一定会改变。
每次拉取镜像时会有有一个摘要作为返回值。
也可以通过如下命令在本地查看摘要:
$ docker image ls --digests ubuntu
$ docker image pull ubuntu@sha256:b6b83d3c331794420340093eb706a6f152d9c1fa51b262d9bf34594887c2c7ac
为了方便在后续工作中使用特定镜像,还可以使用 docker tag 命令来为本地镜像任
意添加新的标签。例如,添加一个新的 myubun七u:la七 es 七镜像标签:
docker tag ubuntu:latest myubuntu:latest
再次使用 docker images 列出本地主机上镜像信息,可以看到多了一个 myubuntu:latest的镜像:
可以看到,这些镜像的 ID是一样的,它们实际上指向了同一个镜像文件,只是别名不同而已。 docker tag命令添加的标签实际上起到了类似链接的作用。
删除操作会在当前主机上删除该镜像以及相关的镜像层,这意味着无法通过docker image ls命令查看删除后的镜像(它只能看本机仓库的),并且对应的包含镜像层数据的目录会被删除
$ docker rmi myubuntu:latest
Untagged: myubuntu:latest
当使用 docker rmi 命令,并且后面跟上镜像的 ID (也可以是能进行区分的部分 ID 串前缀)时,会先尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。
注意,当有该镜像创建的容器存在时,镜像文件默认是无法被删除的,看个例子:
(1) 先启动一个容器
$ docker run ubuntu:latest echo 'hello'
hello
(2)使用 docker ps -a 命令可以看到本机上存在的所有容器:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1cc612923b2a ubuntu:latest "echo hello" 6 seconds ago Exited (0) 5 seconds ago
可以看到,后台存在一个退出状态的容器,是刚基于ubuntu:latest镜像创建的。
(3)试图删除该镜像, Docker 会提示有容器正在运行,无法删除:
$ docker rmi ubuntu
Error response from daemon: conflict: unable to remove repository reference "ubuntu" (must force) - container 1cc612923b2a is using its referenced image 27941809078c
如果要想强行删除镜像,可以使用-f
参数:
$ docker rmi -f ubuntu
注意,通常并不推荐使用-f参数来强制删除一个存在容器依赖的镜像。正确的做法是,先删除依赖该镜像的所有容器,再来删除镜像。
(1)先删除容器
$ docker rm 1cc612923b2a
1cc612923b2a
(2)再删除镜像
$ docker rm 27941809078c
删除全部镜像
可以在docker image rm
命令中传入当前系统的全部镜像ID,可以通过docker image ls -q
获取全部镜像ID
# 停止所有容器 docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker stop # 删除所有容器 docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm # 删除异常停止的docker容器 docker rm `docker ps -a | grep Exited | awk '{print $1}'` # 可以删除所有名字中带 “none” 关键字的镜像 docker rmi $(docker images | grep "none" | awk '{print $3}') # 删除所有镜像 docker image rm $(docker image ls -q) -f # 删除所有镜像 docker rmi `docker images -q`
在 Docker 中删除 image 时有时会遇到类似
Error response from daemon: conflict: unable to delete 6ec9a5a0fc9f (cannot be forced) - image has dependent child images
这样的错误,是因为镜像有从属关系,因为当前镜像是其他镜像的创建底层。而且这个镜像在容器里面还在运行。
解决:
docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=xxxxxx)
其中 xxxxxx 是报错 image 的 id,在文章开头的例子中就是 6ec9a5a0fc9f。从列表中查找到之后就可以核对并删除这些 image。
docker rm REPOSITORY:TAG
原因:IMAGE ID为7042885a156a的nginx指向两个repository,所以删除失败了
解决:指定repository和tag删除
docker rmi xxx:rag
一般来说产生这个报错是因为启动的容器是被docker export出来的镜像
[root@dockertest container]# docker run --name nginx-import-test -d -p 4000:80 nginx-import-test:1.0
docker: Error response from daemon: No command specified.
See 'docker run --help'.
被docker export出来的镜像在启动的时候需要指定command,例如我启动上述nginx容器,需要指定Command
Command可以通过下面命令查询到:
$ docker ps -a --no-trunc
查询到Command之后,运行容器:
docker run --name nginx-import-test -d -p 4000:80 nginx-import-test:1.0 /docker-entrypoint.sh nginx -g 'daemon off;
容器就正常启动了
比如,如下命令会自动删除临时的遗留镜像文件层,最高提示是否的存储空间:
$ docker image prune -f
....
Total reclaimed space: ...
镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础。当我们使用Docker Hub的镜像无法满足我们的需求时,我们就需要自己定制镜像来满足我们的需求。
创建镜像的方法主要有三种:
docker commit 语法格式:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
实例
(1)启动一个镜像,并在其中做一些修改:
$ docker run -it ubuntu /bin/bash
root@944848df736f:/$ touch test
root@944848df736f:/$ exit
注意,容器的ID为944848df736f
(2)此时容器已经和原来的镜像由一些改变,可以使用docker commit将之提交为一个新的镜像:
$ docker commit --author "oceanstar" --message "add a new file" 944848df736f test:0.1
sha256:b33d05e3bc50856da633dda7982067b5934e8eb96298129daeb50bb88b4cc5c7
顺利的话,会返回新创建镜像的 ID 信息
(3)此时查看本地镜像列表,会发现新创建的镜像已经存在了:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test 0.1 b33d05e3bc50 About a minute ago 77.8MB
实例二
如下命令会用 nginx:1.11 镜像启动一个容器,命名为 webServer,并且映射了80 端口,这样便可以去访问这个 nginx 服务器。然后我们直接访问宿主机的IP可以看到Nginx的欢迎页面
[root@server ~]# docker run --name webServer -d -p 80:80 nginx:1.11 #启动一个容器,基于docker hub上面的nginx:1.11镜像
现在,假设我们不喜欢这个欢迎页面,我们喜欢改成别的文字,我们可以使用docker exec 命令进入到容器,修改其内容给
root@714830c04e5e:/# echo '<h1>Hello Docker Nginx Server</h1>' >/usr/share/nginx/html/index.html #修改默认首页的内容
root@714830c04e5e:/# exit
exit
已交互式终端方式进入 webServer 容器,并执行了 bash命令, 也就是获得了一个可操作的shell。然后覆盖了index.html内容,再次刷新浏览器,会发现内容被改变了。
修改了容器的文件,也就是改动了容器的存储器,可以通过 docker diff 命令查看具体的改动
[root@server ~]# docker diff webServer #查看webServer容器改动的内容
现在我们定制好了变化,我们希望能将其保存下来形成镜像。要知道,当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储器里。而Docker提供了一个 docker commit 命令,可以将容器的存储层保存下来称为镜像。也就是说在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们在运行这个新镜像的时候,就会拥有原有容器最后的文件变化。
示例将上面更改首页的webServer 容器保存为镜像:
[root@server ~]# docker commit \
--author "Bu Ji <381347268@qq.com>" \
--message "修复了默认首页" \
webServer \
nginx:v1
........
[root@server ~]# docker images nginx #查看制作完成的nginx镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 b639fbcc5ec4 2 minutes ago 183MB
nginx 1.11 5766334bdaa0 21 months ago 183MB
其中 --author 是指定修改的作者,而 --message 则是记录本次修改的内容。这点和 git 版本控制器相似。还可以使用 docker history 具体查看镜像内的历史记录
[root@server ~]# docker history nginx:v1 #查看nginx:v1镜像的历史记录
新的镜像定制好后,我们来运行这个镜像
[root@server ~]# docker run --name web1 -d -p 81:80 nginx:v1 #基于上面新建的nginx:v1启动一个名字为web1的容器
当我们访问宿主机IP:81时候,其内容和之前修改后的 webServer一样
至此,完成了一个定制镜像,使用的是 docker commit 命令,手动给旧的镜像添加了新的一层,形成了新的镜像,对镜像多层存储应该有了很直观的感受。
慎用 docker commit
使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中很少这样使用。
要直接导入一个镜像,可以使用 OpenVZ 提供的模板来创建,或者用其他已导出的镜像模板来创建。 OPENVZ 模板的下载地址为http://openvz.org/Download/templates/pr,ecr~ated。
例如,下载了 ubuntu-18.04 的模板压缩包,之后使用以下命令导入即可:
基于 Dockerfile 创建是最常见的方式。 Dockerfile 是一个文本文件,利用给定的指令描述基于某个父镜像创建新镜像的过程。
步骤:
如果要导出镜像到本地文件,可以使用 docker [image] save 命令。该命令支持-o 、 -output string 参数,导出镜像到指定的文件中。
可以使用 docker [image] load 将导出的七 ar 文件再导入到本地镜像库。支持-i、一input string
选项,从指定文件中读入镜像内容。
这将导入镜像以及相关的元数据信息(包括标签)。导入成功后,可以使用docker images命令进行查看,和原镜像一致。
可以使用 docker [image] push 命令上
传镜像到仓库,默认上传到 Docker Hub 官方仓库(需要登录)
镜像是多层存储,每一层是在前一层的基础上进行的修改;而容器同样也是多层存储是在以镜像为基础层,在基础层上加一层作为容器运行时的存储层。
怎么验证
docker镜像由一些只读镜像层组成,如下图:
怎么查看某个镜像的分层呢?可以通过docker image pull
可以看出这个镜像包括5个镜像层,如下图:
也可以可以通过使用docker image inspect来查看分层信息
这些"24efXXXXXX"是镜像摘要
什么叫做镜像摘要:
问题:
怎么构建
在额外添加精选层的同时,镜像时钟是当前所有镜像的组合
所有镜像堆叠合并,对外提供统一的视图
docker通过存储引擎(新版本采用快照机制)的方式来实现镜像层堆栈,并保障多镜像层对外展示为统一的文件系统。linux上可用的存储引擎用AUFS、Device Mapper等。每种存储引擎都基于linux中对应的文件系统或者块设备技术。
怎么映射
docker在拉取镜像时,会先看看这一层是否在本地已经存在,如果存在,就不去拉取了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。