Configuring namespaces and namespace-scoped objects

This page illustrates how to use Config Sync to manage namespaces and namespace-scoped objects. You can also read about configuring clusters and cluster-scoped objects.

Configuring a namespace

All configs for namespaces and namespace-scoped objects are located within the namespaces/ directory of the repo and its descendant directories.

Follow these steps to configure a namespace called audit in each enrolled cluster.

  1. In the local clone of the repo, create a namespace directory. A namespace directory contains a config for a namespace. The name of the namespace directory must match the name of the namespace. In this example, the directory is called namespaces/audit:

    mkdir namespaces/audit
  2. In the namespace directory, create a file audit.yaml, with the following contents. The must match the name of the namespace (and the name of the namespace directory).

    apiVersion: v1
    kind: Namespace
      name: audit
  3. Create a commit that includes the audit.yaml config, and push the commit to the remote repository.

    git add namespaces/audit/audit.yaml
    git commit -m "Created audit namespace config"
  4. In a few moments, the audit namespace is created in each enrolled cluster. To verify, describe the namespace:

    kubectl describe namespace audit
  5. To remove the config and delete the audit namespace from enrolled clusters, you can create a new commit that removes the file, and push it to the remote repository.

Configuring an abstract namespace

This example extends the example in configuring a namespace by moving the audit namespace directory into an abstract namespace containing additional configs inherited by the audit namespace.

  1. In the local clone of the repo, create an abstract namespace directory called regulatory. An abstract namespace directory does not contain a config for a namespace, but its descendant namespace directories do.

    mkdir namespaces/regulatory
  2. In the regulatory abstract namespace directory, create a config for a Role called regulator, that grants get and list on all resources in any namespace that eventually inherits the Role.

    # namespaces/regulatory/regulator_role.yaml
    kind: Role
      name: regulator
    - apiGroups: [""]
      resources: ["*"]
      verbs: ["get", "list"]
  3. Create a config for a RoleBinding called regulatory-admin that binds the regulator Role to group

    # namespaces/regulatory/regulator_rolebinding.yaml
    kind: RoleBinding
      name: regulatory-admin
    - kind: Group
      kind: Role
      name: regulator
  4. Move the audit namespace directory from the namespaces/ to the namespaces/regulatory/ directory:

    mv namespaces/audit/ namespaces/regulatory/
  5. Commit all of your changes and push them to the remote for the repo.

The Config Sync Operator notices the change and applies the new Role and RoleBinding to the audit namespace on all enrolled clusters.

To remove the configs and delete the audit namespace from enrolled clusters, you can create a new commit that removes the entire regulatory abstract namespace, and push it to the remote repository.

Limiting which clusters a config affects

Normally, Config Sync applies a config to each enrolled cluster. If the config is within the namespaces/ subdirectory, Config Sync first creates the namespace within each cluster and then applies all inherited configs to that namespace.

To limit which clusters a particular config affects based on each cluster's labels, refer to Applying configs to a subset of clusters.

Limiting which namespaces a config affects

A NamespaceSelector is a special type of config that uses Kubernetes labelSelectors. You can use a NamespaceSelector in combination with a config in namespaces/ to limit which namespaces can inherit that config.

NamespaceSelectors are similar to but not identical to ClusterSelectors. A NamespaceSelector narrows the pool of namespaces that can inherit a given config from an abstract namespace, regardless of the directory structure of the namespaces/ directory. A ClusterSelector narrows the pool of clusters a config applies to, whether the config targets a cluster-scoped or namespace-scoped object.

NamespaceSelector location

You can place NamespaceSelectors in any abstract namespace directory, but not in a namespace directory.

The following example repository shows you valid and invalid locations for NamespaceSelectors:

├── namespaces
│   ├── ns_selector.yaml  # valid
|   ├──audit
|   |   ├── namespace.yaml
|   |   └── ns_selector.yaml  # invalid
|   └──shipping-app-backend
|       ├── ns_selector.yaml  # valid
|       └── shipping-prod
|           ├──namespace.yaml
|           └──ns_selector.yaml # invalid

Since the namespaces and shipping-app-backend directories represent abstract namespaces, you can put a selector in them. However, because the audit and shipping-prod directories represent actual namespaces, you can't put a NamespaceSelector in them.

Using a NamespaceSelector

The following config creates a NamespaceSelector called sre-supported. If another config references this NamespaceSelector, that config can only be applied to objects in namespaces that have the env: prod label.

kind: NamespaceSelector
  name: sre-supported
      env: prod

To reference a NamespaceSelector in a config, you set the annotation to the name of the NamespaceSelector.

A NamespaceSelector has no effect until you reference it in another config. If the sre-supported NamespaceSelector is in the same hierarchy as the following RoleBinding, sre-admin, the RoleBinding is only created in namespaces that have the env: prod label:

kind: RoleBinding
  name: sre-admin
  annotations: sre-supported
- kind: Group
  kind: ClusterRole
  name: admin

To summarize, using a NamespaceSelector is a three-step process:

  1. Add labels to namespaces.
  2. Create a NamespaceSelector config.
  3. Reference the NamespaceSelector object in another config.

Disabling inheritance for an object type

You can selectively disable inheritance for any config by setting the hierarchyMode field to none. HierarchyConfigs are stored in the system/ directory of the repo. This example disables inheritance for RoleBindings.

# system/hierarchy-config.yaml
kind: HierarchyConfig
  name: rbac
  # Configure Role to only be allowed in leaf namespaces.
  - group:
    kinds: [ "RoleBinding" ]
    hierarchyMode: none

What's next