Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 44 additions & 55 deletions website/content/en/docs/building-operators/golang/crds-scope.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,69 +6,54 @@ weight: 60

## Overview

The CustomResourceDefinition (CRD) scope can also be changed for cluster-scoped operators so that there is only a single
instance (for a given name) of the Custom Resource (CR) to manage across the cluster.
This page details the various methods to control the scope of a CRD. See the [operator scope doc](/docs/building-operators/golang/operator-scope/) for information on configuring operator scope, such as which namespaces to watch.

The CRD manifests are generated in `config/crd/bases`. For each CRD that needs to be cluster-scoped, its manifest
should specify `spec.scope: Cluster`.
Custom Resource Definitions (CRDs) contain a scope field that determines whether the resulting Custom Resource (CR)
is cluster or namespace scoped. An operator author might use a namespaced-scoped CRD
to restrict access to a CR to certain namespaces, or to have different versions of CRs accessible in different namespaces.
Alternatively, an operator author might want a cluster-scoped CRD so all namespaces have visibility and access to CRs.

To ensure that the CRD is always generated with `scope: Cluster`, add the marker
`//+kubebuilder:resource:path=<resource>,scope=Cluster`, or if already present replace `scope={Namespaced -> Cluster}`,
above the CRD's Go type definition in `api/<version>/<kind>_types.go` or `apis/<group>/<version>/<kind>_types.go`
if you are using the [multigroup][multigroup-kubebuilder-doc] layout. Note that the `<resource>`
element must be the same lower-case plural value of the CRD's Kind, `spec.names.plural`.
The CRD manifests are generated by the `operator-sdk create api` command in `config/crd/bases`. A CRD's `spec.scope` field controls API scope; valid values are [`Cluster` and `Namespaced`](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#create-a-customresourcedefinition).
For an Operator-sdk Go project, this value is determined by the `operator-sdk create api --namespaced` boolean flag, which edits the
`types.go` file for the resource. For other operator types, the command edits `spec.scope` in the CRD's YAML manifest directly.

**NOTE**: When a `Manager` instance is created in the `main.go` file, it receives the namespace(s) as Options.
These namespace(s) should be watched and cached for the Client which is provided by the Controllers. Only clients
provided by cluster-scoped projects where the `Namespace` attribute is `""` will be able to manage cluster-scoped CRs.
For more information see the [Manager][manager_user_guide] topic in the user guide and the
[Manager Options][manager_options].
## Set `create api` --namespaced flag

## Example for changing the CRD scope from Namespaced to Cluster
When creating a new API, the `--namespaced` flag controls whether the resulting CRD will be cluster or namespace scoped.
By default, `--namespaced` is set to `true` which sets the scope to `Namespaced`. An example command to create a cluster-scoped API would be:

- Check the `spec.names.plural` in the CRD's Kind YAML file
```console
$ operator-sdk create api --group cache --version v1alpha1 --kind Memcached --resource=true --controller=true --namespaced=false
```

* `/config/crd/bases/cache.example.com_memcacheds.yaml`
```YAML
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.5
creationTimestamp: null
name: memcacheds.cache.example.com
spec:
group: cache.example.com
names:
kind: Memcached
listKind: MemcachedList
plural: memcacheds
singular: memcached
scope: Namespaced
subresources:
status: {}
...
```
## Set Scope Marker in types.go
Comment thread
estroz marked this conversation as resolved.

- Update the `apis/<version>/<kind>_types.go` by adding the
marker `//+kubebuilder:resource:path=<resource>,scope=Cluster`
You can also manually set the scope in the Go `types.go` file by adding or changing the [kubebuilder scope marker][kubebuilder_crd_markers]
to your resource. This file is usually located in `api/<version>/<kind>_types.go` or `apis/<group>/<version>/<kind>_types.go` if
you are using the [multigroup][multigroup-kubebuilder-doc] layout. Once this marker is set, the CRD files will be generated with the approriate scope.
Here is an example API type with the marker set to cluster scope:

* `api/v1alpha1/memcached_types.go`
```golang
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:scope=Cluster

```Go
// Memcached is the Schema for the memcacheds API
//+kubebuilder:resource:path=memcacheds,scope=Cluster
type Memcached struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec MemcachedSpec `json:"spec,omitempty"`
Status MemcachedStatus `json:"status,omitempty"`
Spec MemcachedSpec `json:"spec,omitempty"`
Status MemcachedStatus `json:"status,omitempty"`
}
```
- Run `make manifests`, to update the CRD manifest with the cluster scope setting, as in the following example:

* `/config/crd/bases/cache.example.com_memcacheds.yaml`
```
To set the scope to namespaced, the marker would be set to `//+kubebuilder:resource:scope=Namespace` instead.


## Set scope in CRD YAML file
Comment thread
estroz marked this conversation as resolved.

The scope can be manually set directly in the CRD's Kind YAML file, normally located in `config/crd/bases/<group>.<domain>_<kind>.yaml`.
An example YAML file for a namespace-scoped CRD is shown below:

```YAML
apiVersion: apiextensions.k8s.io/v1beta1
Expand All @@ -85,13 +70,17 @@ spec:
listKind: MemcachedList
plural: memcacheds
singular: memcached
scope: Cluster
scope: Namespaced
subresources:
status: {}
...
```
[RBAC]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/
[manager_user_guide]:/docs/building-operators/golang/tutorial/#manager



[manager_options]: https://godoc.org/github.com/kubernetes-sigs/controller-runtime/pkg/manager#Options
[multigroup-kubebuilder-doc]: https://book.kubebuilder.io/migration/multi-group.html
[manager_user_guide]:/docs/building-operators/golang/tutorial/#manager
[k8s_crd_scope]: https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#create-a-customresourcedefinition
[kubebuilder_crd_markers]: https://book.kubebuilder.io/reference/markers/crd.html
[kubebuilder_multigroup]: https://book.kubebuilder.io/migration/multi-group.html
[RBAC]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/