Go 为什么可以通过 k8s.io 来获取 kubernetes
Kubernetes 的仓库在 github.com/kubernetes/kubernetes, 按照默认的习俗来说, 项目对应 Go Module 应该是 github.com/kubernetes/kubernetes. 但熟悉的同学都知道, kubernetes 的 module 是 k8s.io/kubernetes.
这依赖 https://k8s.io/kubernetes?go-get=1 在返回中包括特定的标签 <meta name="go-import"
.
~ curl https://k8s.io/kubernetes\?go-get\=1
<html><head>
<meta name="go-import"
content="k8s.io/kubernetes
git https://github.com/kubernetes/kubernetes">
<meta name="go-source"
content="k8s.io/kubernetes
https://github.com/kubernetes/kubernetes
https://github.com/kubernetes/kubernetes/tree/master{/dir}
https://github.com/kubernetes/kubernetes/blob/master{/dir}/{file}#L{line}">
</head></html>
Go Module 支持识别 content 中的内容, 以 git 协议去 https://github.com/kubernetes/kubernetes 获取对应内容.
官方对此的介绍位于 Serving modules directly from a proxy.
在公司使用内部部署的 git 服务时, 我经常使用上述的逻辑去优化 Go 的体验:
- 使用简短有象征意义的域名代替繁琐的代码仓库的域名
- 直接指定 SSH 地址, 避免每个 Go 开发都需要处理私仓的访问
返回的内容类似:
<html><head>
<meta name="go-import"
content="ohai.bot/zeus git ssh://git@dev.companion.host:30022/group/zeus">
</head></html>
再不使用 go-import 标签的情况下, Go 访问 Git 私有仓库一般通过 git 配置来将 https 替换为 ssh.
git config --global url."ssh://git@dev.companion/".insteadOf "https://dev.companion/"
总的而言, 当我们在 Go 中处理某个依赖时:
- 对于众所周知的地址, Go 会直接按特定的逻辑处理. 如 github.com 开头的地址都会通过 git 去获取对应内容.
- 或者, 则尝试获取 go-import 标签后再处理
- 否则, 按 git 协议尝试