Skip to content

Commit 47f279b

Browse files
authored
Merge pull request #895 from mengqiy/migrationdoc
📖 Migration doc
2 parents 73805d5 + fa9ab4e commit 47f279b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+3913
-1
lines changed

docs/book/src/SUMMARY.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939

4040
- [Deployment and Testing](./multiversion-tutorial/deployment.md)
4141

42+
---
43+
- [User Guides](./user-guide.md)
44+
45+
- [Kubebuilder v1 vs v2](./migration/v1vsv2.md)
46+
- [Migration Guide](./migration/guide.md)
47+
4248
---
4349

4450
- [Reference](./reference/reference.md)

docs/book/src/migration/guide.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Migration from v1 to v2
2+
3+
Make sure you understand the [differences between Kubebuilder v1 and v2](./v1vsv2.md)
4+
before continuing
5+
6+
Please ensure you have followed the [installation guide](/quick-start.md#installation)
7+
to install the required components.
8+
9+
The recommended way to migrate a v1 project is to create a new v2 project and
10+
copy over the API and the reconciliation code. The conversion will end up with a
11+
project that looks like a native v2 project. However, in some cases, it's
12+
possible to do an in-place upgrade (i.e. reuse the v1 project layout, upgrading
13+
controller-runtime and controller-tools.
14+
15+
Let's take the [example v1 project][v1-project] and migrate it to Kubebuilder
16+
v2. At the end, we should have something that looks like the
17+
[example v2 project][v2-project].
18+
19+
## Preparation
20+
21+
We'll need to figure out what the group, version, kind and domain are.
22+
23+
Let's take a look at our current v1 project structure:
24+
25+
```
26+
pkg/
27+
├── apis
28+
│   ├── addtoscheme_batch_v1.go
29+
│   ├── apis.go
30+
│   └── batch
31+
│   ├── group.go
32+
│   └── v1
33+
│   ├── cronjob_types.go
34+
│   ├── cronjob_types_test.go
35+
│   ├── doc.go
36+
│   ├── register.go
37+
│   ├── v1_suite_test.go
38+
│   └── zz_generated.deepcopy.go
39+
├── controller
40+
└── webhook
41+
```
42+
43+
All of our API information is stored in `pkg/apis/batch`, so we can look
44+
there to find what we need to know.
45+
46+
In `cronjob_types.go`, we can find
47+
48+
```go
49+
type CronJob struct {...}
50+
```
51+
52+
In `register.go`, we can find
53+
54+
```go
55+
SchemeGroupVersion = schema.GroupVersion{Group: "batch.tutorial.kubebuilder.io", Version: "v1"}
56+
```
57+
58+
Putting that together, we get `CronJob` as the kind, and `batch.tutorial.kubebuilder.io/v1` as the group-version
59+
60+
## Initialize a v2 Project
61+
62+
Now, we need to initialize a v2 project. Before we do that, though, we'll need
63+
to initialize a new go module if we're not on the `gopath`:
64+
65+
```bash
66+
go mod init tutorial.kubebuilder.io/project
67+
```
68+
69+
Then, we can finish initializing the project with kubebuilder:
70+
71+
```bash
72+
kubebuilder init --domain tutorial.kubebuilder.io
73+
```
74+
75+
## Migrate APIs and Controllers
76+
77+
Next, we'll re-scaffold out the API types and controllers. Since we want both,
78+
we'll say yes to both the API and controller prompts when asked what parts we
79+
want to scaffold:
80+
81+
```bash
82+
kubebuilder create api --group batch --version v1 --kind CronJob
83+
```
84+
85+
If you're using multiple groups, some manual work is required to migrate.
86+
Please follow [this](/TODO.md) for more details.
87+
88+
### Migrate the APIs
89+
90+
Now, let's copy the API definition from `pkg/apis/batch/v1/cronjob_types.go` to
91+
`api/v1/cronjob_types.go`. We only need to copy the implementation of the `Spec`
92+
and `Status` fields.
93+
94+
We can replace the `+k8s:deepcopy-gen:interfaces=...` marker (which is
95+
[deprecated in kubebuilder](/reference/markers/object.md)) with
96+
`+kubebuilder:object:root=true`.
97+
98+
We don't need the following markers any more (they're not used anymore, and are
99+
relics from much older versions of KubeBuilder):
100+
101+
```go
102+
// +genclient
103+
// +k8s:openapi-gen=true
104+
```
105+
106+
Our API types should look like the following:
107+
108+
```go
109+
// +kubebuilder:object:root=true
110+
111+
// CronJob is the Schema for the cronjobs API
112+
type CronJob struct {...}
113+
114+
// +kubebuilder:object:root=true
115+
116+
// CronJobList contains a list of CronJob
117+
type CronJobList struct {...}
118+
```
119+
120+
### Migrate the Controllers
121+
122+
Now, let's migrate the controller reconciler code from
123+
`pkg/controller/cronjob/cronjob_controller.go` to
124+
`controllers/cronjob_controller.go`.
125+
126+
We'll need to copy
127+
- the fields from the `ReconcileCronJob` struct to `CronJobReconciler`
128+
- the contents of the `Reconcile` function
129+
- the [rbac related markers](/reference/markers/rbac.md) to the new file.
130+
- the code under `func add(mgr manager.Manager, r reconcile.Reconciler) error`
131+
to `func SetupWithManager`
132+
133+
## Migrate the Webhooks
134+
135+
If you don't have a webhook, you can skip this section.
136+
137+
### Webhooks for Core Types and External CRDs
138+
139+
If you are using webhooks for Kubernetes core types (e.g. Pods), or for an
140+
external CRD that is not owned by you, you can refer the
141+
[controller-runtime example for builtin types][builtin-type-example]
142+
and do something similar. Kubebuilder doesn't scaffold much for these cases, but
143+
you can use the library in controller-runtime.
144+
145+
### Scaffold Webhooks for our CRDs
146+
147+
Now let's scaffold the webhooks for our CRD (CronJob). We'll need to run the
148+
following command with the `--defaulting` and `--programmatic-validation` flags
149+
(since our test project uses defaulting and validating webhooks):
150+
151+
```bash
152+
kubebuilder create webhook --group batch --version v1 --kind CronJob --defaulting --programmatic-validation
153+
```
154+
155+
Depending on how many CRDs need webhooks, we may need to run the above command
156+
multiple times with different Group-Version-Kinds.
157+
158+
Now, we'll need to copy the logic for each webhook. For validating webhooks, we
159+
can copy the contents from
160+
`func validatingCronJobFn` in `pkg/default_server/cronjob/validating/cronjob_create_handler.go`
161+
to `func ValidateCreate` in `api/v1/cronjob_webhook.go` and then the same for `update`.
162+
163+
Similarly, we'll copy from `func mutatingCronJobFn` to `func Default`.
164+
165+
### Webhook Markers
166+
167+
When scaffolding webhooks, Kubebuilder v2 adds the following markers:
168+
169+
```
170+
// These are v2 markers
171+
172+
// This is for the mutating webhook
173+
// +kubebuilder:webhook:path=/mutate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=true,failurePolicy=fail,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v1,name=mcronjob.kb.io
174+
175+
...
176+
177+
// This is for the validating webhook
178+
// +kubebuilder:webhook:path=/validate-batch-tutorial-kubebuilder-io-v1-cronjob,mutating=false,failurePolicy=fail,groups=batch.tutorial.kubebuilder.io,resources=cronjobs,verbs=create;update,versions=v1,name=vcronjob.kb.io
179+
```
180+
181+
The default verbs are `verbs=create;update`. We need to ensure `verbs` matches
182+
what we need. For example, if we only want to validate creation, then we would
183+
change it to `verbs=create`.
184+
185+
We also need to ensure `failure-policy` is still the same.
186+
187+
Markers like the following are no longer needed (since they deal with
188+
self-deploying certificate configuration, which was removed in v2):
189+
190+
```go
191+
// v1 markers
192+
// +kubebuilder:webhook:port=9876,cert-dir=/tmp/cert
193+
// +kubebuilder:webhook:service=test-system:webhook-service,selector=app:webhook-server
194+
// +kubebuilder:webhook:secret=test-system:webhook-server-secret
195+
// +kubebuilder:webhook:mutating-webhook-config-name=test-mutating-webhook-cfg
196+
// +kubebuilder:webhook:validating-webhook-config-name=test-validating-webhook-cfg
197+
```
198+
199+
In v1, a single webhook marker may be split into multiple ones in the same
200+
paragraph. In v2, each webhook must be represented by a single marker.
201+
202+
## Others
203+
204+
If there are any manual updates in `main.go` in v1, we need to port the changes
205+
to the new `main.go`. We'll also need to ensure all of the needed schemes have
206+
been registered.
207+
208+
If there are additional manifests added under `config` directory, port them as
209+
well.
210+
211+
Change the image name in the Makefile if needed.
212+
213+
## Verification
214+
215+
Finally, we can run `make` and `make docker-build` to ensure things are working
216+
fine.
217+
218+
[v1-project]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/docs/book/src/migration/testdata/gopath/project
219+
[v2-project]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/docs/book/src/cronjob-tutorial/testdata/project
220+
[builtin-type-example]: https://sigs.k8s.io/controller-runtime/examples/builtins
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
# Binaries for programs and plugins
3+
*.exe
4+
*.exe~
5+
*.dll
6+
*.so
7+
*.dylib
8+
bin
9+
10+
# Test binary, build with `go test -c`
11+
*.test
12+
13+
# Output of the go coverage tool, specifically when used with LiteIDE
14+
*.out
15+
16+
# Kubernetes Generated files - skip generated files, except for vendored files
17+
18+
!vendor/**/zz_generated.*
19+
20+
# editor and IDE paraphernalia
21+
.idea
22+
*.swp
23+
*.swo
24+
*~
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Build the manager binary
2+
FROM golang:1.10.3 as builder
3+
4+
# Copy in the go src
5+
WORKDIR /go/src/project
6+
COPY pkg/ pkg/
7+
COPY cmd/ cmd/
8+
COPY vendor/ vendor/
9+
10+
# Build
11+
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager project/cmd/manager
12+
13+
# Copy the controller-manager into a thin image
14+
FROM ubuntu:latest
15+
WORKDIR /
16+
COPY --from=builder /go/src/project/manager .
17+
ENTRYPOINT ["/manager"]

0 commit comments

Comments
 (0)