go1-12与1-14之私服使用的差异与变化
当私服搭建完成之后,在使用的姿势上,也有一些需要注意的地方,这里记录一下工作中使用的姿势以及坑点。
# 1,go1.12。
一开始大家使用的 golang 版本是 1.12,在这个版本中,go mod 还不是一个官方默认的选项,不过也没有像新版本中引入 sumdb 的验证,因此在配置私服的时候,反而会比较纯粹简单了。
这里假设如下两个地址:
- 私服:nexus.eryajf.net
- 内网包:gitlab.eryajf.net
在 go1.12 中,通过如下配置可以进行连接:
export GO111MODULE=on
export GOPROXY="http://nexus.eryajf.net/repository/go-group/"
2
那么无论在什么地方构建,应该都是可以高效且迅速完成的,此时无论是拉取外网的,GitHub 的包,都是可以通过私服来完成的,同样内网在 gitlab 中的包,也能够通过私服代理拉到。
# 2,go1.14。
后来一部分小伙伴升级了 go 的版本到了 1.14,这个时候,因为官方引入了 sumdb 的校验,这个校验的概念是所有公共的包都会在官方的 sumdb 中存有一份校验值,以防止一些恶意劫持篡改的情况发生,这本是一个好事儿,然而老问题又来了,官方的 sumdb 地址为:sum.golang.org (opens new window),当我们构建的时候,连到这个地址去校验包,往往都是超时的。
Get https://sum.golang.org/lookup/xxxxxx: dial tcp 216.58.200.49:443: i/o timeout
因此,我们得到第一步更新的配置(如下配置似乎也是许多地方推荐使用的配置方式,包括诸如 goproxy.io 官方文档):
export GOPROXY="http://nexus.eryajf.net/repository/go-group/"
export GONOPROXY="gitlab.eryajf.net"
export GONOSUMDB="gitlab.eryajf.net"
export GOPRIVATE="gitlab.eryajf.net"
export GOSUMDB="sum.golang.google.cn"
2
3
4
5
此处更新的配置中,最后一项是针对于校验时的问题解决的,sum.golang.google.cn 也是一个国内的库,可供使用,有一些文章建议说设置 export GOSUMDB=off
,这里并不推荐这么做,毕竟这层校验对安全来说,还是比较重要的。
但上边的配置也给后边的工作埋了一个坑。
有一些问题往往都是在不同场景当中展现的,而我们又很难在一开始就把所有的情况都想到,这不,有小伙伴反馈说 go 版本升级之后,在测试环境(容器化环境,镜像为golang:1.14.1
)发布的时候总是失败,失败的原因也很简单,就像下边所示:
[91mgo: gitlab.eryajf.net/test/admin-go@v1.0.3: reading gitlab.eryajf.net/test/admin-go/go.mod at revision v1.0.3: unknown revision v1.0.3
看得出是在从本地拉包的时候失败了,这个时候没有其他错误,我一般都是先到私服当中搜索一下,发现这个包是在的,那就没有道理拉不下来呀,这个时候思绪也沉溺在环境的不一致上了,做了不少测试验证都没有得到答案,因为在外边构建非常顺利,而测试环境就是发不成功。
后来一个同学把代理配置改成如下样子,发现构建成功了:
export GOPROXY="http://nexus.eryajf.net/repository/go-group/"
export GOSUMDB=off
2
成功了总还算是让人心情舒畅的,但是却没有想明白是为什么,为此,结合了几个开发大佬研讨许久,过程甚是酣畅,这里不多赘述,直接解密。
原因:
因为上边配置中有一项是export GONOPROXY="gitlab.eryajf.net"
,那么编译的时候拉gitlab.eryajf.net/test/admin-go@v1.0.3
这个包的时候,就不再走私服,而是从容器直接去 gitlab 中拉包,而对应项目又是Private
类型的,这两者之间未做任何认证,自然是无法拉到,这一点解释了上边的报错。
而本地之所以无法复现那个报错的原因应该是:当我拉包不通过代理,直接去 gitlab 拉包的时候,因为开发者本地都针对 gitlab 做过了认证,因此即便是直接去 gitlab 拉包也不会有问题,所以本地无法复现在容器中的那个错误。
于是有人提到说 GONOPROXY
这个选项有了,是不是也就代表着不需要我们内部的私服了,直接将代理设置为公共的,然后将GONOPROXY
设置为本地 gitlab,不就完美解决了,这种方案的不科学性与上边一致,要想实现,恐怕需要如下条件才行:
- 除非是所有内网的包都设置为
Public
类型,当然,出于安全性考虑,这种配置几乎不可能会采纳 - 或者是任何需要构建的地方,都加入一个基于所有私服包认证的 key,这或许是一个可行的方案,却不是一个优雅的方案,事实上 nexus 的 go 私服也是基于 key 来拉取内部的包的,只不过是把认证的工作统一交给
athens
来做了。
因此,最终我们在 go1.14 版本中,采用了如下的代理配置:
export GOPROXY="http://nexus.eryajf.net/repository/go-group/"
export GONOSUMDB="gitlab.eryajf.net"
export GOSUMDB="sum.golang.google.cn"
2
3
如上配置指明了我们所有的包都走私服代理进行拉取,但是内部域名下的包不走 sumdb 的校验,如果外部包需要校验,那么使用国内的地址 sum.golang.google.cn。
现在问题似乎都已经明朗了,或许可以再回头来审视一下上边添加的配置中几个选项的含义:
export GOPROXY="http://nexus.eryajf.net/repository/go-group/"
export GONOPROXY="gitlab.eryajf.net"
export GONOSUMDB="gitlab.eryajf.net"
export GOPRIVATE="gitlab.eryajf.net"
export GOSUMDB="sum.golang.google.cn"
2
3
4
5
GO111MODULE
:Go 语言提供了 GO111MODULE 这个环境变量来作为 Go modules 的开关,因为到 1.14 当中默认是 on,因此可以不加了。GOPROXY
:表示设置 go 模块儿代理,同 node 我们经常使用淘宝源一样的,这里地址指向我们的私服地址。GONOPROXY
:用于配置不走代理的地址。GOPRIVATE
:表示此项配置中的地址将会作为 GONOPROXY 和 GONOSUMDB 的默认值。GOSUMDB
:表示编译过程中 go 进行校验时的地址。GONOSUMDB
:表示此项中配置中的地址不进行校验,因为私服当中的包是无法也不能进行公有校验的。