一般情况下,我们需要使用Docker镜像的时候,我们会去公共的镜像仓库,比如Docker Hub搜索并拉取到我们本地机器。但是实际开发中,公司内部通常都会自己搭建一个私有的Docker镜像仓库,用于存放公司内部开发的一些服务镜像,这些镜像是私有的,没经过授权的其他第三方机构或者个人开发者是没办法访问到的。
本篇文章记录了一次私有Docker镜像仓库的搭建过程。
1 准备工作
本篇文章所使用的软件环境:
本次搭建过程所使用的机器只有一台,操作系统:Ubuntu 16.04.4 LTS
;机器的IP(内网IP)为:10.200.0.206
;所有的操作都是在这台机器上进行。
机器上安装的Docker版本为1.12.3
;Docker-Compose版本为1.9.0-rc4
2 搭建Docker私有镜像仓库
从Docker Hub上拉取registry
镜像到本地(retistry
是Docker官方提供的一个用于搭建镜像仓库的Docker镜像):1
docker pull registry
编辑docker-compose.yml
文件,增加以下内容:1
2
3
4
5
6
7
8
9# Docker私有仓库@10.200.0.206:5000
registry:
image: registry:latest
container_name: registry
ports:
- '5000:5000'
volumes:
- '/docker/volumes/registry:/var/lib/registry'
restart: always
在10.200.0.206
机器上创建一个目录/docker/volumes/registry
作为registry
的数据卷,并映射到容器中的/var/lib/registry
目录。执行下面的指令运行registry
:1
docker-compose up -d registry
运行成功后,我们可以另外找一台机器,然后从Docker Hub上找一个镜像,比如redis,拉取下来:1
docker pull redis
然后给本地的redis镜像打tag并push到我们创建的私有镜像仓库(10.200.0.206:5000
)中:1
2docker tag redis 10.200.0.206:5000/redis
docker push 10.200.0.206:5000/redis
注意:在执行docker push
指令的时候,有可能会报错:
The push refers to a repository [10.200.0.206:5000/redis]
Get https://10.200.0.206:5000/v1/_ping: http: server gave HTTP response to HTTPS client
错误原因:
Docker Registry默认将仓库的访问方式设置成HTTPS。
解决办法:
在执行docker push
指令的机器上(有可能是10.200.0.206
机器,也有可能是其他执行docker push
指令的机器),编辑/etc/docker/daemon.json
文件,将私有仓库地址10.200.0.206:5000
添加到insecure-registries
列表中,设置此仓库使用HTTP而不是HTTPS:1
2
3
4
5{
"insecure-registries": [
"10.200.0.206:5000"
]
}
编辑完/etc/docker/daemon.json
文件后,重启Docker即可解决:1
service docker restart
以上,我们已经搭建了一个私有Docker镜像仓库10.200.0.206:5000
并成功将redis
镜像push到该仓库中。现在我们从该私有仓库拉取redis
镜像来验证一下:1
2
3
4
5
6
7docker pull 10.200.0.206:5000/redis
... 输出的日志信息 ...
Using default tag: latest
latest: Pulling from redis
Digest: sha256:4b3351a079109964b63558c9ff1122ca8e0446992dba1ea6209e01a719818e7c
Status: Downloaded newer image for 10.200.0.206:5000/redis:latest
从输出的日志看,我们已经成功往新创建的私有仓库push镜像,并成功从新创建的私有仓库中pull镜像。我们也可以使用指令来查看私有仓库中有哪些镜像:1
2
3
4curl 10.200.0.206:5000/v2/_catalog
... 输出的日志信息 ...
{"repositories":["redis"]}
可以看到我们的私有镜像仓库里面只有一个我们之前push上去的redis镜像。
3 为私有镜像仓库配置基本的安全认证
上面搭建的私有Docker Registry
是没有任何访问的认证的,任何能访问到10.200.0.206
主机的人都可以访问到该仓库。现在我们为私有仓库加上最基本的安全认证:用户名/密码认证。只有拥有正确用户名和密码的人才能够访问我们的私有仓库。
首先,创建一个存储密码的文件:用户名设置为test
,密码设置为123456
;我们这里将密码文件创建在宿主机的数据卷/docker/volumes/registry/auth
目录下面:1
2cd /docker/volumes/registry && mkdir auth
docker run --entrypoint htpasswd registry:latest -Bbn test 123456 > auth/htpasswd
然后,修改docker-compose.yml
文件,增加以下配置:
密码认证数据卷映射:/docker/volumes/registry/auth:/auth
三个环境变量:REGISTRY_AUTH: "htpasswd"
、REGISTRY_AUTH_HTPASSWD_REALM: "Registry Realm"
和REGISTRY_AUTH_HTPASSWD_PATH: "/auth/htpasswd"
修改后完整的docker-compose.yml
文件内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14# Docker私有仓库@10.200.0.206:5000
registry:
image: registry:latest
container_name: registry
ports:
- '5000:5000'
volumes:
- '/docker/volumes/registry:/var/lib/registry'
- '/docker/volumes/registry/auth:/auth'
environment:
REGISTRY_AUTH: "htpasswd"
REGISTRY_AUTH_HTPASSWD_REALM: "Registry Realm"
REGISTRY_AUTH_HTPASSWD_PATH: "/auth/htpasswd"
restart: always
最后,删除并重启registry
容器:1
docker-compose stop registry && docker-compose rm -f registry && docker-compose up -d registry
验证验一下:push镜像&pull镜像1
2
3
4
5
6
7
8
9
10
11
12
13
14// push镜像
docker tag mongo:3.6.5 10.200.0.206:5000/mongo:3.6.5
docker push 10.200.0.206:5000/mongo:3.6.5
The push refers to a repository [10.200.0.206:5000/mongo]
e7ade1faa3c1: Preparing
ee7790e59fb6: Preparing
no basic auth credentials
// pull镜像
docker pull 10.200.0.206:5000/redis
Using default tag: latest
Pulling repository 10.200.0.206:5000/redis
Error: image redis:latest not found
执行上面的指令的时候,没有加任何认证,所以无法进行操作。下面我们加上用户名密码认证:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27// 先使用docker login指令登录私有仓库:输入之前设置的用户名和密码
docker login 10.200.0.206:5000
Username: test
Password:
Login Succeeded
// 然后push镜像
docker tag mongo:3.6.5 10.200.0.206:5000/mongo:3.6.5
docker push 10.200.0.206:5000/mongo:3.6.5
The push refers to a repository [10.200.0.206:5000/mongo]
be6db55356c7: Pushed
70c679c30be9: Pushed
d13240d3c0f5: Pushed
d26400fed10f: Pushed
e8f7461e1ac9: Pushed
a4b62bfb1dd5: Pushed
662627a7978c: Pushed
0a96e0010225: Pushed
76ffda9e0d20: Pushed
8fd847ca0bf3: Pushed
3.6.5: digest: sha256:c1f8087915888d17657d76bb0de74e3e7aaf090116892e1ed047221d46aedba6 size: 2407
// pull镜像
docker pull 10.200.0.206:5000/mongo:3.6.5
3.6.5: Pulling from mongo
Digest: sha256:c1f8087915888d17657d76bb0de74e3e7aaf090116892e1ed047221d46aedba6
Status: Downloaded newer image for 10.200.0.206:5000/mongo:3.6.5
以上结果说明,我们成功为私有镜像仓库添加了用户名/密码的认证!
注明:当我们使用docker login
指令登录私有仓库后,Docker会为我们保存用户名密码(默认存放在用户home目录下的.docker文件夹下:~/.docker/config.json
),这样就不需要我们每次push或pull镜像的时候都docker login
一下输入账号密码。
此时,我们再通过浏览器打开链接:http://10.200.0.206:5000/v2/_catalog
来查看仓库中的镜像,会提示我们输入用户名密码:
或者使用curl指定用户名密码进行访问:curl -u test:123456 http://10.200.0.206:5000/v2/_catalog
以上就是Docker私有镜像仓库的基本搭建过程,本文只用到了基本的用户名密码认证,更高级的例如HTTPS的配置请参考官方的文档!
——————–【参考文章】——————–