Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Manager Scope

Manager scope determines which namespace(s) your manager watches and manages resources in.

Overview

Kubebuilder supports three types of manager scope:

ScopeDescriptionUse Case
Cluster-scoped (default)Watches all namespaces in the clusterSingle manager managing resources cluster-wide
Namespace-scopedWatches only specific namespace(s)Multi-tenant, least-privilege deployments
Multi-namespaceWatches multiple specific namespacesManager managing resources in subset of namespaces

Manager scope is configured through:

  • RBAC resources (Role vs ClusterRole)
  • Cache configuration in cmd/main.go
  • WATCH_NAMESPACE environment variable

Cluster-Scoped (Default)

By default, Kubebuilder scaffolds cluster-scoped managers that watch all namespaces in the cluster.

kubebuilder init --domain example.com

Characteristics:

  • Uses ClusterRole and ClusterRoleBinding for RBAC
  • Manager watches all namespaces
  • No cache configuration needed

When to use:

  • Single manager instance for the entire cluster
  • Managing cluster-scoped resources (Nodes, ClusterRoles, Namespaces)
  • Simpler RBAC model when cluster-wide access is acceptable

Namespace-Scoped

Namespace-scoped managers watch only specific namespace(s), configured via the WATCH_NAMESPACE environment variable.

# New projects
kubebuilder init --domain example.com --namespaced

# Existing projects
kubebuilder edit --namespaced=true

Characteristics:

  • Uses namespace-scoped Role and RoleBinding for RBAC
  • Manager watches only specified namespace(s)
  • Requires cache configuration in cmd/main.go
  • Requires namespace= parameter in controller RBAC markers

When to use:

  • Multi-tenant environments (one manager per tenant/namespace)
  • Security policies requiring least-privilege access
  • Multiple manager instances in different namespaces

RBAC markers:

Controllers in namespace-scoped projects use the namespace= parameter in RBAC markers to generate namespace-scoped Role resources:

// +kubebuilder:rbac:groups=myapp.example.com,namespace=myproject-system,resources=mykinds,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=myapp.example.com,namespace=myproject-system,resources=mykinds/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=myapp.example.com,namespace=myproject-system,resources=mykinds/finalizers,verbs=update

When controller-gen sees the namespace= parameter, it generates kind: Role instead of kind: ClusterRole. The namespace field is added by kustomize during the build process (configured in config/default/kustomization.yaml).

Cache configuration:

Kubebuilder automatically scaffolds the cache configuration in cmd/main.go when using --namespaced flag:

// setupCacheNamespaces configures the cache to watch specific namespace(s).
// It supports both single namespace ("ns1") and multi-namespace ("ns1,ns2,ns3") formats.
func setupCacheNamespaces(namespaces string) cache.Options {
    defaultNamespaces := make(map[string]cache.Config)
    for ns := range strings.SplitSeq(namespaces, ",") {
        defaultNamespaces[strings.TrimSpace(ns)] = cache.Config{}
    }
    return cache.Options{
        DefaultNamespaces: defaultNamespaces,
    }
}

// In main()
watchNamespace, err := getWatchNamespace()
if err != nil {
    setupLog.Error(err, "Unable to get WATCH_NAMESPACE")
    os.Exit(1)
}

mgrOptions := ctrl.Options{
    Scheme:                 scheme,
    Metrics:                metricsServerOptions,
    WebhookServer:          webhookServer,
    HealthProbeBindAddress: probeAddr,
    LeaderElection:         enableLeaderElection,
    LeaderElectionID:       "your-leader-election-id",
}

// Configure cache to watch namespace(s) specified in WATCH_NAMESPACE
mgrOptions.Cache = setupCacheNamespaces(watchNamespace)
setupLog.Info("Watching namespace(s)", "namespaces", watchNamespace)

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), mgrOptions)

This configuration works for both single namespace (WATCH_NAMESPACE=my-namespace) and multi-namespace (WATCH_NAMESPACE=ns1,ns2,ns3) scenarios.

Multi-Namespace

Managers can watch multiple specific namespaces using comma-separated values in WATCH_NAMESPACE.

Characteristics:

  • Requires Role and RoleBinding in each watched namespace
  • Uses the same setupCacheNamespaces helper function
  • Same code as single-namespace mode (KISS principle)

Example:

# Deploy manager to watch multiple namespaces
export WATCH_NAMESPACE=namespace1,namespace2,namespace3
kubectl apply -f dist/install.yaml

The setupCacheNamespaces helper function automatically handles both single and multiple namespaces without conditional logic.

See Also