通过手动更新文件进行从 v2 到 v3 的迁移

在继续之前,请确保您了解 Kubebuilder v2 和 v3 之间的区别

请确保您已按照安装指南安装所需的组件。

以下指南描述了升级您的配置版本并开始使用插件支持版本所需的手动步骤。

这种方式更复杂,容易出错,成功也无法得到保证。此外,按照这些步骤操作,您将无法获得默认生成项目文件中的改进和bug修复。

通常情况下,如果您对项目进行了自定义并且偏离了建议的框架,您才会选择手动处理。在继续之前,请确保您理解关于项目自定义的说明。请注意,手动执行此过程可能需要比组织项目自定义以遵循建议布局投入更多的精力,而后者可以让您的项目在未来更易于维护和升级。

推荐的升级方法是遵循 从 V2 到 V3 的迁移指南

从项目配置版本迁移 \

在项目配置版本之间迁移涉及对您项目的 PROJECT 文件中的字段进行添加、删除和/或更改,该文件是通过运行 init 命令创建的。

PROJECT 文件现在有了新的布局。它存储了更多关于正在使用的资源的信息,以更好地帮助插件在搭建时做出有用的决策。

此外,PROJECT 文件本身现在是版本化的。version 字段对应于 PROJECT 文件本身的版本,而 layout 字段则指示正在使用的框架和主要插件的版本。

迁移步骤

以下步骤描述了手动更改项目配置文件(PROJECT)所需的步骤。这些更改将添加Kubebuilder在生成文件时会添加的信息。该文件可以在根目录中找到。

添加 projectName

项目名称是项目目录的名称,使用小写字母。

...
projectName: example
...

添加 layout

默认的插件布局与之前的版本相当,设置为 go.kubebuilder.io/v2

...
layout:
- go.kubebuilder.io/v2
...

更新版本

version 字段表示项目布局的版本。将其更新为 "3"

...
version: "3"
...

添加资源数据

属性 resources 代表在您的项目中搭建的资源列表。

您需要为每个添加到项目中的资源添加以下数据。

通过添加 resources[entry].api.crdVersion: v1beta1 来添加 Kubernetes API 版本:
...
resources:
- api:
    ...
    crdVersion: v1beta1
  domain: 我的域名
  group: 网络应用程序
  kind:  guestbook (签名册)
  ...
通过添加 resources[entry].api.namespaced: true 来添加用于搭建 CRDs 的范围,除非它们是集群范围的。
...
resources:
- api:
    ...
    namespaced: true
  group: 网络应用程序
  kind:  guestbook (签名册)
  ...
如果你为 API 创建了控制器框架,那么添加 resources[entry].controller: true
...
resources:
- api:
    ...
  controller: true
  group: 网络应用程序
  kind:  guestbook (签名册)
添加资源域,例如 resources[entry].domain: testproject.org,这通常是项目域,除非 API 骨架是核心类型和/或外部类型:
...
resources:
- api:
    ...
  domain: testproject.org
  group: 网络应用程序
  kind:  guestbook (签名册)

请注意,只有当您的项目有一个核心类型 API 的脚手架,并且 Kubernetes API 组合格方案定义中的 Domain 值不为空时,您才需要添加 domain。 (例如,您可以查看 这里,在 API apps 中,Kinds 的域为空,而在 这里 中,API authentication 的 Kinds 的域是 k8s.io

请查看以下列表,以了解支持的核心类型及其领域:

核心类型域名
入学“k8s.io”
入学注册“k8s.io”
appsempty
审计注册“k8s.io”
apiextensions 的中文翻译是“API 扩展“。“k8s.io”
身份验证“k8s.io”
授权“k8s.io”
自动扩展empty
batchempty
证书“k8s.io”
调整“k8s.io”
核心empty
events“k8s.io”
扩展包empty
图像策略“k8s.io”
网络连接“k8s.io”
节点“k8s.io”
指标“k8s.io”
政策empty
rbac.authorization“k8s.io”
调度“k8s.io”
设置“k8s.io”
storage“k8s.io”

以下是一个示例,其中通过命令 create api --group apps --version v1 --kind Deployment --controller=true --resource=false --make=false 为核心类型 Kind Deployment 搭建了控制器:

- controller: true
  group: apps
  kind: 部署
  path: k8s.io/api/apps/v1
  version: v1
resources[entry].path 添加为 api 的导入路径:
...
resources:
- api:
    ...
  ...
  group: 网络应用程序
  kind:  guestbook (签名册)
  path: 示例/api/v1
如果您的项目使用了 Webhooks,则对于每种生成的类型,添加 resources[entry].webhooks.[type]: true,然后添加 resources[entry].webhooks.webhookVersion: v1beta1
resources:
- api:
    ...
  ...
  group: 网络应用程序
  kind:  guestbook (签名册)
  webhooks:
    defaulting: true
    validation: true
    webhookVersion: v1beta1

检查您的项目文件。

现在请确保您的 PROJECT 文件在通过 Kubebuilder V3 CLI 生成清单时包含相同的信息。

对于 QuickStart 示例,手动更新为使用 go.kubebuilder.io/v2PROJECT 文件如下所示:

domain: 我的域名
layout:
- go.kubebuilder.io/v2
projectName: example
repo: example
resources:
- api:
    crdVersion: v1
    namespaced: true
  controller: true
  domain: 我的域名
  group: 网络应用程序
  kind:  guestbook (签名册)
  path: 示例/api/v1
  version: v1
version: "3"

您可以通过比较一个涉及多个 API 和 Webhook 的示例场景,查看以前布局(版本 2)和当前格式(版本 3)之间的差异,具体请参阅 go.kubebuilder.io/v2

示例(项目版本 2)

domain: testproject.org
repo: sigs.k8s.io/kubebuilder/example
resources:
- group: 船员
  kind: 船长
  version: v1
- group: 船员
  kind: 第一伴侣
  version: v1
- group: 船员
  kind: 海军上将
  version: v1
version: "2"

示例(项目版本 3)

domain: testproject.org
layout:
- go.kubebuilder.io/v2
projectName: example
repo: sigs.k8s.io/kubebuilder/example
resources:
- api:
    crdVersion: v1
    namespaced: true
  controller: true
  domain: testproject.org
  group: 船员
  kind: 船长
  path: 示例/api/v1
  version: v1
  webhooks:
    defaulting: true
    validation: true
    webhookVersion: v1
- api:
    crdVersion: v1
    namespaced: true
  controller: true
  domain: testproject.org
  group: 船员
  kind: 第一伴侣
  path: 示例/api/v1
  version: v1
  webhooks:
    转换: true
    webhookVersion: v1
- api:
    crdVersion: v1
  controller: true
  domain: testproject.org
  group: 船员
  kind: 海军上将
  path: 示例/api/v1
  plural: 海军将领
  version: v1
  webhooks:
    defaulting: true
    webhookVersion: v1
version: "3"

验证

在上述步骤中,你只更新了代表项目配置的 PROJECT 文件。这个配置仅对命令行工具有用。它不应该影响你的项目的行为。

没有选项可以验证您是否正确更新了配置文件。确保配置文件具有正确的 V3+ 字段的最佳方法是初始化一个具有相同 API、控制器和 webhook 的项目,以便比较生成的配置与手动更改的配置。

如果您在上述过程中犯了错误,您可能会在使用命令行界面时遇到问题。

将您的项目更新为使用 go/v3 插件。

在项目之间迁移 插件 涉及对任何插件支持的命令(例如 initcreate)创建的文件进行添加、删除和/或更改。一个插件支持一个或多个项目配置版本;在升级插件版本之前,请确保将项目的配置版本升级到目标插件版本所支持的最新版本。

以下步骤描述了手动修改项目布局所需的变更,以便使您的项目能够使用 go/v3 插件。这些步骤不会帮助您解决已生成的脚手架中的所有错误。

迁移步骤

将你的插件版本更新到 PROJECT 文件中。

在更新 layout 之前,请确保您已经按照上述步骤将您的项目版本升级到 3。一旦您升级了项目版本,请将 layout 更新为新插件版本 go.kubebuilder.io/v3,具体操作如下:

domain: 我的域名
layout:
- go.kubebuilder.io/v3
...

升级 Go 版本及其依赖项:

确保你的 go.mod 文件使用 Go 版本 1.15 和以下依赖版本:

module example

go 1.18

require (
    github.com/onsi/ginkgo/v2 v2.1.4
    github.com/onsi/gomega v1.19.0
    k8s.io/api v0.24.0
    k8s.io/apimachinery v0.24.0
    k8s.io/client-go v0.24.0
    sigs.k8s.io/controller-runtime v0.12.1
)

更新 Go 语言镜像

在 Dockerfile 中替换:

# Build the manager binary
FROM docker.io/golang:1.13 as builder

With:

# Build the manager binary
FROM docker.io/golang:1.16 as builder

更新你的 Makefile

允许 controller-gen 来搭建新的 Kubernetes API。

为了让 controller-gen 和脚手架工具使用新的 API 版本,请替换:

``With:

``##### 允许自动下载

为了允许将 Envtest 所需的 Kubernetes 二进制文件的新版本下载到您项目的 testbin/ 目录中,而不是全局设置,请替换:

# 运行测试
test: 生成格式化的兽医清单
	go test ./... -coverprofile cover.out

With:

将SHELL设置为bash允许通过配方执行bash命令。
# Options are set to exit when a recipe line exits non-zero or a piped command fails.
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
test: 生成清单 格式 校验 ## 运行测试。
	mkdir -p ${ENVTEST_ASSETS_DIR}
	test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.3/hack/setup-envtest.sh
	source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out
升级所使用的 controller-genkustomize 依赖版本

要升级用于生成清单的 controller-genkustomize 版本,请替换:

# find or download controller-gen
# download controller-gen if necessary
controller-gen:
ifeq (, $(shell which controller-gen))
	@{ \
	set -e ;\
	CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
	cd $$CONTROLLER_GEN_TMP_DIR ;\
	go mod init tmp ;\
	go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.2.5 ;\
	rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
	}
CONTROLLER_GEN=$(GOBIN)/controller-gen
else
CONTROLLER_GEN=$(shell which controller-gen)
endif

With:

`然后,为了使您的项目使用 Makefile 中定义的 kustomize版本,请将所有kustomize的用法替换为$(KUSTOMIZE)`。

更新您的控制器。

Replace:

func (r *<MyKind>Reconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
    ctx := context.Background()
    log := r.Log.WithValues("cronjob", req.NamespacedName)

With:

func (r *<MyKind>Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    log := r.Log.WithValues("cronjob", req.NamespacedName)

更新你的控制器和 webhook 测试套件。

Replace:

	. "github.com/onsi/ginkgo"

With:

	. "github.com/onsi/ginkgo/v2"

另外,请调整您的测试套件。

针对控制器套件:

	RunSpecsWithDefaultAndCustomReporters(t,
		"Controller Suite",
		[]Reporter{printer.NewlineReporter{}})

With:

	RunSpecs(t, "Controller Suite")

用于 Webhook 套件:

	RunSpecsWithDefaultAndCustomReporters(t,
		"Webhook Suite",
		[]Reporter{printer.NewlineReporter{}})

With:

	RunSpecs(t, "Webhook Suite")

最后但同样重要的是,从 BeforeSuite 块中移除超时变量:

Replace:

var _ = BeforeSuite(func(done Done) {
	....
}, 60)

var _ = BeforeSuite(func(done Done) {
	....
})

将日志记录器更改为使用标志选项。

main.go 文件中替换:

flag.Parse()

ctrl.SetLogger(zap.New(zap.UseDevMode(true)))

With:

opts := zap.Options{
	Development: true,
}
opts.BindFlags(flag.CommandLine)
flag.Parse()

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))

重命名监控程序标志

该管理器的--metrics-addrenable-leader-election标志已重命名为--metrics-bind-address--leader-elect,以与核心Kubernetes组件更一致。更多信息请查看:#1839

在您的 main.go 文件中替换:

func main() {
	var metricsAddr string
	var enableLeaderElection bool
	flag.StringVar(&metricsAddr, "metrics-addr", ":8080", "The address the metric endpoint binds to.")
	flag.BoolVar(&enableLeaderElection, "enable-leader-election", false,
		"Enable leader election for controller manager. "+
			"启用此功能将确保只有一个活动的控制管理器。")

With:

func main() {
	var metricsAddr string
	var enableLeaderElection bool
	flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
	flag.BoolVar(&enableLeaderElection, "leader-elect", false,
		"Enable leader election for controller manager. "+
			"启用此功能将确保只有一个活动的控制管理器。")

然后,重命名 config/default/manager_auth_proxy_patch.yamlconfig/default/manager.yaml 中的标志:

- name: manager
args:
- "--health-probe-bind-address=:8081"
- "--metrics-bind-address=127.0.0.1:8080"
- "--leader-elect"

验证

最后,我们可以运行 makemake docker-build 来确保一切正常。

将您的项目更改为删除对Kubernetes已弃用API版本的使用。

以下步骤描述了一个工作流程,用于升级您的项目以移除已弃用的 Kubernetes API:apiextensions.k8s.io/v1beta1admissionregistration.k8s.io/v1beta1cert-manager.io/v1alpha2

Kubebuilder CLI 工具不支持同时使用具有两个 Kubernetes API 版本的脚手架资源,例如:一个 API/CRD 使用 apiextensions.k8s.io/v1beta1,另一个使用 apiextensions.k8s.io/v1

第一步是更新您的 PROJECT 文件,将 api.crdVersion:v1betawebhooks.WebhookVersion:v1beta 替换为 api.crdVersion:v1webhooks.WebhookVersion:v1,如下所示:

domain: 我的域名
layout: go.kubebuilder.io/v3
projectName: example
repo: example
resources:
- api:
    crdVersion: v1
    namespaced: true
  group: 网络应用程序
  kind:  guestbook (签名册)
  version: v1
  webhooks:
    defaulting: true
    webhookVersion: v1
version: "3"

您可以尝试使用 --force 标志重新创建 APIS(CRD)和 Webhooks 清单。

现在,通过运行 kubebuilder create apikubebuilder create webhook 命令,并分别使用 --force 标志,为相同的组、种类和版本重新创建 APIS(CRDs)和 Webhooks 清单。