Help us learn about your current experience with the documentation. Take the survey.

将项目用作 Go 包

  • Tier: Free, Premium, Ultimate
  • Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated

先决条件:

  • 联系管理员启用 GitLab Go 代理
  • 要将子组中的私有项目用作 Go 包,你必须认证 Go 请求。未经认证的 Go 请求会导致 go get 失败。对于不在子组中的项目,你不需要认证 Go 请求。

如果你使用无效的 HTTP 凭据发起 go get 请求,你会收到 404 错误。 你可以在 ~/.netrc(MacOS 和 Linux)或 ~/_netrc(Windows)中找到 HTTP 凭据。

为私有项目认证 Go 请求

先决条件:

  • 你的 GitLab 实例必须可以通过 HTTPS 访问。
  • 你必须拥有一个具有 read_api 权限的个人访问令牌

要认证 Go 请求,创建一个包含以下信息的 .netrc 文件:

machine gitlab.example.com
login <gitlab_user_name>
password <personal_access_token>

在 Windows 上,Go 会读取 ~/_netrc 而不是 ~/.netrc

go 命令不会在不安全的连接上传输凭据。它会认证 Go 发起的 HTTPS 请求,但不会认证通过 Git 发起的请求。

认证 Git 请求

如果 Go 无法从代理获取模块,它会使用 Git。Git 使用 .netrc 文件来认证请求,但你也可以 配置其他认证方法。

配置 Git 以选择以下任一方式:

  • 在请求 URL 中嵌入凭据:

    git config --global url."https://${user}:${personal_access_token}@gitlab.example.com".insteadOf "https://gitlab.example.com"
  • 使用 SSH 而不是 HTTPS:

    git config --global url."[email protected]:".insteadOf "https://gitlab.example.com/"

禁用私有项目的 Go 模块获取

要获取模块或包,Go 使用 以下环境变量:

  • GOPRIVATE
  • GONOPROXY
  • GONOSUMDB

要禁用获取:

  1. 禁用 GOPRIVATE
    • 要禁用对单个项目的查询,禁用 GOPRIVATE=gitlab.example.com/my/private/project
    • 要禁用对 GitLab.com 上所有项目的查询,禁用 GOPRIVATE=gitlab.example.com
  2. GONOPROXY 中禁用代理查询。
  3. GONOSUMDB 中禁用校验和查询。
  • 如果模块名称或其前缀在 GOPRIVATEGONOPROXY 中,Go 不会查询模块 代理。
  • 如果模块名称或其前缀在 GOPRIVATEGONOSUMDB 中,Go 不会查询 校验和数据库。

为私有子组认证 Git 请求

如果 Go 模块位于私有子组下,例如 gitlab.com/namespace/subgroup/go-module,那么 Git 认证将不起作用。 这是因为 go get 会发起未经认证的请求来发现 仓库路径。 如果不使用 .netrc 文件进行 HTTP 认证,GitLab 会响应 gitlab.com/namespace/subgroup.git,以防止向未认证用户暴露 项目存在的安全风险。 结果,Go 模块无法被下载。

不幸的是,除了 .netrc 之外,Go 不提供任何请求认证方式。 在未来的版本中,Go 可能会添加对任意 认证头的支持。 有关详细信息,请关注 golang/go#26232

解决方案:在模块名中使用 .git

有一种方法可以跳过 go get 请求并强制 Go 直接使用 Git 认证, 但这需要修改模块名称。来自 Go 文档

如果模块路径在路径组件的末尾有 VCS 限定符(.bzr.fossil.git.hg.svn 之一), go 命令将使用该路径限定符之前的所有内容作为仓库 URL。例如,对于模块 example.com/foo.git/bar,go 命令会使用 Git 下载 example.com/foo.git 上的仓库,期望在 bar 子目录中找到该模块。

  1. 转到私有子组中的 Go 模块的 go.mod
  2. 在模块名称中添加 .git。 例如,将 module gitlab.com/namespace/subgroup/go-module 重命名为 module gitlab.com/namespace/subgroup/go-module.git
  3. 提交并推送此更改。
  4. 访问依赖于此模块的 Go 项目并调整它们的 import 调用。 例如,import gitlab.com/namespace/subgroup/go-module.git

进行此更改后,Go 模块应该能被正确获取。 例如,GOPRIVATE=gitlab.com/namespace/* go mod tidy

从 Geo 从站获取 Go 模块

使用 Geo 来访问包含 Go 模块的 Geo 从站上的 Git 仓库。

你可以使用 SSH 或 HTTP 来访问 Geo 从站服务器。

使用 SSH 访问 Geo 从站服务器

要通过 SSH 访问 Geo 从站服务器:

  1. 在客户端重新配置 Git,将主站的流量发送到从站:

    git config --global url."[email protected]".insteadOf "https://gitlab.example.com"
    git config --global url."[email protected]".insteadOf "http://gitlab.example.com"
    • 对于 gitlab.example.com,使用主站域名。
    • 对于 gitlab-secondary.example.com,使用从站域名。
  2. 确保客户端已设置为通过 SSH 访问 GitLab 仓库。你可以在主站上测试, GitLab 会将公钥复制到从站。

go get 请求会生成到主 Geo 服务器的 HTTP 流量。当模块 下载开始时,insteadOf 配置会将流量发送到从 Geo 服务器。

使用 HTTP 访问 Geo 从站

你必须使用复制到从站服务器的持久访问令牌。你不能使用 CI/CD 作业令牌通过 HTTP 获取 Go 模块。

要通过 HTTP 访问 Geo 从站服务器:

  1. 在客户端添加一个 Git insteadOf 重定向:

    git config --global url."https://gitlab-secondary.example.com".insteadOf "https://gitlab.example.com"
    • 对于 gitlab.example.com,使用主站域名。
    • 对于 gitlab-secondary.example.com,使用从站域名。
  2. 生成一个个人访问令牌并 在客户端的 ~/.netrc 文件中添加凭据:

    machine gitlab.example.com login USERNAME password TOKEN
    machine gitlab-secondary.example.com login USERNAME password TOKEN

go get 请求会生成到主 Geo 服务器的 HTTP 流量。当模块 下载开始时,insteadOf 配置会将流量发送到从 Geo 服务器。