A Guide to Implement Hierarchical Namespaces for Enhanced Cluster Management

A Guide to Implement Hierarchical Namespaces for Enhanced Cluster Management

Introduction: Hosting numerous users on a single Kubernetes cluster poses challenges due to varying organizational needs. Kubernetes provides building blocks like RBAC and NetworkPolicies for crafting custom tenancy models. Among these, namespaces play a pivotal role, forming the foundation for control plane security and sharing policies.

The Power of Namespaces: Namespaces are key to policy enforcement, representing ownership and controlling authorized creation and use. Objects like RBAC, NetworkPolicies, and ResourceQuotas align with namespaces by default. However, practical limitations arise in scenarios where flexibility is paramount.

Challenges with Vanilla Namespaces: Consider a scenario where a team manages multiple microservices, each requiring different secrets and quotas. Placing these services in separate namespaces is ideal for isolation, but issues arise. Vanilla namespaces lack a common ownership concept for teams managing multiple namespaces, hindering uniform policy application.

Overcoming Limitations with Hierarchical Namespaces: Enter hierarchical namespaces, a groundbreaking concept from the Kubernetes Working Group for Multi-Tenancy. Hierarchical namespaces introduce a small custom resource within a regular namespace, establishing a parent-child relationship. This ownership concept brings two crucial benefits:

Policy Inheritance: Child namespaces inherit policies like RBAC RoleBindings from their parent. Ensures uniform application of policies across namespaces, addressing ownership challenges.

Delegated Creation: Introduces subnamespaces, allowing limited-permission manipulation in the parent namespace. Enables teams to autonomously create subnamespaces without cluster admin intervention.

Solving Dev Team Challenges: Hierarchical namespaces offer a solution for development teams. Cluster administrators can create a root namespace with necessary policies, and then delegate subnamespace creation to team members. This empowers teams to create and manage their namespaces within the defined policies, reducing administrative toil.

Installing HNC Plugin

# Select the latest version of HNC
#HNC_VERSION=v1.1.0
#HNC_VARIANT=default
#kubectl apply -f https://github.com/kubernetes-sigs/hierarchical-namespaces/releases/download/${HNC_VERSION}/${HNC_VARIANT}.yaml 

#kubectl krew update
#kubectl krew install hns

# Ensure the plugin is working
#kubectl hns

Hands-on with hierarchical namespaces

Lets Create namespace

#kubectl create ns test

Lets Create Subnamespace subtest in namespace test

#kubectl hns create subtest -n test

We can view the structure of these namespaces by asking for a tree view

#kubectl hns tree test
test
└── [s] subtest

Lets create Role and Role Binding and attach it to test namespace

#cat role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: test
  name: example-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "create", "delete"]


#cat rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: example-rolebinding
  namespace: test
subjects:
- kind: User
  name: "user1"  # replace with the actual username
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role  # or ClusterRole
  name: example-role
  apiGroup: rbac.authorization.k8s.io

#kubectl apply -f role.yaml
#kubectl apply -f rolebinding.yaml

Lets verify

# kubectl describe rolebinding example-rolebinding -n test
Name:         example-rolebinding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  example-role
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  user1

We did not apply the Role and Rolebinding on subnamespace, lets verify did the Role and Rolebinding get inherited

# kubectl describe rolebinding example-rolebinding -n subtest
Name:         example-rolebinding
Labels:       app.kubernetes.io/managed-by=hnc.x-k8s.io
              hnc.x-k8s.io/**inherited-from=test**
Annotations:  <none>
Role:
  Kind:  Role
  Name:  example-role
Subjects:
  Kind  Name   Namespace
  ----  ----   ---------
  User  user1

Finally, HNC adds labels to these namespaces with useful information about the hierarchy which you can use to apply other policies

For example, you can create the following NetworkPolicy:

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-team-a
  namespace: team-a
spec:
  ingress:
  - from:
    - namespaceSelector:
        matchExpressions:
          - key: 'team-a.tree.hnc.x-k8s.io/depth' # Label created by HNC
            operator: Exists

This policy will both be propagated to all descendants of test, and will also allow ingress traffic between all of those namespaces. The “tree” label can only be applied by HNC, and is guaranteed to reflect the latest hierarchy.


Author: CloudOpsKube

New Blog By CloudOpsKube