声明:所有的实验示例大部分来自《learn-docker-in-a-month-of-lunches》的作者Elton Stoneman,但运行结果并不都是照搬,大部分实验结果可能与原书不同
一、前言
前面几节讲述了如何去创建镜像和容器,现在是时候讲述如何将镜像上传到Image Registry(镜像仓库)了,但千万不要认为上传镜像是一件随便的事,所以本节将会讲述如何标准的给镜像打标签,如何上传镜像到镜像仓库(公有或者私有,云端或者本地)以及如何正确使用镜像等内容。
二、镜像标签命名规则
-
镜像仓库?
镜像仓库就是一个集中存储镜像的服务器,当然并不是直接存储镜像啦,而是像本地缓存镜像一样,存储的是镜像层。Docker Hub是目前最流行的镜像仓库,并且也是默认的镜像仓库,如果用户上传是未在标签指定镜像仓库,则默认上传到Docker Hub,同样地,如果用户下拉镜像时,没有指定下拉地址,则默认从Docker Hub中下拉。 -
镜像标签解析
docker.registry.local:5000/gallery/ui:1.0.0 docker.io/snmutsuki/registry:latest
上述两个标签里
docker.registry.local:5000
和docker.io
都是镜像仓库的地址,区别在于前者是本地的仓库,后者是Docker Hub的地址且可以省略
gallery
和snmutsuki
一般是组织名字或者用户名
ui
和registry
则是你定义的镜像名字(Docker Hub上为仓库,其实也可以理解为镜像,一个仓库一个种类的镜像)
1.0.0
和latest
为镜像的版本标签,后者是默认的,可以不加,前者是通用的版本号。注意,版本标签实际上可以是任何字符 -
通用版本号的命名规则
major release : minor version : patch number
1.2.3
patch number主要是和补丁相关的版本号,如果该项目修复了bug或者打了补丁(没有大的影响的)则增加该版本号
minor version的增加表示该项目添加了新的功能和特点
major release的增加表示该项目发生了极大的变化
- 更高效的指定版本号
- 问题:
如果有这么一个镜像标签testUserName/testRep:2.1.0
,该镜像比2.0版本添加了新的功能但存在很多潜在bug,某位用户正好需要2.1版本添加的新功能,随后他在他的Dockerfile中指定了该镜像的2.1.0版本。刚写完他发现一个问题,2.1.0版本可能存在比较多的bug,如果将来bug修复了,他将不得不修改他的Dockerfile以重新指定版本。那么如何解决这个问题呢? - 解决方案:为同一个镜像指定多个版本标签,比如2.1.3发布了,便给这个镜像同时指定2.1.3、2.1、2、latest四个标签,这样用户只要在他的Dockerfile中指定版本号2.1就可以了,因为此时的2.1版本对应的就是2.1.3版本。
- 问题:
三、上传镜像到Docker Hub
- 注册Docker Hub账号
- 本地使用
docker login
命令登录你的Docker Hub账号 - 以上节的diamol/registry为例,重新给该镜像的标签命名
$ docker image tag diamol/registry snmutsuki/registry:1.0.0
注意:
docker image tag
是重新给镜像打标签的命令,该命令并不会删除源镜像标签,源镜像标签与重新命名的标签都会存在,只是它们拥有同一个镜像ID
- push你的镜像到Docker Hub
$ docker image push snmutsuki/registry:1.0.0
如果你发现你的镜像修改后,每次上传需要的时间都很久,你得好好考虑一下Dockerfile的问题了。
其实你也可以手动在Docker Hub上创建仓库。
如果直接用命令push的话,对于不存在的仓库,Docker Hub将会自动为你创建
-
在Docker Hub上查看你的镜像
docker-hub
左下角Tags是该镜像的版本标签,左上角显示所在的镜像仓库
四、创建本地的镜像仓库(基于容器)
- 下拉Elton Stoneman制作的镜像,当然你也可以自己下拉dockr维护在github上的registry服务的代码(docker/distribution)并自己制作一个镜像
$ docker container run --detach --publish 5000:5000 diamol/registry
registry服务默认端口是5000
- 这一步你当然可以选择直接给你的镜像打标签为
localhost:5000/xxx/xxx:xxx
,然后push,但是这样会出现一个问题,这个镜像和localhost绑定啦!不管怎么弄,它都只会寻找上传镜像的那台机器的本地仓库,本次我们以前述的docker.registry.local:5000/gallery/ui:1.0.0
来作为例子,去解决这个问题。假设我们现在有docker.registry.local:5000/gallery/ui:1.0.0
镜像,如何把它正确上传到本地的镜像仓库呢,假设本地镜像仓库地址为172.0.0.1(这是本机地址,使用它仅仅是为了方便讲解) - 修改host文件
- windows
$ echo "`n127.0.0.1 docker.registry.local" >> C:\Windows\System32\drivers\etc\hosts
- Linux
$ echo "\n127.0.0.1 docker.registry.local" >> /etc/hosts
- ping测试
$ ping docker.registry.local
正在 Ping docker.registry.local [127.0.0.1] 具有 32 字节的数据:
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=64
ping测试通过
- 离成功解决问题还差一步,现在出现了一个新问题,该本地仓库使用的是Http协议去上传和下拉镜像,而不是加密的Https协议,而Docker默认是不会与使用Http协议的仓库进行通讯的,所以我们的镜像还是上传不了,但是Docker提供一个非安全仓库白名单的设置,我们可以将我们这个仓库注册在这个白名单里
-
Windows用户直接在任务栏中右击Docker图标 -> settings -> Daemon在Insecure registries中按提示填写你本地仓库的信息
Insecure-registries.PNG - Linux用户需要修改/etc/docker/daemon.json(如果没有该文件,请自行创建),并添加以下条目,如果是新创建的记得首尾加上大括号(毕竟是Json格式的文件啊)
"insecure-registries" : [
"docker.registry.local:5000"
]
- 重启Docker
- windows右键Docker图标 -> restart
- Linux
$ systemctl restart docker
- 查看设置是否应用
$ docker info
...
Insecure Registries:
docker.registry.local:5000
127.0.0.0/8
...
- 上传你的镜像(记得重启一下你的容器哦,因为重启了Docker)
五、其他
- 请注意Docker Hub是一个开放的平台,任何人都可以在上面上传或者下载镜像,所以你得小心非法之徒放一些不安全的东西在上面,最好的做法是使用官方的镜像
- 使用本地仓库时,如何查看本地仓库拥有的镜像?
GET /v2/_catalog
//powershell
$ curl.exe -X GET "Http://docker.registry.local:5000/v2/_catalog"
{"repositories":["gallery/api","gallery/logs","gallery/ui"]}
- 使用本地仓库时,如何查看指定镜像的所有版本号
GET /v2/<imageName>/tags/list
//powershell
$ curl.exe -X GET "http://docker.registry.local:5000/v2/gallery/ui/tags/list"
{"name":"gallery/ui","tags":["v1"]}
- 使用本地仓库时,如何删除指定的镜像?
- 找到要删除的镜像的Digest
GET /v2/<imageName>/manifests/<versionTag>
//powershell $ curl.exe --head ` http://docker.registry.local:5000/v2/gallery/ui/manifests/v1 ` -H "Accept:application/vnd.docker.distribution.manifest.v2+json" HTTP/1.1 200 OK Content-Length: 1364 Content-Type: application/vnd.docker.distribution.manifest.v2+json Docker-Content-Digest: sha256:4060ff398874fa42b1b575e58d321b3554aa54541a63613bdc274835934a71a7 Docker-Distribution-Api-Version: registry/2.0 Etag: "sha256:4060ff398874fa42b1b575e58d321b3554aa54541a63613bdc274835934a71a7" X-Content-Type-Options: nosniff Date: Mon, 13 Jan 2020 09:27:27 GMT
- 删除镜像
DELETE /v2/<imageName>/manifests/<digest>
//powershell $ curl.exe -X DELETE "http://docker.registry.local:5000/v2/gallery/ui/manifests/sha256:4060ff398874fa42b1b575e58d321b3554aa54541a63613bdc274835934a71a7"
参考文档:
[1] learn-docker-in-a-month-of-lunches
[2] 官方文档
附:
[1] Elton Stoneman的github项目
网友评论