zl程序教程

您现在的位置是:首页 >  后端

当前栏目

使用athens部署企业内部Gitlab go mod包的Go私服代理

Go代理企业部署 内部 gitlab mod 私服
2023-09-14 09:01:53 时间

# 1,前言

当前 go 开发,已经全面投入到 mod 的怀抱,国内也有一些优秀的代理,例如 https://goproxy.iohttps://goproxy.cn等,但是企业内网的 gitlab 上的包如何也能想公网包那样引用拉取呢,这是一个问题,我曾体验过如上 goproxy 这个项目的开源版本,但是内网拉包仍旧是一个没有完美解决的问题,公司在用的是 athens,还不甚熟悉,但是为了能对它胸有成竹,今天打算钻研一番。

之前的文档云里雾里,自己跑了一遍也没有跑通,网上的文章也都是没有能够参考的。今天再次自己研究,果然功夫不负有心人,重要的还是要静下心认真看人家的官方文档才行。

之前生产在跑的镜像是 latest 版本,以至于很多内容不好控制,进到容器里看了下用的是 0.3.0 版本的,目前官方已经更新到了 0.10.0,相差很远了,今天就来固定版本,并且完美跑通。

部分信息内容已经脱敏处理,如果读者有迷惑的地方,欢迎留言交流。本文偏向于构建内部私服代理,如果想要构建一个包容性更强的大私服,可以参考这篇文章

# 2,配置

下载对应镜像,这不多说:

docker pull gomods/athens:v0.10.0
# 如果太慢,可以用如下镜像
registry.cn-hangzhou.aliyuncs.com/eryajf/athens:v0.10.0

这里需要用到官方对应版本的配置文件,可以下载对应 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
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"
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
config:
$ cat config
Host gitlab.test.com
Hostname gitlab.test.com
StrictHostKeyChecking no
IdentityFile /root/.ssh/id_rsa

剩下两个秘钥文件就不展示了,不过需要注意的一点是,通过秘钥认证的话,要注意这个秘钥在 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

这样基本上就能提供服务了,不过这个时候可能拉外网的包还会有问题,所以在 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;
    }
}

img

# 3,验证

然后即可投入使用了,简单验证一下,在客户端配置如下内容,我在 go1.12 环境下测试的:

export GO111MODULE=on
export GOPROXY="http://192.168.0.2:4000"

接着下一两个包试试效果:

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

非常完美!

# 4,踩坑

关于拉取内部包失败的一些原因:

  1. 容器报错 通过 docker logs -f athens看日志, 说 /data/athens/storage目录不存在,此时可以进入到容器中,创建这个目录,即可成功。
  2. 认证问题 这个问题比较好验证以及处理,要知道,私服想要从内部 gitlab 拉包成功,要么通过用户名密码,要么通过秘钥,这里当然推荐使用秘钥,那么,只要上边配置没有毛病,我们只需拷贝一个项目地址,来到容器内部克隆一下,看能否成功,如果失败,则说明是认证的问题,如果成功,则说明这块儿没问题。
  3. 其他错误 如果配置过程中没有按我上边的内容,则可能会出现其他奇怪的错误,欢迎大家一起提出交流。

最后再次感谢 athens 的开源分享,让我们的工作显得更加轻巧便捷。

# 5,参考

原文链接

官方文档

官方镜像 - Dockerfile

下载方式的介绍

https://github.com/gomods/athens/issues/1471