使用athens部署企业内部Gitlab包的私服代理
# 1,前言
当前 go 开发,已经全面投入到 mod 的怀抱,国内也有一些优秀的代理,例如 https://goproxy.io
,https://goproxy.cn
等,但是企业内网的 gitlab 上的包如何也能想公网包那样引用拉取呢,这是一个问题,我曾体验过如上 goproxy 这个项目的开源版本,但是内网拉包仍旧是一个没有完美解决的问题,公司在用的是 athens,还不甚熟悉,但是为了能对它胸有成竹,今天打算钻研一番。
之前的文档云里雾里,自己跑了一遍也没有跑通,网上的文章也都是没有能够参考的。今天再次自己研究,果然功夫不负有心人,重要的还是要静下心认真看人家的官方文档才行。
之前生产在跑的镜像是 latest 版本,以至于很多内容不好控制,进到容器里看了下用的是 0.3.0 版本的,目前官方已经更新到了 0.10.0,相差很远了,今天就来固定版本,并且完美跑通。
部分信息内容已经脱敏处理,如果读者有迷惑的地方,欢迎留言交流。本文偏向于构建内部私服代理,如果想要构建一个包容性更强的大私服,可以参考这篇文章 (opens new window)。
# 2,配置
下载对应镜像,这不多说:
docker pull gomods/athens:v0.10.0
# 如果太慢,可以用如下镜像
registry.cn-hangzhou.aliyuncs.com/eryajf/athens:v0.10.0
2
3
这里需要用到官方对应版本的配置文件,可以下载对应 release 的配置文件解压拿到,还有其他一些配置文件,目录详情如下:
$ pwd
/data/athens
$ tree -a
.
|-- config
| |-- config.toml --------# 主配置文件
| |-- FilterForGoCenter --# 一个过滤配置
| `-- .netrc ------------# 拉取gitlab时配置转换信息
|-- gitconfig
| `-- ssh-keys --------# 拉取gitlab包时认证信息
| |-- config --------# 认证gitlab的信息
| |-- id_rsa --------# 私钥
| |-- id_rsa.pub ----# 公钥
| `-- known_hosts
`-- storage ----------------# 缓存目录
4 directories, 7 files
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
config.toml:
$ cat config.toml | egrep -v '^$|^#|^.*#'
GoBinary = "go"
GoEnv = "development"
GoProxy = "direct"
GoBinaryEnvVars = ["GOPROXY=direct"]
GoGetWorkers = 10
GoGetDir = "/data/athens/storage" # go get 时的目录
ProtocolWorkers = 30
LogLevel = "debug"
CloudRuntime = "none"
EnablePprof = false
PprofPort = ":3001"
FilterFile = ""
RobotsFile = "robots.txt"
Timeout = 300
StorageType = "disk"
Port = ":3000"
GlobalEndpoint = "http://localhost:3001"
BasicAuthUser = ""
BasicAuthPass = ""
ForceSSL = false
ValidatorHook = ""
PathPrefix = ""
NETRCPath = ""
GithubToken = ""
HGRCPath = ""
TraceExporter = ""
TraceExporterURL = "http://localhost:14268"
StatsExporter = "prometheus"
SumDBs = ["https://sum.golang.google.cn"]
NoSumPatterns = []
DownloadMode = "sync"
DownloadURL = ""
SingleFlightType = "memory"
IndexType = "none"
[SingleFlight]
[SingleFlight.Etcd]
Endpoints = "localhost:2379,localhost:22379,localhost:32379"
[SingleFlight.Redis]
Endpoint = "127.0.0.1:6379"
Password = ""
[SingleFlight.RedisSentinel]
Endpoints = ["127.0.0.1:26379"]
MasterName = "redis-1"
SentinelPassword = "sekret"
[Storage]
[Storage.CDN]
Endpoint = "cdn.example.com"
[Storage.Disk]
RootPath = "/data/athens/storage"
[Storage.GCP]
ProjectID = "MY_GCP_PROJECT_ID"
Bucket = "MY_GCP_BUCKET"
JSONKey = ""
[Storage.Minio]
Endpoint = "127.0.0.1:9001"
Key = "minio"
Secret = "minio123"
EnableSSL = false
Bucket = "gomods"
Region = ""
[Storage.Mongo]
URL = "mongodb://127.0.0.1:27017"
DefaultDBName = "athens"
CertPath = ""
Insecure = false
[Storage.S3]
Region = "MY_AWS_REGION"
Key = "MY_AWS_ACCESS_KEY_ID"
Secret = "MY_AWS_SECRET_ACCESS_KEY"
Token = ""
Bucket = "MY_S3_BUCKET_NAME"
ForcePathStyle = false
UseDefaultConfiguration = false
CredentialsEndpoint = ""
AwsContainerCredentialsRelativeURI = ""
Endpoint = ""
[Storage.AzureBlob]
AccountName = "MY_AZURE_BLOB_ACCOUNT_NAME"
AccountKey = "MY_AZURE_BLOB_ACCOUNT_KEY"
ContainerName = "MY_AZURE_BLOB_CONTAINER_NAME"
[Storage.External]
URL = ""
[Index]
[Index.MySQL]
Protocol = "tcp"
Host = "localhost"
Port = 3306
User = "root"
Password = ""
Database = "athens"
[Index.MySQL.Params]
parseTime = "true"
timeout = "30s"
[Index.Postgres]
Host = "localhost"
Port = 5432
User = "postgres"
Password = ""
Database = "athens"
[Index.Postgres.Params]
connect_timeout = "30s"
sslmode = "disable"
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
FilterForGoCenter:
$ cat FilterForGoCenter
+
D golang.org
D k8s.io
D cloud.google.com
D google.golang.org
D github.com
D sigs.k8s.io
D sourcegraph.com
D gopkg.in
2
3
4
5
6
7
8
9
10
config:
$ cat config
Host gitlab.test.com
Hostname gitlab.test.com
StrictHostKeyChecking no
IdentityFile /root/.ssh/id_rsa
2
3
4
5
剩下两个秘钥文件就不展示了,不过需要注意的一点是,通过秘钥认证的话,要注意这个秘钥在 gitlab 当中的权限,是否能够拉取依赖的 go 项目。
使用如下命令启动服务:
docker run -d --net=host \
-v /data/athens/storage:/data/athens \
-v /data/athens/config:/config \
-v /data/athens/gitconfig/.gitconfig:/root/.gitconfig \
-v /data/athens/gitconfig/ssh-keys:/root/.ssh \
-v /etc/nsswitch.conf:/etc/nsswitch.conf \
-e ATHENS_DISK_STORAGE_ROOT=/data/athens \
-e ATHENS_NETRC_PATH=/config/.netrc \
-e ATHENS_STORAGE_TYPE=disk \
-e ATHENS_DOWNLOAD_MODE=sync \
-e ATHENS_GONOSUM_PATTERNS='gitlab.test.com/*' \
-e GOSUMDB="sum.golang.google.cn" \
--name athens-proxy --add-host gitlab.test.com:192.168.0.1 \
--restart always -p 0.0.0.0:3000:3000 gomods/athens:v0.10.0
2
3
4
5
6
7
8
9
10
11
12
13
14
这样基本上就能提供服务了,不过这个时候可能拉外网的包还会有问题,所以在 github 看到有同学用如下方案曲线救国了一下,在 NGINX 配置中添加如下内容:
upstream my-athens {
server 127.0.0.1:3000;
}
server {
listen 4000;
location / {
proxy_pass https://goproxy.io;
proxy_cache_valid 30d;
}
location ~ /(gitlab\.test\.com)/ {
proxy_pass http://my-athens;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
# 3,验证
然后即可投入使用了,简单验证一下,在客户端配置如下内容,我在 go1.12 环境下测试的:
export GO111MODULE=on
export GOPROXY="http://192.168.0.2:4000"
2
接着下一两个包试试效果:
go get -u github.com/gin-gonic/gin
先拉外部的包,此时发现速度杠杠的,通过 NGINX 日志也能对应的请求:
192.168.0.3 - - [21/Jul/2020:22:20:51 +0800] "GET /github.com/gin-gonic/gin/@v/v1.6.3.info HTTP/1.1" 200 50 "-" "Go-http-client/1.1" "-" "-" "10.3.6.27" "##0.136##" "##0.136##"
然后再测试内网包:
go get gitlab.test.com/micro-service/sale-srv@v0.1.21
也可以看到正常下载下来了,然后也能在私服缓存当中看到这个包了。
$ ls /data/athens/storage/gitlab.test.com/micro-service/sale-srv
v0.1.21
2
非常完美!
# 4,踩坑
关于拉取内部包失败的一些原因:
- 容器报错
通过
docker logs -f athens
看日志, 说/data/athens/storage
目录不存在,此时可以进入到容器中,创建这个目录,即可成功。 - 认证问题 这个问题比较好验证以及处理,要知道,私服想要从内部 gitlab 拉包成功,要么通过用户名密码,要么通过秘钥,这里当然推荐使用秘钥,那么,只要上边配置没有毛病,我们只需拷贝一个项目地址,来到容器内部克隆一下,看能否成功,如果失败,则说明是认证的问题,如果成功,则说明这块儿没问题。
- 其他错误 如果配置过程中没有按我上边的内容,则可能会出现其他奇怪的错误,欢迎大家一起提出交流。
最后再次感谢 athens 的开源分享,让我们的工作显得更加轻巧便捷。
# 5,参考
- 官方文档 (opens new window)
- 官方镜像 - Dockerfile (opens new window)
- 下载方式的介绍 (opens new window)
- https://github.com/gomods/athens/issues/1471