mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-26 21:30:55 +08:00
15b228f501
sources/tech/20210210 Configure multi-tenancy with Kubernetes namespaces.md
369 lines
12 KiB
Markdown
369 lines
12 KiB
Markdown
[#]: 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/
|