玩转Docker镜像仓库-Docker Registry及Harbor
作者:行百里er
博客:https://chendapeng.cn (opens new window)
提示
这里是 行百里er 的博客:行百里者半九十,凡事善始善终,吾将上下而求索!
# Docker镜像仓库
# 1 Docker Hub公共仓库
# 1.1 注册Docker账号
Docker Hub是Docker官方提供的公共仓库,需要我们注册一个Docker账号进行使用,注册地址:
https://hub.docker.com (opens new window)
# 1.2 客户端登录
本文操作均是在Linux环境下。
命令
docker login
# 1.3 push镜像到Docker Hub仓库
先看一下镜像列表:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx dev ae2feff98a0c 3 days ago 133MB
nginx latest ae2feff98a0c 3 days ago 133MB
2
3
4
就推送 nginx:dev
到仓库,命令如下:
docker push nginx:dev
然而这里会出现故障:
[root@localhost ~]# docker push nginx:dev
The push refers to repository [docker.io/library/nginx]
4eaf0ea085df: Preparing
2c7498eef94a: Preparing
7d2b207c2679: Preparing
5c4e5adc71a8: Preparing
87c8a1d8f54f: Preparing
denied: requested access to the resource is denied
2
3
4
5
6
7
8
拒绝了对资源的请求访问!
这是因为,推送镜像到官方仓库是有格式要求的,必须是如下格式:
docker push username/image_name:tag
所以,我们得先按照格式将镜像打个标签:
docker tag nginx:latest xblzer/nginx:v1
再看一下镜像:
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx dev ae2feff98a0c 3 days ago 133MB
nginx latest ae2feff98a0c 3 days ago 133MB
xblzer/nginx v1 ae2feff98a0c 3 days ago 133MB
2
3
4
5
此时再推送到仓库,命令如下:
docker push xblzer/nginx:v1
受网络限制,可能需要等待一段时间,push成功,会有如下提示:
推送成功会返回一个远程的版本,这里有一个hash值,表示已经推送成功了。
在Docker Hub上验证一下:
那么此时,就可以在别的服务器直接通过这个地址把它拉下来使用。
这对我们部署项目很有用,比如我们在很多的服务器直接docker pull
我们仓库中上传的镜像,就可以直接使用。
# 2 Docker Registry私有镜像仓库
实际操作中,推送镜像到公共仓库是很慢的,甚至需要推送多次才能推送成功,这不利于项目的持续集成和持续部署,一般我们不会使用公共仓库。
在实际成产环境中,可以搭建私有仓库使用,好处如下:
- 私有仓库在内网,比较安全
- 访问(上传/下载)速度快
- 方便管理
- 除了镜像管理以外,还可以用户管理
- 登录权限的管理等
# 2.1 Docker私有仓库工作原理
假设有一个docker客户端A,将本地运行的tomcat容器进过commit、push到私有仓库,客户端B便可以直接从私有仓库拉下来,在自己的客户端运行,客户端A与客户端B跑的容器环境是一样的。
# 2.2 搭建Docker-registry私有仓库
养成习惯,先进行 主机规划
准备两台虚拟机
搭建步骤
在 docker-registry
主机上运行:
1. docker search registry
2. docker pull registry
3. 运行容器
docker run -d -v /registry:/home/docker-registry -p 5000:5000 --restart=always --privileged=true --name registry registry:latest
Tip:可以不经过第1、2步,直接docker run
。
查看容器运行情况:
[root@docker-registry ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0e429bc1e3bf registry:latest "/entrypoint.sh /etc…" 9 seconds ago Up 8 seconds 0.0.0.0:5000->5000/tcp registry
2
3
在浏览器输入 http://192.168.242.218:5000/v2/
,出现如下情况,则表示私库搭建成功。
# 2.3 通过私有仓库进行上传/下载
在 docker
主机(192.168.242.219)上操作。
按照 docker push
的标准格式-必须按照符合仓库要求的 registry_url:port/image_name:tag
的格式,通过docker tag命令来实现镜像命名,然后在push到仓库。
1. 给镜像打标签
docker tag nginx:latest 192.168.242.218:5000/nginx:pro
2. push到私有仓库
docker push 192.168.242.218:5000/nginx:pro
[root@docker ~]# docker push 192.168.242.218:5000/nginx:pro
The push refers to repository [192.168.242.218:5000/nginx]
Get https://192.168.242.218:5000/v2/: http: server gave HTTP response to HTTPS client
2
3
出现这个错误的解决方法:
如果之前配置了阿里云加速器,则删除文件 /etc/docker/daemon.json
,然后执行如下命令:
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"insecure-registries": ["192.168.242.218:5000"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2
3
4
5
6
7
再来 docker push :
[root@docker ~]# docker push 192.168.242.218:5000/nginx:pro
The push refers to repository [192.168.242.218:5000/nginx]
4eaf0ea085df: Pushed
2c7498eef94a: Pushed
7d2b207c2679: Pushed
5c4e5adc71a8: Pushed
87c8a1d8f54f: Pushed
pro: digest: sha256:13e4551010728646aa7e1b1ac5313e04cf75d051fa441396832fcd6d600b5e71 size: 1362
2
3
4
5
6
7
8
成功!再通过浏览器输入 http://192.168.242.218:5000/v2/_catalog
查看仓库列表:
3. 从私库pull镜像
先删掉本地已存在的 192.168.242.218:5000/nginx:pro
镜像:
docker rmi 192.168.242.218:5000/nginx:pro
拉取私库中的nginx镜像:
docker pull 192.168.242.218:5000/nginx:pro
验证拉取成功。
# 3 企业级开源组件Harbor
# 3.1 Harbor特点概括
Harbor是一个用于存储Docker镜像的企业级Registry服务。
Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的镜像仓库,但是从安全和效率等方面考虑,部署我们私有环境内的Registry也是非常必要的。
Harbor是由VMware公司开源的企业级的Docker Registry管理项目,它包括权限管理(RBAC)、LDAP、日志审核、管理界面、自我注册、镜像复制和中文支持等功能。
# 3.2 环境部署
网速不好或者不想下载的,可关注我的公众号 行百里er 回复 docker 下载,还有本文原创pdf及docker脑图。
# 1. 需要安装docker-compose
离线安装,下载地址:
https://dl.bintray.com/docker-compose/master/ (opens new window)
下载完成,得到文件docker-compose-Linux-x86_64
,重命名:
mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
# 2. 离线安装harbor
下载离线安装包,下载地址从如下网址找到:
https://github.com/goharbor/harbor/releases (opens new window)
这里直接下载最新的 2.1.2
版本。
将文件放到合适的位置(比如/usr/local
),解压:
cd /usr/local && tar xvf harbor-offline-installer-v2.1.2.tgz
得到harbor
文件夹,进入,执行prepare:
[root@harbor harbor]# ./prepare
prepare base dir is set to /usr/local/harbor
Unable to find image 'goharbor/prepare:v2.1.2' locally
v2.1.2: Pulling from goharbor/prepare
d92f685b57aa: Pull complete
fc55d5d4818d: Pull complete
ea8c2aea8e20: Pull complete
3330770cd308: Pull complete
c549bbd461f6: Pull complete
df56c6333246: Pull complete
ecedca2dfa64: Pull complete
d3b48e96a07e: Pull complete
Digest: sha256:d7959b235cbd0a357594d58c2341cb12788a388d7edacbad71095f3231cab4ca
Status: Downloaded newer image for goharbor/prepare:v2.1.2
ERROR:root:Please specify hostname
Error happened in config validation...
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
出现这个错误 ERROR:root:Please specify hostname
,修改一下配置文件harbor.yml
再次执行:
[root@myharbor harbor]# ./prepare
prepare base dir is set to /usr/local/harbor
ERROR:root:Error: The protocol is https but attribute ssl_cert is not set
2
3
继续修改配置文件,注释掉https:
然后继续执行prepare
:
prepare成功后,执行install脚本:
安装成功提示如上,查看一下docker镜像和运行的容器:
此时,我们就可以登录harbor web ui页面玩了。
用户名是admin 密码可以在 harbor.yml
配置文件中找到,默认为 Harbor12345
,登录进去,可以看到一个漂亮的管理页面:
TIP:可能会遇到的问题
虚拟机关闭后再次启动,发现harbor页面打不开了,这个问题困扰了我很久,值得提一下我的解决过程。
我先进入到harbor目录,用docker-compose down && docker-compose up -d
一套组合拳进行关闭harbor和重新启动harbor,再次访问,依旧不行;
然后我验证了一下该主机上的其他端口是否可以访问,于是用Docker创建了一个tomcat容器,端口映射成8081,浏览器访问之,发现也访问不了;
那么问题可以确定不是在harbor上,而是在网络上,我在启动tomcat容器的时候,有这么一个提示:
[root@myharbor harbor]# docker run -d -p 8081:8080 tomcat
WARNING: IPv4 forwarding is disabled. Networking will not work.
73d1c0463aa2694cfa34b997b41afb86eb2e50d908b3f2e2b9588dd65181735f
2
3
WARNING: IPv4 forwarding is disabled. Networking will not work.
这个信息提醒了我,于是怀疑是IP转发功能的问题。最终解决方案如下:
1. Linux系统缺省并没有打开IP转发功能,用如下命令确认IP转发功能的状态:
cat /proc/sys/net/ipv4/ip_forward
2. 如果发现该值为0,说明禁止进行IP转发;如果是1,则说明IP转发功能已经打开。打开IP转发功能命令:
echo 1 > /proc/sys/net/ipv4/ip_forward
3. 使配置生效
sysctl -p /etc/sysctl.conf
4. 重启网络 & Docker
systemctl restart network && systemctl restart docker
5. 关闭harbor
cd /usr/local/harbor && docker-compose down
6. 启动harbor
docker-compose up -d
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 3.3 Docker镜像上传下载至Harbor私有仓库
这个和 Docker-Registry 私有仓库的操作大同小异:
- 在Harbor管理页面创建一个项目先,这个项目也就是镜像存放的地址,镜像名称也需要用到
- 给镜像打符合要求的标签 docker tag IP:端口/项目名称/镜像名称:tag
- Docker客户端配置
/etc/docker/daemon.json
,添加insecure-registries
内容 - Docker客户端登录 docker login IP:端口 -u admin -p Harbor12345
- docker push/pull
下面我以一个dev版本的Tomcat镜像为例。
在Docker客户端(192.168.242.217)制作一个镜像,从官方下载的Tomcat镜像,运行容器无法正常访问Tomcat首页,原因是运行的Tomcat容器内部webapps目录下没有任何内容,而是放在了webapps.dist目录下,我就以这个容器为基础,进入到容器内部,将webapps.dist的内容拷贝到webapps目录下,然后 docker commit 成一个新镜像,最后将这个新镜像提交到Harbor私有仓库。
制作镜像并打标签的主要操作命令:
[root@docker ~]# docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
6c33745f49b4: Pull complete
ef072fc32a84: Pull complete
c0afb8e68e0b: Pull complete
d599c07d28e6: Pull complete
e8a829023b97: Pull complete
d04be46a31d1: Pull complete
db6007c69c35: Pull complete
e4ad4c894bce: Pull complete
248895fda357: Pull complete
277059b4cba2: Pull complete
Digest: sha256:57dae7dfb9b62a413cde65334c8a18893795cac70afc3be589c8336d8244655d
Status: Downloaded newer image for tomcat:latest
docker.io/library/tomcat:latest
[root@docker ~]# docker run -d -p 8001:8080 tomcat:latest
56d1f7ab0b2ee95c369ff26eef99908ba256a8c6d6ba8144bd3954525381383f
[root@docker ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56d1f7ab0b2e tomcat:latest "catalina.sh run" 4 seconds ago Up 3 seconds 0.0.0.0:8001->8080/tcp reverent_lamport
[root@docker ~]# docker exec -it 56d1f7ab0b2e /bin/bash
root@56d1f7ab0b2e:/usr/local/tomcat# cd webapps.dist/
root@56d1f7ab0b2e:/usr/local/tomcat/webapps.dist# cp -r * ../webapps/
root@56d1f7ab0b2e:/usr/local/tomcat/webapps.dist# cd ../webapps
root@56d1f7ab0b2e:/usr/local/tomcat/webapps# ls
ROOT docs examples host-manager manager
root@56d1f7ab0b2e:/usr/local/tomcat/webapps# exit
exit
[root@docker ~]# docker commit 56d1f7ab0b2e 192.168.242.217/xblzer/tomcat:dev
sha256:1e982d89a75763a93d902b71a76e2c43fd3d7e03a70fb0dbd3089712ca0dbaed
[root@docker ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.242.217/xblzer/tomcat dev 1e982d89a757 4 seconds ago 653MB
tomcat latest feba8d001e3f 2 days ago 649MB
xblzer/nginx v1 ae2feff98a0c 5 days ago 133MB
nginx latest ae2feff98a0c 5 days ago 133MB
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
28
29
30
31
32
33
34
35
36
37
PS:这里的Tomcat是为了方便而举的例子,实际生产环境一般都是自己的应用,比如SpringBoot应用、Vue应用等构建成镜像推送到仓库。
推送主要步骤涉及的命令都在下面了:
[root@docker ~]# vim /etc/docker/daemon.json
[root@docker ~]# systemctl restart docker
[root@docker ~]# systemctl restart docker
[root@docker ~]# docker login 192.168.242.217 -u admin -p Harbor12345
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@docker ~]# docker push 192.168.242.217/xblzer/tomcat:dev
The push refers to repository [192.168.242.217/xblzer/tomcat]
b64a3ca40e3a: Pushed
ecec7e17c20b: Layer already exists
467d4d32e8da: Layer already exists
d2329ec79afd: Layer already exists
998e4e1e3864: Layer already exists
fb6f398853f5: Layer already exists
e528f2c31deb: Layer already exists
c5f4367d4a59: Layer already exists
ceecb62b2fcc: Layer already exists
193bc1d68b80: Layer already exists
f0e10b20de19: Layer already exists
dev: digest: sha256:00d031e1dd37cdafbd1d8ae1334b71a2e8a8280d90895fd0266654fddd314eb4 size: 2632
[root@docker ~]# docker pull 192.168.242.217/xblzer/tomcat:dev
dev: Pulling from xblzer/tomcat
Digest: sha256:00d031e1dd37cdafbd1d8ae1334b71a2e8a8280d90895fd0266654fddd314eb4
Status: Image is up to date for 192.168.242.217/xblzer/tomcat:dev
192.168.242.217/xblzer/tomcat:dev
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
28
29
30
31
这个时候看一下仓库:
运行一下容器:
docker run -d -p 8002:8080 192.168.242.217/xblzer/tomcat:dev
访问 http://192.168.242.219:8002
:
完成。
首发公众号 行百里er ,欢迎老铁们关注阅读指正。