Skip to content

Commit a03ef64

Browse files
authored
Merge pull request #814 from droot/book-move-crd-docs
📖 added CRD generation reference for v2 docs
2 parents 27c1cc0 + 54e782a commit a03ef64

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

docs/book/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
- [Reference](./reference/reference.md)
3030

31+
- [Generating CRD](./reference/generating-crd.md)
3132
- [Using Finalizers](./reference/using-finalizers.md)
3233

3334
---
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Generating CRD
2+
3+
Kubebuilder provides a tool named `controller-gen` to generate manifests for CustomResourceDefinitions. The tool resides in the [controller-tools](http://sigs.k8s.io/controller-tools) repository and is installed through a Makefile target called `controller-gen`.
4+
5+
If you examine the `Makefile` in your project, you will see a target named `manifests` for generating manifests. `manifests` target is also listed as prerequisite for other targets like `run`, `tests`, `deploy` etc to ensure CRD manifests are regenerated when needed.
6+
7+
```sh
8+
# Generate manifests e.g. CRD, RBAC etc.
9+
manifests: controller-gen
10+
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
11+
12+
# find or download controller-gen
13+
# download controller-gen if necessary
14+
controller-gen:
15+
ifeq (, $(shell which controller-gen))
16+
go get sigs.k8s.io/controller-tools/cmd/[email protected]
17+
CONTROLLER_GEN=$(GOBIN)/controller-gen
18+
else
19+
CONTROLLER_GEN=$(shell which controller-gen)
20+
endif
21+
```
22+
23+
When you run `make manifests`, you should see generated CRDs are under `config/crd/bases` directory.
24+
25+
`controller-gen` generates manifests for RBAC as well, but this section covers the generation of CRD manifests.
26+
27+
`controller-gen` reads kubebuilder markers of the form `// +kubebuilder:something...` defined as Go comments in the `<your-api-kind>_types.go` file under `apis/...` to produce the CRD manifests. Sections below describe various supported annotations.
28+
29+
## Validation
30+
31+
CRDs support [validation](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#validation) by definining ([OpenAPI v3 schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md#schemaObject)) in the validation section. To learn more about the validation feature, refer to the original docs [here](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#validation). One can specify validation for a field by annotating the field with kubebuilder marker which is of the form`// +kubebuilder:validation:<key=value>`. If you want to specify multiple validations for a field, you can add multiple such markers as demonstrated in the example below.
32+
33+
Currently, supporting keys are `Maximum`, `Minimum`, `MaxLength`, `MinLength`, `MaxItems`, `MinItems`, `UniqueItems`, `Enum`, `Pattern`, `ExclusiveMaximum`,
34+
`ExclusiveMinimum`, `MultipleOf`, `Format`. The `// +kubebuilder:validation:Pattern=.+:.+` annotation specifies the Pattern validation requiring that the `Image` field match the regular expression `.+:.+`
35+
36+
**Example:**
37+
38+
```go
39+
type ToySpec struct {
40+
41+
// +kubebuilder:validation:Maximum=100
42+
// +kubebuilder:validation:Minimum=1
43+
// +kubebuilder:validation:ExclusiveMinimum=true
44+
Power float32 `json:"power,omitempty"`
45+
46+
Bricks int32 `json:"bricks,omitempty"`
47+
// +kubebuilder:validation:MaxLength=15
48+
// +kubebuilder:validation:MinLength=1
49+
Name string `json:"name,omitempty"`
50+
51+
// +kubebuilder:validation:MaxItems=500
52+
// +kubebuilder:validation:MinItems=1
53+
// +kubebuilder:validation:UniqueItems=false
54+
Knights []string `json:"knights,omitempty"`
55+
56+
// +kubebuilder:validation:Enum=Lion,Wolf,Dragon
57+
Alias string `json:"alias,omitempty"`
58+
59+
// +kubebuilder:validation:Enum=1,2,3
60+
Rank int `json:"rank"`
61+
}
62+
63+
```
64+
65+
## Additional printer columns
66+
67+
Starting with Kubernetes 1.11, kubectl uses server-side printing. The server
68+
decides which columns are shown by the kubectl get command. You can
69+
[customize these columns using a CustomResourceDefinition](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#additional-printer-columns).
70+
To add an additional column, add a comment with the following marker format
71+
just above the struct definition of the Kind.
72+
73+
Format: `// +kubebuilder:printcolumn:name="Name",type="type",JSONPath="json-path",description="desc",priority="priority",format="format"`
74+
75+
Note that `description`, `priority` and `format` are optional. Refer to the
76+
[additonal printer columns docs](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#additional-printer-columns)
77+
to learn more about the values of `name`, `type`, `JsonPath`, `description`, `priority` and `format`.
78+
79+
The following example adds the `Spec`, `Replicas`, and `Age` columns.
80+
81+
```go
82+
// +kubebuilder:printcolumn:name="Spec",type="integer",JSONPath=".spec.cronSpec",description="status of the kind"
83+
// +kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".spec.replicas",description="The number of jobs launched by the CronJob"
84+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
85+
type CronTab struct {
86+
metav1.TypeMeta `json:",inline"`
87+
metav1.ObjectMeta `json:"metadata,omitempty"`
88+
89+
Spec CronTabSpec `json:"spec,omitempty"`
90+
Status CronTabStatus `json:"status,omitempty"`
91+
}
92+
93+
```
94+
95+
96+
## Subresource
97+
Custom resources support `/status` and `/scale` subresources as of kubernetes
98+
1.13 release. You can learn more about the subresources [here](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#status-subresource).
99+
100+
### 1. Status
101+
To enable `/status` subresource, annotate the kind with `// +kubebuilder:subresource:status` marker.
102+
103+
### 2. Scale
104+
To enable `/scale` subresource, annotate the kind with `// +kubebuilder:subresource:scale:specpath=<jsonpath>,statuspath=<jsonpath>,selectorpath=<jsonpath>` marker.
105+
106+
Scale subresource marker contains three fields: `specpath`, `statuspath` and `selectorpath`.
107+
108+
- `specpath` refers to `specReplicasPath` attribute of Scale object, and value `jsonpath` defines the JSONPath inside of a custom resource that corresponds to `Scale.Spec.Replicas`. This is a required field.
109+
- `statuspath` refers to `statusReplicasPath` attribute of Scale object. and the `jsonpath` value of it defines the JSONPath inside of a custom resource that corresponds to `Scale.Status.Replicas`. This is a required field.
110+
- `selectorpath` refers to `labelSelectorPath` attribute of Scale object, and the value `jsonpath` defines the JSONPath inside of a custom resource that corresponds to `Scale.Status.Selector`. This is an optional field.
111+
112+
113+
**Example:**
114+
115+
```go
116+
type ToySpec struct {
117+
Replicas *int32 `json:"replicas"` // Add this field in Toy Spec, so the jsonpath to this field is `.spec.replicas`
118+
}
119+
120+
// ToyStatus defines the observed state of Toy
121+
type ToyStatus struct {
122+
Replicas int32 `json:"replicas"` // Add this field in Toy Status, so the jsonpath to this field is `.status.replicas`
123+
}
124+
125+
126+
// Toy is the Schema for the toys API
127+
// +kubebuilder:subresource:status
128+
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas
129+
type Toy struct {
130+
metav1.TypeMeta `json:",inline"`
131+
metav1.ObjectMeta `json:"metadata,omitempty"`
132+
133+
Spec ToySpec `json:"spec,omitempty"`
134+
Status ToyStatus `json:"status,omitempty"`
135+
}
136+
137+
```
138+
139+
In order to enable scale subresource in type definition file, you have to apply the scale subresource right before the kind struct definition, with correct jsonpath values according to the spec and status. And then make sure the jsonpaths are already defined in the Spec and Status struct. Finally, update the `<kind>_types_test.go` files according to the types Spec and Status changes.
140+
141+
In the above example for the type `Toy`, we added `// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas` comment before `Toy` struct definition. `.spec.replicas` refers to the josnpath of Spec struct field (`ToySpec.Replicas`). And jsonpath `.status.healthyReplicas` refers to Status struct field (`ToyStatus.Replicas`).
142+
143+
## Multiple Versions
144+
145+
If you are defining multiple versions of a kind in your project, you need to do
146+
the following:
147+
148+
- Set `CRD_OPTIONS ?= "crd:trivialVersions=false"` in the Makefile
149+
- Annotate the Go struct with marker `// +kubebuilder:storageversion` for the
150+
indicating the storage version. Read [more](../TODO.md) for supporting
151+
multiple versions in your project

0 commit comments

Comments
 (0)