Operators and CRD scope with Operator SDK
Overview
A namespace-scoped operator watches and manages resources in a single namespace, whereas a cluster-scoped operator watches and manages resources cluster-wide. Namespace-scoped operators are preferred because of their flexibility. They enable decoupled upgrades, namespace isolation for failures and monitoring, and differing API definitions.
However, there are use cases where a cluster-scoped operator may make sense. For example, the cert-manager operator is often deployed with cluster-scoped permissions and watches so that it can manage issuing certificates for an entire cluster.
NOTE: CustomResourceDefinition (CRD) scope can also be changed to cluster-scoped. See the CRD scope document for more details.
Namespace-scoped operator usage
This scope is ideal for operator projects which will control resources just in one namespace, which is where the operator is deployed.
NOTE: Projects created by operator-sdk
are namespace-scoped by default which means that they will NOT have a ClusterRole
defined in deploy/
.
Cluster-scoped operator usage
This scope is ideal for operator projects which will control resources in more than one namespace.
Changes required for a cluster-scoped operator
The SDK scaffolds operators to be namespaced by default but with a few modifications to the default manifests the operator can be run as cluster-scoped.
deploy/operator.yaml
:- Set
WATCH_NAMESPACE=""
to watch all namespaces instead of setting it to the pod’s namespace - Set
metadata.namespace
to define the namespace where the operator will be deployed.
- Set
deploy/role.yaml
:- Use
ClusterRole
instead ofRole
- Use
deploy/role_binding.yaml
:- Use
ClusterRoleBinding
instead ofRoleBinding
- Use
ClusterRole
instead ofRole
forroleRef
- Set the subject namespace to the namespace in which the operator is deployed.
- Use
deploy/service_account.yaml
:- Set
metadata.namespace
to the namespace where the operator is deployed.
- Set
Example for cluster-scoped operator
With the above changes the specified manifests should look as follows:
deploy/operator.yaml
:apiVersion: apps/v1
kind: Deployment
metadata:
name: memcached-operator
namespace: <operator-namespace>
...
spec:
...
template:
...
spec:
...
serviceAccountName: memcached-operator
containers:
- name: memcached-operator
...
env:
- name: WATCH_NAMESPACE
value: ""
deploy/role.yaml
:apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: memcached-operator
...
deploy/role_binding.yaml
:kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: memcached-operator
subjects:
- kind: ServiceAccount
name: memcached-operator
namespace: <operator-namespace>
roleRef:
kind: ClusterRole
name: memcached-operator
apiGroup: rbac.authorization.k8s.io
deploy/service_account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: memcached-operator
namespace: <operator-namespace>
Last modified May 26, 2020: doc: add operator-scope kb layout (#2982) (795c8b58)