1.引用自己的fork

Wiki: document how to fork a package and use that fork in your project · Issue #39889 · golang/go (github.com)

replace 原始=>fork 分支/版本

例:
replace github.com/evanw/esbuild => github.com/matthewmueller/esbuild master

2.修改fork后的项目自立门户

  1. go module名称改成自己的
  2. replace:原始 => ./例:fork了kubekey后,github.com/kubesphere/kubekey => ./

3.报错-module declares its path as X,but was required as Y

报错详情如下:

gopkg.in/urfave/cli.v2: gopkg.in/urfave/cli.v2@v2.3.0: parsing go.mod:
        module declares its path as: github.com/urfave/cli/v2
                but was required as: gopkg.in/urfave/cli.v2

通过go mod edit replace将required改为declared即可

go mod edit -replace=${required}${version}=${declared}${version} 

4.找到依赖项目了,但是找不到package

通常是因为依赖引用的版本用了latest,而现在的latest和当时的latest在代码结构上已经变了

解决方案:根据项目的时间,倒推出大致的版本,用go mod edit replace将latest版本指定为过去的某个版本

go mod edit -replace=google.golang.org/grpc@latest=google.golang.org/grpc@v1.17.0

# go会自动在go.mod里将latest展开成当前的最高版本,go.mod里会看到如下的结果:
replace google.golang.org/grpc v1.50.1 => google.golang.org/grpc v1.17.0

5.两阶段构建优化

ENV GOPROXY https://goproxy.cn
# go mod tidy会打破缓存,download不会
RUN go mod download

6.有可能被间接引用过的包

基于k8s二次开发时,用到的一些公共的库,有较大概率在引用k8s.io相关的库时已经被间接引用过了。此时最好不要go get latest,应当先去go mod里查一下是否有引用及其版本,如果可用的话,用那个版本即可,避免引起依赖冲突

7.依赖兼容性问题

基于k8s的二次开发中,编译报错:

# k8s.io/component-base/logs/json
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:47:21: cannot use &zapLogger{} (value of type *zapLogger) as type logr.Logger in variable declaration
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:129:9: cannot use &zapLogger{…} (value of type *zapLogger) as type logr.Logger in return statement
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:138:9: cannot use l (variable of type *zapLogger) as type logr.Logger in return statement
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:144:9: cannot use l (variable of type *zapLogger) as type logr.Logger in return statement
../../../../go/pkg/mod/k8s.io/component-base@v0.21.14/logs/json/json.go:167:9: cannot use &zapLogger{…} (value of type *zapLogger) as type logr.Logger in return statement
# k8s.io/klog/v2
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:705:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:724:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:742:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)
../../../../go/pkg/mod/k8s.io/klog/v2@v2.9.0/klog.go:763:13: invalid operation: logr != nil (mismatched types logr.Logger and untyped nil)

搜索相关资料可以找到这个issue:controller-runtime is broken by github.com/go-logr/logr v1.0.0 · Issue #1607 · kubernetes-sigs/controller-runtime

里面提到了和报错相关的一个依赖的不兼容变更。

查看项目的go mod发现间接依赖的正是发生了不兼容修改后的github.com/go-logr/logr@v1.2.0,用replace将其改为老版本即可。

8.pgpme

go build cmd/kk/main.go
# pkg-config --cflags  -- gpgme
Package gpgme was not found in the pkg-config search path.
Perhaps you should add the directory containing `gpgme.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gpgme' found
pkg-config: exit status 1

brew install gpgme

9.module name是不是可以不用仓库名前缀

永远用module xxxxxx

不用module github.com/y/xxxxxx

A:当项目是终端项目,不会暴露给别人引用时,可以这么用

10. 引用kubernetes源码

kubernetes仓库中的部分模块有意设计为不允许外部直接引用,在引用这些模块时go mod会报错,关键词为

at revision v0.0.0: unknown revision

解决方法是用脚本做一些workaround实现这类源码的下载和导入

详情参考本博客调度器开发的内容,其中有专门章节提到:基于kubernetes调度框架的自定义调度器实现 - Lwabish Index (wubw.fun)