TranslateProject/sources/tech/20210210 Configure multi-tenancy with Kubernetes namespaces.md

369 lines
12 KiB
Markdown
Raw Normal View History

[#]: collector: (lujun9972)
[#]: translator: ( )
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Configure multi-tenancy with Kubernetes namespaces)
[#]: via: (https://opensource.com/article/21/2/kubernetes-namespaces)
[#]: author: (Mike Calizo https://opensource.com/users/mcalizo)
Configure multi-tenancy with Kubernetes namespaces
======
Namespaces provide basic building blocks of access control for
applications, users, or groups of users.
![shapes of people symbols][1]
Most enterprises want a multi-tenancy platform to run their cloud-native applications because it helps manage resources, costs, and operational efficiency and control [cloud waste][2].
[Kubernetes][3] is the leading open source platform for managing containerized workloads and services. It gained this reputation because of its flexibility in allowing operators and developers to establish automation with declarative configuration. But there is a catch: Because Kubernetes grows rapidly, the old problem of velocity becomes an issue. The bigger your adoption, the more issues and resource waste you discover.
### An example of scale
Imagine your company started small with its Kubernetes adoption by deploying a variety of internal applications. It has multiple project streams running with multiple developers dedicated to each project stream.
In a scenario like this, you need to make sure your cluster administrator has full control over the cluster to manage its resources and implement cluster policy and security standards. In a way, the admin is herding the cluster's users to use best practices. A namespace is very useful in this instance because it enables different teams to share a single cluster where computing resources are subdivided into multiple teams.
While namespaces are your first step to Kubernetes multi-tenancy, they are not good enough on their own. There are a number of Kubernetes primitives you need to consider so that you can administer your cluster properly and put it into a production-ready implementation.
The Kubernetes primitives for multi-tenancy are:
1. **RBAC:** Role-based access control for Kubernetes
2. **Network policies:** To isolate traffic between namespaces
3. **Resource quotas:** To control fair access to cluster resources
This article explores how to use Kubernetes namespaces and some basic RBAC configurations to partition a single Kubernetes cluster and take advantage of this built-in Kubernetes tooling.
### What is a Kubernetes namespace?
Before digging into how to use namespaces to prepare your Kubernetes cluster to become multi-tenant-ready, you need to know what namespaces are.
A [namespace][4] is a Kubernetes object that partitions a Kubernetes cluster into multiple virtual clusters. This is done with the aid of [Kubernetes names and IDs][5]. Namespaces use the Kubernetes name object, which means that each object inside a namespace gets a unique name and ID across the cluster to allow virtual partitioning.
### How namespaces help in multi-tenancy
Namespaces are one of the Kubernetes primitives you can use to partition your cluster into multiple virtual clusters to allow multi-tenancy. Each namespace is isolated from every other user's, team's, or application's namespace. This isolation is essential in multi-tenancy so that updates and changes in applications, users, and teams are contained within the specific namespace. (Note that namespace does not provide network segmentation.)
Before moving ahead, verify the default namespace in a working Kubernetes cluster:
```
[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   3d
kube-node-lease   Active   3d
kube-public       Active   3d
kube-system       Active   3d
```
Then create your first namespace, called **test**:
```
[root@master ~]# kubectl create namespace test
namespace/test created
```
Verify the newly created namespace:
```
[root@master ~]# kubectl get namespace
NAME              STATUS   AGE
default           Active   3d
kube-node-lease   Active   3d
kube-public       Active   3d
kube-system       Active   3d
test              Active   10s
[root@master ~]#
```
Describe the newly created namespace:
```
[root@master ~]# kubectl describe namespace test
Name:         test
Labels:       <none>
Annotations:  <none>
Status:       Active
No resource quota.
No LimitRange resource.
```
To delete a namespace:
```
[root@master ~]# kubectl delete namespace test
namespace "test" deleted
```
Your new namespace is active, but it doesn't have any labels, annotations, or quota-limit ranges defined. However, now that you know how to create and describe and delete a namespace, I'll show how you can use a namespace to virtually partition a Kubernetes cluster.
### Partitioning clusters using namespace and RBAC
Deploy the following simple application to learn how to partition a cluster using namespace and isolate an application and its related objects from "other" users.
First, verify the namespace you will use. For simplicity, use the **test** namespace you created above:
```
[root@master ~]# kubectl get namespaces
NAME              STATUS   AGE
default           Active   3d
kube-node-lease   Active   3d
kube-public       Active   3d
kube-system       Active   3d
test              Active   3h
```
Then deploy a simple application called **test-app** inside the test namespace by using the following configuration:
```
apiVersion: v1
kind: Pod
metadata:
  name: test-app                 ⇒ name of the application
  namespace: test                ⇒ the namespace where the app runs
  labels:
     app: test-app                      ⇒ labels for the app
spec:
  containers:
  - name: test-app
    image: nginx:1.14.2         ⇒ the image we used for the app.
    ports:
    - containerPort: 80
```
Deploy it:
```
$ kubectl create -f test-app.yaml
    pod/test-app created
```
Then verify the application pod was created:
```
$ kubectl get pods -n test
  NAME       READY   STATUS    RESTARTS   AGE
  test-app   1/1     Running   0          18s
```
Now that the running application is inside the **test** namespace, test a use case where:
* **auth-user** can edit and view all the objects inside the test namespace
* **un-auth-user** can only view the namespace
I pre-created the users for you to test. If you want to know how I created the users inside Kubernetes, view the commands [here][6].
```
$ kubectl config view -o jsonpath='{.users[*].name}'
  auth-user
  kubernetes-admin
  un-auth-user
```
With this set up, create a Kubernetes [Role and RoleBindings][7] to isolate the target namespace **test** to allow **auth-user** to view and edit objects inside the namespace and not allow **un-auth-user** to access or view the objects inside the **test** namespace.
Start by creating a ClusterRole and a Role. These objects are a list of verbs (action) permitted on specific resources and namespaces.
Create a ClusterRole:
```
$ cat clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: list-deployments
  namespace: test
rules:
  - apiGroups: [ apps ]
    resources: [ deployments ]
    verbs: [ get, list ]
```
Create a Role:
```
$ cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: list-deployments
  namespace: test
rules:
  - apiGroups: [ apps ]
    resources: [ deployments ]
    verbs: [ get, list ]
```
Apply the Role:
```
$ kubectl create -f role.yaml
roles.rbac.authorization.k8s.io "list-deployments" created
```
Use the same command to create a ClusterRole:
```
$ kubectl create -f clusterrole.yaml
$ kubectl get role -n test
  NAME               CREATED AT
  list-deployments   2021-01-18T00:54:00Z
```
Verify the Roles:
```
$ kubectl describe roles -n test
  Name:         list-deployments
  Labels:       <none>
  Annotations:  <none>
  PolicyRule:
    Resources         Non-Resource URLs  Resource Names  Verbs
    ---------         -----------------  --------------  -----
    deployments.apps  []                 []              [get list]
```
Remember that you must create RoleBindings by namespace, not by user. This means you need to create two role bindings for user **auth-user**.
Here are the sample RoleBinding YAML files to permit **auth-user** to edit and view.
**To edit:**
```
$ cat rolebinding-auth-edit.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: auth-user-edit
  namespace: test
subjects:
\- kind: User
  name: auth-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: edit
  apiGroup: rbac.authorization.k8s.io
```
**To view:**
```
$ cat rolebinding-auth-view.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: auth-user-view
  namespace: test
subjects:
\- kind: User
  name: auth-user
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io
```
Create these YAML files:
```
$ kubectl create rolebinding-auth-view.yaml
$ kubectl create rolebinding-auth-edit.yaml
```
Verify if the RoleBindings were successfully created:
```
$ kubectl get rolebindings -n test
NAME             ROLE               AGE
auth-user-edit   ClusterRole/edit   48m
auth-user-view   ClusterRole/view   47m
```
With the requirements set up, test the cluster partitioning:
```
[root@master]$ sudo su un-auth-user
[un-auth-user@master ~]$ kubect get pods -n test
[un-auth-user@master ~]$ kubectl get pods -n test
Error from server (Forbidden): pods is forbidden: User "un-auth-user" cannot list resource "pods" in API group "" in the namespace "test"
```
Log in as **auth-user**:
```
[root@master ]# sudo su auth-user
[auth-user@master auth-user]$ kubectl get pods -n test
NAME       READY   STATUS    RESTARTS   AGE
test-app   1/1     Running   0          3h8m
[auth-user@master un-auth-user]$
[auth-user@master auth-user]$ kubectl edit pods/test-app -n test
Edit cancelled, no changes made.
```
You can view and edit the objects inside the **test** namespace. How about viewing the cluster nodes?
```
[auth-user@master auth-user]$ kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "auth-user" cannot list resource "nodes" in API group "" at the cluster scope
[auth-user@master auth-user]$
```
You can't because the role bindings for user **auth-user** dictate they have access to view or edit objects only inside the **test** namespace.
### Enable access control with namespaces
Namespaces provide basic building blocks of access control using RBAC and isolation for applications, users, or groups of users. But using namespaces alone as your multi-tenancy solution is not enough in an enterprise implementation. It is recommended that you use other Kubernetes multi-tenancy primitives to attain further isolation and implement proper security.
Namespaces can provide some basic isolation in your Kubernetes cluster; therefore, it is important to consider them upfront, especially when planning a multi-tenant cluster. Namespaces also allow you to logically segregate and assign resources to individual users, teams, or applications.
By using namespaces, you can increase resource efficiencies by enabling a single cluster to be used for a diverse set of workloads.
--------------------------------------------------------------------------------
via: https://opensource.com/article/21/2/kubernetes-namespaces
作者:[Mike Calizo][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: https://opensource.com/users/mcalizo
[b]: https://github.com/lujun9972
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/Open%20Pharma.png?itok=GP7zqNZE (shapes of people symbols)
[2]: https://devops.com/the-cloud-is-booming-but-so-is-cloud-waste/
[3]: https://opensource.com/resources/what-is-kubernetes
[4]: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
[5]: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/
[6]: https://www.adaltas.com/en/2019/08/07/users-rbac-kubernetes/
[7]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/