Sync objects to multiple namespaces

This page explains how to use Config Sync to manage namespaces andchoose which objects Config Sync syncs to your namespaces.

Kubernetes resource objects can either be cluster-scoped or namespace-scoped,depending on the resource type. You select the cluster by configuring your clientto talk to a specific cluster. You select the namespace by configuring themetadata.namespace field in the object manifest. Config Sync adds additionalcapabilities: cluster selectors and namespace selectors, which let you further refinewhich objects are synced.

Before reading this page, you should already be familiar with the followingKubernetes concepts:

About scoping objects with Config Sync

By default, when you install Config Syncon a cluster or as a fleet default, Config Syncsyncsall of the Kubernetes objects in yoursource of truth to clusters withConfig Sync installed or all clusters in a fleet. But,byscoping objects to a cluster or namespace, you can controlwhich objects are synced to a cluster or namespace.

Config Sync offersthe following methods to scope your objects:

Use explicit namespaces

We recommend that you use explicit namespace declaration when configuring Config Syncbecause it lets you manage namespace metadata and delete namespaces later, if needed.

The default setting isimplicit, but you can change the namespace strategy in yourRootSync orRepoSync object by setting thenamespaceStrategy field toexplicit. For more information, seenamespace strategy.

About namespace selectors

Namespace selectors are a feature of Config Sync that let you deployotherwise identical resource objects into multiple namespaces.

Using namespace selectors is similar to usingKubernetes label selectorsto map a Service to a set of Pods, but with an extra layer of indirection.Because you can't add custom fields to existing resource types, you instead defineyour selector in aNamespaceSelector object. Then, you reference that selectorby name in an annotation on the objects that you want to use that selector.

To use namespace selectors:

  1. Add or choose an existing label on the namespaces to which you want to deploy.
  2. Define aNamespaceSelector resource object in your source of truth.Config Sync does not syncNamespaceSelector objects to your cluster.
  3. For each object that you want to sync to one or more namespaces, modify the object'sconfiguration to remove themetadata.namespace field and add theconfigmanagement.gke.io/namespace-selector annotation with a value thatmatches themetadata.name of yourNamespaceSelector.

The examples in the subsequent section provide more details on how to defineNamespaceSelector objects and annotate other objects to use theNamespaceSelector.

Before you begin

Use namespace selectors

Namespace selectors are defined either withequality-based requirements orset-based requirements. You can combinemultiple requirements.

Equality-based label selector example

The following example shows how to use equality-based selectors to select which namespacesa configuration applies to:

  1. Add a label to one or more namespaces:

    kubectllabelnamespaceNAMESPACEapp=gamestore

    ReplaceNAMESPACE with the name of your namespace.

    Run this command for each namespace that you want to label.

  2. Create a namespace selector calledgamestore-selector.

    kind:NamespaceSelectorapiVersion:configmanagement.gke.io/v1metadata:name:gamestore-selectorspec:selector:matchLabels:app:gamestore

    If another object's configuration references this namespace selector, that configuration can only beapplied to objects in namespaces that have theapp: gamestore label.

  3. A namespace selector has no effect until you reference it in another configuration.Create an example object quota that references the namespace selector:

    kind:ResourceQuotaapiVersion:v1metadata:name:quotaannotations:configmanagement.gke.io/namespace-selector:gamestore-selectorspec:hard:pods:"1"cpu:"200m"memory:"200Mi"

    The resource quota is created only in namespaces that have theapp: gamestore label.

Set-based label selector example

The following example shows how to use set-based selectors to exempt namespacesfrom inheriting objects:

  1. Add a label to one or more namespaces:

    kubectllabelnamespaceNAMESPACEquota-exempt=exempt

    ReplaceNAMESPACE with the name of your namespace.

    Run this command for each namespace that you want to label.

  2. Create a namespace selector calledexclude-exempt-namespaces:

    kind:NamespaceSelectorapiVersion:configmanagement.gke.io/v1metadata:name:excludes-exempt-namespacesspec:selector:matchExpressions:-key:quota-exemptoperator:NotInvalues:-exempt

    If another object's configuration references this namespace selector, thatconfiguration is applied to all namespacesexcept those with thequota-exempt: exempt key-value pair.

  3. A namespace selector has no effect until you reference it in another configuration.Create an example object quota that references the namespace selector:

    kind:ResourceQuotaapiVersion:v1metadata:name:quotaannotations:configmanagement.gke.io/namespace-selector:exclude-exempt-namespacesspec:hard:pods:"1"cpu:"200m"memory:"200Mi"

    The resource quota is created in all namespaces except those that havethequota-exempt: exempt key-value pair.

Integration with team scopes and fleet namespaces

Fleet namespaces created in Google Cloud automatically have thefleet.gke.io/fleet-scope: your-scope label. All namespaces also have the Kuberneteskubernetes.io/metadata.name: your-namespace label. You can use these defaultlabels to set up a namespace selector for selecting fleet namespaces.

Thefleet tenancy tutorialexplains in more detail how to use namespace selectorswith fleets and team scopes to selectively manage objects for different teams.

Namespace-scoped objects with hierarchical mode

Although unstructured repositories are recommended for most use cases,you can use namespace selectorsto scope your objects with a hierarchical repository. The use of namespaceselectors is the same, but there are additional limitations and requirementsfor how you organize your namespace configuration in your source of truth.

Limitations

When you use a namespace selector configuration with a hierarchical repository,be aware of the following limitations and requirements:

  • You must store all configuration files for namespaces and namespace-scoped objects within thenamespaces/ directory of thehierarchical repository and itsdescendant directories.
  • You must explicitly specify a namespace configuration inthenamespaces/NAMESPACE subdirectory, whereNAMESPACEmatches the name of the namespace. All other namespace-scoped objects mustbe stored in the same subdirectory. If a namespace configuration is missing,Config Sync returns a KNV1044 error.
  • Resources that reference a namespace selectorare applied to namespaces that inherit a given configuration from anabstract namespace, regardless of the directory structure of thenamespaces/directory.

Namespace selector location

In a hierarchical repository, you can place anamespace selector configuration in anyabstract namespace directory, but not in anamespace directory.

The following example repository architecture shows valid and invalidlocations for namespace selectors:

namespace-inheritance...├── namespaces│   ├── eng│   │   ├── gamestore│   │   │   ├── namespace.yaml│   │   │   └── ns_selector.yaml  # invalid│   │   └── ns_selector.yaml  # valid│   ├── ns_selector.yaml  # valid│   ├── rnd│   │   ├── incubator-1│   │   │   ├── namespace.yaml│   │   │   └── ns_selector.yaml  # invalid│   │   └── ns_selector.yaml  # valid

Because thenamespaces,eng, andrnd directories represent abstractnamespaces, you can put a selector in them. However, because thegamestore andincubator-1 directories represent actual namespaces, you can't put anamespace selector in them.

Configure an abstract namespace

With a hierarchical repository, you can optionally use abstract namespaces.

The following example shows how to move your namespace directory into an abstract namespacethat contains additional configurations inherited by the namespace:

  1. In your repository, create an abstract namespace directory. The abstractnamespace directory doesn't contain any configurations for namespaces,but the descendant namespace directories do contain configurations.

  2. In the abstract namespace directory that you created, create a configuration for a Rolethat grantsget andlist permissions on all objects in anynamespace that eventually inherits the Role:

    apiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:name:ROLE_NAMErules:-apiGroups:[""]resources:["*"]verbs:["get","list"]

    ReplaceROLE_NAME with the name of the role.

  3. Create a configuration for a role binding that binds therole to an email group:

    kind:RoleBindingapiVersion:rbac.authorization.k8s.io/v1metadata:name:ROLE_NAMEsubjects:-kind:Groupname:group@example.comapiGroup:rbac.authorization.k8s.ioroleRef:kind:Rolename:ROLEBINDING_NAMEapiGroup:rbac.authorization.k8s.io

    ReplaceROLEBINDING_NAME with the name of the Role.

  4. Move the namespace configuration that youcreated in the previous section from thenamespaces/ directory to theabstract namespace directory that you created in this section.

Disable inheritance for objects

You can selectively disable inheritance for any configuration by setting thehierarchyMode field tonone. HierarchyConfigs are stored in thesystem/directory of the repository. This example disables inheritance for role bindings:

# system/hierarchy-config.yamlkind:HierarchyConfigapiVersion:configmanagement.gke.io/v1metadata:name:rbacspec:resources:# Configure role to only be allowed in leaf namespaces.-group:rbac.authorization.k8s.iokinds:["RoleBinding"]hierarchyMode:none

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-15 UTC.