From d0ea3b7b3aaa941e437a750acb420f2b05aca3f2 Mon Sep 17 00:00:00 2001 From: Adrian Ludwin Date: Fri, 14 Aug 2020 11:28:21 -0400 Subject: [PATCH] Blog: introducing hierarchical namespaces (#23079) * Blog: introducing hierarchical namespaces * Made suggested changes by sftim * Change date to Aug 14 --- ...-14-introducing-hierarchical-namespaces.md | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 content/en/blog/_posts/2020-08-14-introducing-hierarchical-namespaces.md diff --git a/content/en/blog/_posts/2020-08-14-introducing-hierarchical-namespaces.md b/content/en/blog/_posts/2020-08-14-introducing-hierarchical-namespaces.md new file mode 100644 index 00000000000..3778240f6c8 --- /dev/null +++ b/content/en/blog/_posts/2020-08-14-introducing-hierarchical-namespaces.md @@ -0,0 +1,199 @@ +--- +layout: blog +title: "Introducing Hierarchical Namespaces" +date: 2020-08-14 +--- + +**Author**: Adrian Ludwin (Google) + +Safely hosting large numbers of users on a single Kubernetes cluster has always +been a troublesome task. One key reason for this is that different organizations +use Kubernetes in different ways, and so no one tenancy model is likely to suit +everyone. Instead, Kubernetes offers you building blocks to create your own +tenancy solution, such as Role Based Access Control (RBAC) and NetworkPolicies; +the better these building blocks, the easier it is to safely build a multitenant +cluster. + +# Namespaces for tenancy + +By far the most important of these building blocks is the namespace, which forms +the backbone of almost all Kubernetes control plane security and sharing +policies. For example, RBAC, NetworkPolicies and ResourceQuotas all respect +namespaces by default, and objects such as Secrets, ServiceAccounts and +Ingresses are freely usable _within_ any one namespace, but fully segregated +from _other_ namespaces. + +Namespaces have two key properties that make them ideal for policy enforcement. +Firstly, they can be used to **represent ownership**. Most Kubernetes objects +_must_ be in a namespace, so if you use namespaces to represent ownership, you +can always count on there being an owner. + +Secondly, namespaces have **authorized creation and use**. Only +highly-privileged users can create namespaces, and other users require explicit +permission to use those namespaces - that is, create, view or modify objects in +those namespaces. This allows them to be carefully created with appropriate +policies, before unprivileged users can create “regular” objects like pods and +services. + +# The limits of namespaces + +However, in practice, namespaces are not flexible enough to meet some common use +cases. For example, let’s say that one team owns several microservices with +different secrets and quotas. Ideally, they should place these services into +different namespaces in order to isolate them from each other, but this presents +two problems. + +Firstly, these namespaces have no common concept of ownership, even though +they’re both owned by the same team. This means that if the team controls +multiple namespaces, not only does Kubernetes not have any record of their +common owner, but namespaced-scoped policies cannot be applied uniformly across +them. + +Secondly, teams generally work best if they can operate autonomously, but since +namespace creation is highly privileged, it’s unlikely that any member of the +dev team is allowed to create namespaces. This means that whenever a team wants +a new namespace, they must raise a ticket to the cluster administrator. While +this is probably acceptable for small organizations, it generates unnecessary +toil as the organization grows. + +# Introducing hierarchical namespaces + +[Hierarchical +namespaces](https://github.com/kubernetes-sigs/multi-tenancy/blob/master/incubator/hnc/docs/user-guide/concepts.md#basic) +are a new concept developed by the [Kubernetes Working Group for Multi-Tenancy +(wg-multitenancy)](https://github.com/kubernetes-sigs/multi-tenancy) in order to +solve these problems. In its simplest form, a hierarchical namespace is a +regular Kubernetes namespace that contains a small custom resource that +identifies a single, optional, parent namespace. This establishes the concept of +ownership _across_ namespaces, not just _within_ them. + +This concept of ownership enables two additional types of behaviours: + +* **Policy inheritance:** if one namespace is a child of another, policy objects + such as RBAC RoleBindings are [copied from the parent to the + child](https://github.com/kubernetes-sigs/multi-tenancy/blob/master/incubator/hnc/docs/user-guide/concepts.md#basic-propagation). +* **Delegated creation:** you usually need cluster-level privileges to create a + namespace, but hierarchical namespaces adds an alternative: + [_subnamespaces_](https://github.com/kubernetes-sigs/multi-tenancy/blob/master/incubator/hnc/docs/user-guide/concepts.md#basic-subns), + which can be manipulated using only limited permissions in the parent + namespace. + +This solves both of the problems for our dev team. The cluster administrator can +create a single “root” namespace for the team, along with all necessary +policies, and then delegate permission to create subnamespaces to members of +that team. Those team members can then create subnamespaces for their own use, +without violating the policies that were imposed by the cluster administrators. + +# Hands-on with hierarchical namespaces + +Hierarchical namespaces are provided by a Kubernetes extension known as the +[**Hierarchical Namespace +Controller**](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/incubator/hnc), +or **HNC**. The HNC consists of two components: + +* The **manager** runs on your cluster, manages subnamespaces, propagates policy + objects, ensures that your hierarchies are legal and manages extension points. +* The **kubectl plugin**, called `kubectl-hns`, makes it easy for users to + interact with the manager. + +Both can be easily installed from the [releases page of our +repo](https://github.com/kubernetes-sigs/multi-tenancy/releases). + +Let’s see HNC in action. Imagine that I do not have namespace creation +privileges, but I can view the namespace `team-a` and create subnamespaces +within it[1](#note-1). Using the plugin, I can now say: + +```bash +$ kubectl hns create svc1-team-a -n team-a +``` + +This creates a subnamespace called `svc1-team-a`. Note that since subnamespaces +are just regular Kubernetes namespaces, all subnamespace names must still be +unique. + +I can view the structure of these namespaces by asking for a tree view: + +```bash +$ kubectl hns tree team-a +# Output: +team-a +└── svc1-team-a +``` + +And if there were any policies in the parent namespace, these now appear in the +child as well[2](#note-2). For example, let’s say that `team-a` had +an RBAC RoleBinding called `sres`. This rolebinding will also be present in the +subnamespace: + +```bash +$ kubectl describe rolebinding sres -n svc1-team-a +# Output: +Name: sres +Labels: hnc.x-k8s.io/inheritedFrom=team-a # inserted by HNC +Annotations: +Role: + Kind: ClusterRole + Name: admin +Subjects: ... +``` + +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: + +```yaml +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 `team-a`, 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. + +You can learn all about the features of HNC from the [user +guide](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/incubator/hnc/docs/user-guide). + +# Next steps and getting involved + +If you think that hierarchical namespaces can work for your organization, [HNC +v0.5.1 is available on +GitHub](https://github.com/kubernetes-sigs/multi-tenancy/releases/tag/hnc-v0.5.1). +We’d love to know what you think of it, what problems you’re using it to solve +and what features you’d most like to see added. As with all early software, you +should be cautious about using HNC in production environments, but the more +feedback we get, the sooner we’ll be able to drive to HNC 1.0. + +We’re also open to additional contributors, whether it’s to fix or report bugs, +or help prototype new features such as exceptions, improved monitoring, +hierarchical resource quotas or fine-grained configuration. + +Please get in touch with us via our +[repo](https://github.com/kubernetes-sigs/multi-tenancy), [mailing +list](https://groups.google.com/g/kubernetes-wg-multitenancy) or on +[Slack](https://kubernetes.slack.com/messages/wg-multitenancy) - we look forward +to hearing from you! + +--- + +_[Adrian Ludwin](https://twitter.com/aludwin) is a software engineer and the +tech lead for the Hierarchical Namespace Controller._ + + + +_Note 1: technically, you create a small object called a "subnamespace anchor" +in the parent namespace, and then HNC creates the subnamespace for you._ + + + +_Note 2: By default, only RBAC Roles and RoleBindings are propagated, but you +can configure HNC to propagate any namespaced Kubernetes object._