8000 doc: improve/fix memcached go tutorial (#4021) · operator-framework/operator-sdk@7845eec · GitHub
[go: up one dir, main page]

Skip to content

Commit 7845eec

Browse files
doc: improve/fix memcached go tutorial (#4021)
* doc: improve/fix memcached tutorial * fix link
1 parent a68f5fa commit 7845eec

File tree

4 files changed

+100
-83
lines changed

4 files changed

+100
-83
lines changed

website/content/en/docs/building-operators/ansible/tutorial.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ please [migrate][migration-guide], or consult the [legacy docs][legacy-quickstar
1313
- Go through the [installation guide][install-guide].
1414
- User authorized with `cluster-admin` permissions.
1515

16+
## Overview
17+
18+
We will create a sample project to let you know how it works and this sample will:
19+
20+
- Create a Memcached Deployment if it doesn't exist
21+
- Ensure that the Deployment size is the same as specified by the Memcached CR spec
22+
- Update the Memcached CR status using the status writer with the names of the memcached pods
23+
1624
## Create a new project
1725

1826
Use the CLI to create a new memcached-operator project:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
---
2+
title: OpenAPI validation
3+
linkTitle: OpenAPI validation
4+
weight: 70
5+
---
6+
7+
OpenAPIv3 schemas are added to CRD manifests in the `spec.validation` block when the manifests are generated. This validation block allows Kubernetes to validate the properties in a Memcached Custom Resource when it is created or updated.
8+
9+
[Markers][markers] (annotations) are available to configure validations for your API. These markers will always have a `+kubebuilder:validation` prefix.
10+
11+
Usage of markers in API code is discussed in the kubebuilder [CRD generation][generating-crd] and [marker][markers] documentation. A full list of OpenAPIv3 validation markers can be found [here][crd-markers].
12+
13+
To learn more about OpenAPI v3.0 validation schemas in CRDs, refer to the [Kubernetes Documentation][doc-validation-schema].
14+
15+
[markers]: https://book.kubebuilder.io/reference/markers.html
16+
[crd-markers]: https://book.kubebuilder.io/reference/markers/crd-validation.html
17+
[generating-crd]: https://book.kubebuilder.io/reference/generating-crd.html
18+
[doc-validation-schema]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#specifying-a-structural-schema

website/content/en/docs/building-operators/golang/tutorial.md

Lines changed: 66 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ please [migrate][migration-guide], or consult the [legacy docs][legacy-quickstar
1414
- Access to a Kubernetes v1.11.3+ cluster (v1.16.0+ if using `apiextensions.k8s.io/v1` CRDs).
1515
- User authorized with `cluster-admin` permissions.
1616

17+
## Overview
18+
19+
We will create a sample project to let you know how it works and this sample will:
20+
21+
- Create a Memcached Deployment if it doesn't exist
22+
- Ensure that the Deployment size is the same as specified by the Memcached CR spec
23+
- Update the Memcached CR status using the status writer with the names of the memcached pods
24+
1725
## Create a new project
1826

1927
Use the CLI to create a new memcached-operator project:
@@ -48,33 +56,8 @@ By default this will be the namespace that the operator is running in. To watch
4856
mgr, err := ctrl.NewManager(cfg, manager.Options{Namespace: ""})
4957
```
5058

51-
It is also possible to use the [MultiNamespacedCacheBuilder][multi-namespaced-cache-builder] to watch a specific set of namespaces:
52-
```Go
53-
var namespaces []string // List of Namespaces
54-
// Create a new Cmd to provide shared dependencies and start components
55-
mgr, err := ctrl.NewManager(cfg, manager.Options{
56-
NewCache: cache.MultiNamespacedCacheBuilder(namespaces),
57-
})
58-
```
59-
60-
#### Operator scope
61-
6259
Read the [operator scope][operator_scope] documentation on how to run your operator as namespace-scoped vs cluster-scoped.
6360

64-
### Multi-Group APIs
65-
66-
Before creating an API and controller, consider if your operator requires multiple API [groups][api-groups]. Then to change the layout of your project to support multi-group run the command `operator-sdk edit --multigroup`. It will update the `PROJECT` file which should look like the following:
67-
68-
```YAML
69-
domain: example.com
70-
layout: go.kubebuilder.io/v3
71-
multigroup: true
72-
...
73-
```
74-
For multi-group projects, the API Go type files are created under `apis/<group>/<version>/` and the controllers under `controllers/<group>/` and then, the Dockerfile will be updated accordingly. For further information see the [multi-group migration doc][multigroup-kubebuilder-doc]
75-
76-
This guide will cover the default case of a single group API.
77-
7861
## Create a new API and Controller
7962

8063
Create a new Custom Resource Definition(CRD) API with group `cache` version `v1alpha1` and Kind Memcached.
@@ -90,12 +73,21 @@ controllers/memcached_controller.go
9073

9174
This will scaffold the Memcached resource API at `api/v1alpha1/memcached_types.go` and the controller at `controllers/memcached_controller.go`.
9275

93-
See the [API terminology doc][api_terms_doc] for details on the CRD API conventions.
76+
**Note:** This guide will cover the default case of a single group API. If you would like to support Multi-Group APIs see the [Single Group to Multi-Group][multigroup-kubebuilder-doc] doc.
77+
78+
#### Understanding Kubernetes APIs
9479

95-
To understand the API Go types and controller scaffolding see the Kubebuilder [api doc][kb_api_doc] and [controller doc][kb_controller_doc].
80+
For an in-depth explanation of Kubernetes APIs and the group-version-kind model, check out these [kubebuilder docs][kb-doc-gkvs].
81+
82+
In general, it's recommended to have one controller responsible for manage each API created for the project to
83+
properly follow the design goals set by [controller-runtime][controller-runtime].
9684

9785
### Define the API
9886

87+
To begin, we will represent our API by defining the `Memcached` type, which will have a `MemcachedSpec.Size` field to set the quantity of memcached instances (CRs) to be deployed, and a `MemcachedStatus.Nodes` field to store a CR's Pod names.
88+
89+
**Note** The Node field is just to illustrate an example of a Status field. In real cases, it would be recommended to use [Conditions][conditionals].
90+
9991
Define the API for the Memcached Custom Resource(CR) by modifying the Go type definitions at `api/v1alpha1/memcached_types.go` to have the following spec and status:
10092

10193
```Go
@@ -143,30 +135,20 @@ Once the API is defined with spec/status fields and CRD validation markers, the
143135
make manifests
144136
```
145137

146-
This makefile target will invoke controller-gen to generate the CRD manifests at `config/crd/bases/cache.example.com_memcacheds.yaml`.
147-
148-
#### OpenAPI validation
149-
150-
OpenAPIv3 schemas are added to CRD manifests in the `spec.validation` block when the manifests are generated. This validation block allows Kubernetes to validate the properties in a Memcached Custom Resource when it is created or updated.
138+
This makefile target will invoke [controller-gen][controller_tools] to generate the CRD manifests at `config/crd/bases/cache.example.com_memcacheds.yaml`.
151139

152-
Markers (annotations) are available to configure validations for your API. These markers will always have a `+kubebuilder:validation` prefix.
140+
### OpenAPI validation
153141

154-
Usage of markers in API code is discussed in the kubebuilder [CRD generation][generating-crd] and [marker][markers] documentation. A full list of OpenAPIv3 validation markers can be found [here][crd-markers].
142+
OpenAPI validation defined in a CRD ensures CRs are validated based on a set of declarative rules. All CRDs should have validation.
143+
See the [OpenAPI valiation][openapi-validation] doc for details.
155144

156-
To learn more about OpenAPI v3.0 validation schemas in CRDs, refer to the [Kubernetes Documentation][doc-validation-schema].
157-
158-
### Implement the Controller
145+
## Implement the Controller
159146

160147
For this example replace the generated controller file `controllers/memcached_controller.go` with the example [`memcached_controller.go`][memcached_controller] implementation.
161148

162-
The example controller executes the following reconciliation logic for each Memcached CR:
163-
- Create a memcached Deployment if it doesn't exist
164-
- Ensure that the Deployment size is the same as specified by the Memcached CR spec
165-
- Update the Memcached CR status using the status writer with the names of the memcached pods
166-
167-
The next two subsections explain how the controller watches resources and how the reconcile loop is triggered. Skip to the ["run the Operator"](#run-the-operator) section to see how to build and run the operator.
149+
**Note**: The next two subsections explain how the controller watches resources and how the reconcile loop is triggered. Skip to the [Build](#build-and-push-the-image) section to see how to build and run the operator.
168150

169-
#### Resources watched by the Controller
151+
### Resources watched by the Controller
170152

171153
The `SetupWithManager()` function in `controllers/memcached_controller.go` specifies how the controller is built to watch a CR and other resources that are owned and managed by that controller.
172154

@@ -191,7 +173,7 @@ The `NewControllerManagedBy()` provides a controller builder that allows various
191173

192174
`Owns(&appsv1.Deployment{})` specifies the Deployments type as the secondary resource to watch. For each Deployment type Add/Update/Delete event, the event handler will map each event to a reconcile `Request` for the owner of the Deployment. Which in this case is the Memcached object for which the Deployment was created.
193175

194-
#### Controller Configurations
176+
### Controller Configurations
195177

196178
There are a number of other useful configurations that can be made when initialzing a controller. For more details on these configurations consult the upstream [builder][builder_godocs] and [controller][controller_godocs] godocs.
197179

@@ -208,10 +190,11 @@ There are a number of other useful configurations that can be made when initialz
208190
- Filter watch events using [predicates][event_filtering]
209191
- Choose the type of [EventHandler][event_handler_godocs] to change how a watch event will translate to reconcile requests for the reconcile loop. For operator relationships that are more complex than primary and secondary resources, the [`EnqueueRequestsFromMapFunc`][enqueue_requests_from_map_func] handler can be used to transform a watch event into an arbitrary set of reconcile requests.
210192

193+
### Reconcile loop
211194

212-
#### Reconcile loop
195+
The reconcile function is responsible for enforcing the desired CR state on the actual state of the system. It runs each time an event occurs on a watched CR or resource, and will return some value depending on whether those states match or not.
213196

214-
Every Controller has a Reconciler object with a `Reconcile()` method that implements the reconcile loop. The reconcile loop is passed the [`Request`][request-go-doc] argument which is a Namespace/Name key used to lookup the primary resource object, Memcached, from the cache:
197+
In this way, every Controller has a Reconciler object with a `Reconcile()` method that implements the reconcile loop. The reconcile loop is passed the [`Request`][request-go-doc] argument which is a Namespace/Name key used to lookup the primary resource object, Memcached, from the cache:
215198

216199
```Go
217200
import (
@@ -229,32 +212,32 @@ func (r *MemcachedReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
229212
}
230213
```
231214

232-
Based on the return values, [`Result`][result_go_doc] and error, the `Request` may be requeued and the reconcile loop may be triggered again:
233-
234-
```Go
235-
// Reconcile successful - don't requeue
236-
return ctrl.Result{}, nil
237-
// Reconcile failed due to error - requeue
238-
return ctrl.Result{}, err
239-
// Requeue for any reason other than an error
240-
return ctrl.Result{Requeue: true}, nil
241-
```
242-
243-
You can set the `Result.RequeueAfter` to requeue the `Request` after a grace period as well:
244-
```Go
245-
import "time"
215+
For a guide on Reconcilers, Clients, and interacting with resource Events, see the [Client API doc][doc_client_api].
246216

247-
// Reconcile for any reason other than an error after 5 seconds
248-
return ctrl.Result{RequeueAfter: time.Second*5}, nil
249-
```
217+
The following are a few possible return options for a Reconciler:
250218

251-
**Note:** Returning `Result` with `RequeueAfter` set is how you can periodically reconcile a CR.
219+
- With the error:
220+
```go
221+
return ctrl.Result{}, err
222+
```
223+
- Without an error:
224+
```go
225+
return ctrl.Result{Requeue: true}, nil
226+
```
227+
- Therefore, to stop the Reconcile, use:
228+
```go
229+
return ctrl.Result{}, nil
230+
```
231+
- Reconcile again after X time:
232+
```go
233+
return ctrl.Result{RequeueAfter: nextRun.Sub(r.Now())}, nil
234+
```
252235

253-
For a guide on Reconcilers, Clients, and interacting with resource Events, see the [Client API doc][doc_client_api].
236+
For more details, check the Reconcile and its [Reconcile godoc][reconcile-godoc].
254237

255238
### Specify permissions and generate RBAC manifests
256239

257-
The controller needs certain RBAC permissions to interact with the resources it manages. These are specified via [RBAC markers][rbac_markers] like the following:
240+
The controller needs certain [RBAC][rbac-k8s-doc] permissions to interact with the resources it manages. These are specified via [RBAC markers][rbac_markers] like the following:
258241

259242
```Go
260243
// +kubebuilder:rbac:groups=cache.example.com,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
@@ -284,15 +267,11 @@ There are three ways to run the operator:
284267

285268
### 1. Run locally outside the cluster
286269

287-
Execute the following command, which install your CRDs and run the manager locally:
288-
289-
```sh
290-
make install run ENABLE_WEBHOOKS=false
291-
```
270+
The following steps will show how to deploy the operator on the Cluster. However, to run locally for development purposes and outside of a Cluster use the target `make install run`.
292271

293272
### 2. Run as a Deployment inside the cluster
294273

295-
#### Build and push the image
274+
### Build and push the image
296275

297276
Before building the operator image, ensure the generated Dockerfile references
298277
the base image you want. You can change the default "runner" image `gcr.io/distroless/static:nonroot`
@@ -331,9 +310,6 @@ Run the following to deploy the operator. This will also install the RBAC manife
331310
make deploy IMG=quay.io/$USERNAME/memcached-operator:v0.0.1
332311
```
333312

334-
*NOTE* If you have enabled webhooks in your deployments, you will need to have cert-manager already installed
335-
in the cluster or `make deploy` will fail when creating the cert-manager resources.
336-
337313
Verify that the memcached-operator is up and running:
338314

339315
```console
@@ -368,7 +344,6 @@ operator-sdk run bundle $BUNDLE_IMG
368344

369345
Check out the [docs][quickstart-bundle] for a deep dive into `operator-sdk`'s OLM integration.
370346

371-
372347
## Create a Memcached CR
373348

374349
Update the sample Memcached CR manifest at `config/samples/cache_v1alpha1_memcached.yaml` and define the `spec` as the following:
@@ -454,12 +429,11 @@ make undeploy
454429

455430
## Further steps
456431

457-
The following guides build off the operator created in this example, adding advanced features:
458-
459-
- [Create a validating or mutating Admission Webhook][create_a_webhook]
460-
461-
Also see the [advanced topics][advanced_topics] doc for more use cases and under the hood details.
432+
Next, try adding the following to your project:
433+
1. Validating and mutating [admission webhooks][create_a_webhook].
434+
2. Operator packaging and distribution with [OLM][olm-integration].
462435

436+
Also see the [advanced topics][advanced_topics] doc for more use cases and under the hood details.
463437

464438
[legacy-quickstart-doc]:https://v0-19-x.sdk.operatorframework.io/docs/golang/legacy/quickstart/
465439
[migration-guide]:/docs/building-operators/golang/migration
@@ -493,8 +467,17 @@ Also see the [advanced topics][advanced_topics] doc for more use cases and under
493467
[create_a_webhook]: https://book.kubebuilder.io/cronjob-tutorial/webhook-implementation.html
494468
[status_marker]: https://book.kubebuilder.io/reference/generating-crd.html#status
495469
[status_subresource]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#status-subresource
496-
[env-test-setup]: /docs/building-operators/golang/references/envtest-setup
470+
[API-groups]:https://kubernetes.io/docs/concepts/overview/kubernetes-api/#api-groups
471+
[legacy_CLI]:https://v0-19-x.sdk.operatorframework.io/docs/cli/
497472
[role-based-access-control]: https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#iam-rolebinding-bootstrap
498473
[multigroup-kubebuilder-doc]: https://book.kubebuilder.io/migration/multi-group.html
499474
[quickstart-bundle]:/docs/olm-integration/quickstart-bundle
500475
[doc-olm]:/docs/olm-integration/quickstart-bundle/#enabling-olm
476+
[conditionals]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties
477+
[kubernetes-extend-api]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
478+
[reconcile-godoc]: https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/reconcile
479+
[rbac-k8s-doc]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
480+
[olm-integration]: /docs/olm-integration
481+
[openapi-validation]: /docs/building-operators/golang/references/openapi-validation
482+
[controller-runtime]: https://github.com/kubernetes-sigs/controller-runtime
483+
[kb-doc-gkvs]: https://book.kubebuilder.io/cronjob-tutorial/gvks.html

website/content/en/docs/building-operators/helm/tutorial.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ please [migrate][migration-guide], or consult the [legacy docs][legacy-quickstar
1313
- Go through the [installation guide][install-guide].
1414
- User authorized with `cluster-admin` permissions.
1515

16+
## Overview
17+
18+
We will create a sample project to let you know how it works and this sample will:
19+
20+
- Create a Memcached Deployment if it doesn't exist
21+
- Ensure that the Deployment size is the same as specified by the Memcached CR spec
22+
- Update the Memcached CR status using the status writer with the names of the memcached pods
23+
1624
## Create a new project
1725

1826
Use the CLI to create a new Helm-based nginx-operator project:

0 commit comments

Comments
 (0)
0