Harbor 调用Docker registry接口

Harbor 是一个CNCF基金会托管的开源的可信的云原生docker registry项目,可以用于存储、签名、扫描镜像内容,Harbor 通过添加一些常用的功能如安全性、身份权限管理等来扩展 docker registry 项目,此外还支持在 registry 之间复制镜像,还提供更加高级的安全功能,如用户管理、访问控制和活动审计等,在新版本中还添加了Helm仓库托管的支持。

​ Harbor最核心的功能就是给 docker registry 添加上一层权限保护的功能,要实现这个功能,就需要我们在使用 docker login、pull、push 等命令的时候进行拦截,先进行一些权限相关的校验,再进行操作,其实这一系列的操作 docker registry v2 就已经为我们提供了支持,v2 集成了一个安全认证的功能,将安全认证暴露给外部服务,让外部服务去实现。

docker registry v2 认证

img

在命令行中docker login https://registry.demo.com为例来说明下认证流程:

  • docker client 接收到用户输入的 docker login 命令,将命令转化为调用 engine api 的 RegistryLogin 方法
  • 在 RegistryLogin 方法中通过 http 盗用 registry 服务中的 auth 方法
  • 因为我们这里使用的是 v2 版本的服务,所以会调用 loginV2 方法,在 loginV2 方法中会进行 /v2/ 接口调用,该接口会对请求进行认证
  • 此时的请求中并没有包含 token 信息,认证会失败,返回 401 错误,同时会在 header 中返回去哪里请求认证的服务器地址
  • registry client 端收到上面的返回结果后,便会去返回的认证服务器那里进行认证请求,向认证服务器发送的请求的 header 中包含有加密的用户名和密码
  • 认证服务器从 header 中获取到加密的用户名和密码,这个时候就可以结合实际的认证系统进行认证了,比如从数据库中查询用户认证信息或者对接 ldap 服务进行认证校验
  • 认证成功后,会返回一个 token 信息,client 端会拿着返回的 token 再次向 registry 服务发送请求,这次需要带上得到的 token,请求验证成功,返回状态码就是200了
  • docker client 端接收到返回的200状态码,说明操作成功,在控制台上打印Login Succeeded的信息

Harbor 调用Docker registry接口测试

Harbor搭建完成后如果想要手动的获取镜像信息需要进行两次访问操作

从Harbor获取Docker registry请求的Token

1
2
3
4
5
6
7
8
USER="admin"
PASS="Harbor12345"
HURL="http://192.168.0.241"
MTAG="libaray/busybox"

ttoken=$(curl -iksL -X GET -u $USER:$PASS $HURL/service/token?account=${USER}\&service=harbor-registry\&scope=repository:${MTAG}:pull|grep "token" |awk -F '"' '{print $4}')

echo $ttoken

请求获得的token数据结构如下,一般在30分钟后过期

1
2
3
4
5
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik03Tkw6RzVPVDpZSlVDOk1KM0g6MkZPSzpTQjJHOkdTS0o6Tko0WTpCNEU2Ok9TVUE6Vk9WUjpZVVVRIn0.eyJpc3MiOiJoYXJib3ItdG9rZW4taXNzdWVyIiwic3ViIjoiYWRtaW4iLCJhdWQiOiJoYXJib3ItcmVnaXN0cnkiLCJleHAiOjE1NzQ4MzY3MzksIm5iZiI6MTU3NDgzNDkzOSwiaWF0IjoxNTc0ODM0OTM5LCJqdGkiOiJINVZoRXlwNHJPQmd4aWdmIiwiYWNjZXNzIjpbeyJ0eXBlIjoicmVwb3NpdG9yeSIsIm5hbWUiOiJ6eXkvenl5ZGVtbyIsImFjdGlvbnMiOlsicHVzaCIsIioiLCJwdWxsIl19XX0.CU4f4eOv5OuGjeFFJsgmTwj18tiK-n3zFM10FIGl5CJ_p1sR0HYJuceFpPyq2e_XEAho--oaDVBns2lo3i_4RMvMqkAdIFpTagWRiWlv-VZ12NHOLCnEBIK9qodxeTyYaJLCPc7ZjG376aVlYT9OSC6uA4QDrcfkNiLnAPQk97HGodWtd8D2-k8V3zxbhX9fP5LKQXRxK_Az5o2aMaR_P5DxLaFhb-sD8IIJCrrlNzucO92GhQl_ypdQj3ZGG_45ot0TiVknzHO9Tz6mOsOMIV_uhF4trG_tu6p1PAUhsQiIATjNYPFW6KRpJsQjfpqcnNoOl0P2RdsOcYjpAfY2Iw",
"expires_in": 1800,
"issued_at": "2019-11-27T06:08:59Z"
}

通过token调用docker registry接口获取数据

1
2
3
4
# 接上面sh部分
tlist=$(curl -ksL -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $ttoken" ${HURL}/v2/${MTAG}/tags/list|awk -F '[' '{print $2}'|awk -F ']' '{print $1}'|sed 's/"//g')

echo $tlist|sed 's/,/\n/g'

这里访问的是docker registry的v2接口/tags/list,获取镜像的标签列表。注意每个token对应的都是具体的镜像和操作,一旦有所修改就要重新更换token

1
2
3
4
5
6
{
"name": "libaray/busybox",
"tags": [
"v1.0.0"
]
}

参考

Harbor 源码浅析

Harbor 搜索镜像及查看 tag

Harbor 源码分析之API(四)