community
community copied to clipboard
Add proposal doc for accelerate replicate speed between Harbor and the target cr
hi all , I post this proposal here and hope you to check. thanks!
https://github.com/goharbor/harbor/issues/10414
@steven-zou @reasonerjt @wy65701436 @xaleeks
@wy65701436 @bitsf
Let's have a look at this proposal if it can improve the perf of replication that is the focus of post 2.0 release.
@wy65701436 @bitsf
Let's have a look at this proposal if it can improve the perf of replication that is the focus of post 2.0 release.
@steven-zou Much appreciated! ping @wy65701436 @bitsf thx for yours attentions!
hi @markzhang0928 不好意思我没有太看明天你的这个proposal,你这里提到的 ui model 是指的我们 harbor 的portal ui模块,还是 nginx proxy模块,还是一个你提议单独实现的用于拦截upload blob request 的新模块? 你说的用于加速实际复制传输数据的操作是发生在什么时候
hi @markzhang0928 不好意思我没有太看明天你的这个proposal,你这里提到的 ui model 是指的我们 harbor 的portal ui模块,还是 nginx proxy模块,还是一个你提议单独实现的用于拦截upload blob request 的新模块? 你说的用于加速实际复制传输数据的操作是发生在什么时候
你好,@bitsf 目前修改是在harbor-ui 模块,src/ui/proxy/proxy.go 这个文件。以下是一些关键的代码片段。
用于加速实际复制传输数据的操作,是在harbor-ui ReverseProxy拿到每次HEAD请求的返回,并且判断为200时。
func (bt *ProxyBlobsTransfer) RoundTrip(req *http.Request) (resp *http.Response, err error) {
resp, err = bt.rt.RoundTrip(req)
if err != nil {
return nil, err
}
if resp.Request.Method == http.MethodHead && resp.StatusCode == http.StatusOK {
log.Infof("handler Chain %v", req.URL)
if err := bt.initParams(req.URL); err != nil {
log.Errorf("ui proxy HEAD request URL init params failed. err: %s", err)
}
tfClient, err := NewBlobTransferClient(bt)
if err != nil {
log.Errorf("ui proxy blob transfer client initialized failed. err: %s", err)
}
digest := strings.Trim(resp.Header.Get("Etag"), "\"")
err = tfClient.transferLayer(digest)
if err != nil {
log.Errorf("ui proxy transfer blob layer failed. err: %s ", err)
}
}
return resp, nil
}
// Init initialize the Proxy instance and handler chain.
func Init(urls ...string) error {
var err error
return err
}
Proxy = httputil.NewSingleHostReverseProxy(targetURL)
log.Infof("harbor ui proxy - target URL %v", targetURL)
Proxy.Transport = &ProxyBlobsTransfer{
rt: http.DefaultTransport,
TransferMap: make(map[string]interface{})}
handlers = handlerChain{head: readonlyHandler{next: urlHandler{next: listReposHandler{next: contentTrustHandler{next: vulnerableHandler{next: Proxy}}}}}}
return nil
}
你这个用的是哪个版本的harbor?看起来是几年前的代码了。 我们现在没有src/ui 这个模块 我们现在的架构是 nginx -> portal -> core -> harbor api -> registry api
我估计你的代码对应当前master 的代码应该是 https://github.com/goharbor/harbor/blob/master/src/server/registry/proxy.go#L33
我理解你的这个提议目的是说在用户 push image 的同时就开始往远端的 registry 中先push blob。
你这个用的是哪个版本的harbor?看起来是几年前的代码了。 我们现在没有src/ui 这个模块 我们现在的架构是 nginx -> portal -> core -> harbor api -> registry api
我估计你的代码对应当前master 的代码应该是 https://github.com/goharbor/harbor/blob/master/src/server/registry/proxy.go#L33
是的。不好意思,我忽略了注明版本。目前的流程对应是在您发的这个src/server/registry/proxy.go文件.
我理解你的这个提议目的是说在用户 push image 的同时就开始往远端的 registry 中先push blob。
对,当用户在enable了目标地址加速功能之后,会在这个反向代理转发请求的同时,上传镜像层到目标地址。真正的复制流程还是依赖原本的jobservice模块,只不过其中的镜像blob数据已经提前上传,以此达到加速复制的效果。
如果提议可以通过的话,我会按照当前master分支的代码进行修改,再提一个PR。
个人感觉这个改动和我们当前的架构设计差异比较大,会破坏设计模式,不适合直接在代码库中增加这样的修改。 而且这个改动还需要考虑安全、调度、缓存、日志、阀值、异常处理等方面的需求,开发维护工作量都较大。 如果对于内部使用场景确实有比较大的性能提升,我建议找一些其他的方式加载此实现,比如能够以单独的插件配置进来,比如修改nginx再配置一个额外的代理专门做这个
@steven-zou @ywk253100 What do you think?
个人感觉这个改动和我们当前的架构设计差异比较大,会破坏设计模式,不适合直接在代码库中增加这样的修改。 而且这个改动还需要考虑安全、调度、缓存、日志、阀值、异常处理等方面的需求,开发维护工作量都较大。 如果对于内部使用场景确实有比较大的性能提升,我建议找一些其他的方式加载此实现,比如能够以单独的插件配置进来,比如修改nginx再配置一个额外的代理专门做这个
@steven-zou @ywk253100 What do you think?
异地镜像复制本身确实需要考虑比较多问题,原本的jobservice模块也做得十分健壮。但是考虑到是用户开关控制的加速功能,针对两个内网可达的harbor实例场景,提前开始镜像层的复制,确实能有比较好的加速效果,缩短3-5倍镜像复制的时间窗口。如果habor 原生的release 可以支持该可选功能,也是一种旁路支持的加速方式,且开箱即用,并不影响原本的镜像复制流程。不需要用户进行额外的开发和配置,对有多region的harbor用户,提供了实在的便捷。
个人感觉这个改动和我们当前的架构设计差异比较大,会破坏设计模式,不适合直接在代码库中增加这样的修改。 而且这个改动还需要考虑安全、调度、缓存、日志、阀值、异常处理等方面的需求,开发维护工作量都较大。 如果对于内部使用场景确实有比较大的性能提升,我建议找一些其他的方式加载此实现,比如能够以单独的插件配置进来,比如修改nginx再配置一个额外的代理专门做这个
@steven-zou @ywk253100 What do you think?
内部测试统计 ,同步一个大小1.05GB,11层的镜像,加速之后跨域同步的时间从原本的61s缩短到17s.
SH-harbor同步到SZ-harbor
SH-node push到SH-harbor,镜像大小1.05GB,十一层
(1)13:36:06,执行docker push reg.harbor154-shanghai.com/tmp1/name2:v2
(2)13:36:22,PUT /v2/tmp1/name2/manifests/v2 HTTP/1.1
docker push用时 16s
(3)13:36:24,(SH-harbor)开始下载镜像,192.168.192.1
Dec 1 13:36:24 192.168.192.1 registry[45966]: time="2019-12-01T05:36:24.242702161Z" level=warning msg="error authorizing context: authorization token required" go.version=go1.7.3 http.request.host=reg.harbor154-shanghai.com http.request.id=832f70d6-dedd-4027-8efb-24bc76f1fa72 http.request.method=GET http.request.remoteaddr=192.168.192.1 http.request.uri="/v2/" http.request.useragent="Go-http-client/1.1" instance.id=699b9430-a63a-4353-b6ec-813346e88ebb service=registry version=v2.6.2
每一层按顺序复制
(4)13:37:09,SH-harbor,http.request.remoteaddr=192.168.192.1下载最后一层
Dec 1 13:37:09 172.27.0.1 registry[1469]: 2019/12/01 13:37:09 PUT https://xxx.aliyuncs.com/docker/registry/v2/repositories/tmp1/name2/_uploads/5845a333-54ca-4b43-aa46-935f1f8769e0/startedat ...
复制镜像用时45s
(5)SZ-harbor,收到manifest
Dec 1 13:37:14 172.27.0.1 registry[1469]: time="2019-12-01T13:37:14.878078856+08:00" level=info msg="response completed" go.version=go1.7.3 http.request.contenttype="application/vnd.docker.distribution.manifest.v2+json" http.request.host=reg-harbor154-shenzhen.local.haiyan.hy http.request.id=1e7dfcaf-f352-45cf-9b10-363e41822aff http.request.method=PUT http.request.remoteaddr=10.68.5.86 http.request.uri="/v2/tmp1/name2/manifests/v2" http.request.useragent=harbor-registry-client http.response.duration=321.868753ms http.response.status=201 http.response.written=0 instance.id=760dc1d7-9124-494c-8c44-9ccfe4c5eddf service=registry version=v2.6.2
个人感觉这个改动和我们当前的架构设计差异比较大,会破坏设计模式,不适合直接在代码库中增加这样的修改。
关于这一点,应该也可以解耦的。具体的流程和代码,请给我一些时间,我再做调整..
I would agree with @bitsf, that this looks like an external tool to achieve the feature of tee, instead of within Harbor.
If a few seconds faster to have the image data available on a remote registry is important to you, these 2 instances can share the storage...
I would agree with @bitsf, that this looks like an external tool to achieve the feature of
tee, instead of within Harbor.If a few seconds faster to have the image data available on a remote registry is important to you, these 2 instances can share the storage...
I suppose that 2 instances share the same storage is another use case which could not support the scene of download image nearby.
@markzhang0928 Like I said I agree with @bitsf it's more suitable as an external tool, because it does not fit into the replication framework.
You can continue with the development but I personally don't think it should be upstreamed.
If you make it an external tool you don't need to maintain your branch and you solve your problem as well.
We close for now, this proposal for now. Due to the current lack of interest from the community. However, this decision does not prevent the possibility of revisiting your proposal in the future, should the situation change.