大多数企业都希望拥有一个多租户平台来运行他们的云原生应用程序,因为它有助于管理资源、成本和运营效率,并控制 云浪费。
Kubernetes 是领先的开源平台,用于管理容器化的工作负载和服务。 它之所以获得这一声誉,是因为它在允许运营商和开发人员通过声明式配置建立自动化方面的灵活性。 但有一个问题:由于 Kubernetes 发展迅速,旧的速度问题再次出现。 你的采用规模越大,你发现的问题和资源浪费就越多。
规模示例
想象一下,你的公司最初通过部署各种内部应用程序来小规模采用 Kubernetes。 它有多个项目流在运行,每个项目流都有多个开发人员。
在这种情况下,你需要确保你的集群管理员完全控制集群,以管理其资源并实施集群策略和安全标准。 在某种程度上,管理员正在引导集群的用户使用最佳实践。 在这种情况下,命名空间非常有用,因为它使不同的团队可以共享一个集群,其中计算资源被细分为多个团队。
虽然命名空间是你迈向 Kubernetes 多租户的第一步,但它们本身并不够好。 你需要考虑许多 Kubernetes 原语,以便你可以正确管理你的集群并将其投入到生产就绪的实施中。
用于多租户的 Kubernetes 原语是
- RBAC: Kubernetes 的基于角色的访问控制
- 网络策略: 用于隔离命名空间之间的流量
- 资源配额: 用于控制对集群资源的公平访问
本文探讨了如何使用 Kubernetes 命名空间和一些基本的 RBAC 配置来划分单个 Kubernetes 集群,并利用这种内置的 Kubernetes 工具。
什么是 Kubernetes 命名空间?
在深入研究如何使用命名空间来准备你的 Kubernetes 集群以使其成为多租户就绪之前,你需要知道什么是命名空间。
命名空间是一个 Kubernetes 对象,它将 Kubernetes 集群划分为多个虚拟集群。 这是借助 Kubernetes 名称和 ID 完成的。 命名空间使用 Kubernetes 名称对象,这意味着命名空间内的每个对象在集群中都有一个唯一的名称和 ID,以允许虚拟分区。
命名空间如何在多租户中提供帮助
命名空间是你可用于将集群划分为多个虚拟集群以允许多租户的 Kubernetes 原语之一。 每个命名空间都与其他用户、团队或应用程序的命名空间隔离。 这种隔离在多租户中至关重要,因此应用程序、用户和团队的更新和更改都包含在特定的命名空间中。(请注意,命名空间不提供网络分段。)
在继续之前,请验证工作 Kubernetes 集群中的默认命名空间
[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
[root@master ~]# kubectl create namespace test
namespace/test created
验证新创建的命名空间
[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 ~]#
描述新创建的命名空间
[root@master ~]# kubectl describe namespace test
Name: test
Labels: <none>
Annotations: <none>
Status: Active
No resource quota.
No LimitRange resource.
删除命名空间
[root@master ~]# kubectl delete namespace test
namespace "test" deleted
你的新命名空间已激活,但它没有任何已定义的标签、注释或配额限制范围。 但是,现在你知道如何创建、描述和删除命名空间了,我将展示如何使用命名空间来虚拟地划分 Kubernetes 集群。
使用命名空间和 RBAC 划分集群
部署以下简单应用程序,以了解如何使用命名空间划分集群,并将应用程序及其相关对象与“其他”用户隔离。
首先,验证你将使用的命名空间。 为了简单起见,请使用你上面创建的 test 命名空间
[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
然后使用以下配置在 test 命名空间内部署一个名为 test-app 的简单应用程序
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
部署它
$ kubectl create -f test-app.yaml
pod/test-app created
然后验证是否创建了应用程序 pod
$ kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
test-app 1/1 Running 0 18s
现在运行的应用程序位于 test 命名空间中,测试一个用例,其中
- auth-user 可以编辑和查看 test 命名空间内的所有对象
- un-auth-user 只能查看命名空间
我预先创建了用户供你测试。 如果你想知道我是如何在 Kubernetes 中创建用户的,请查看此处的命令。
$ kubectl config view -o jsonpath='{.users[*].name}'
auth-user
kubernetes-admin
un-auth-user
通过此设置,创建一个 Kubernetes Role 和 RoleBindings 来隔离目标命名空间 test,以允许 auth-user 查看和编辑命名空间内的对象,而不允许 un-auth-user 访问或查看 test 命名空间内的对象。
首先创建 ClusterRole 和 Role。 这些对象是允许对特定资源和命名空间执行的动词(操作)列表。
创建 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 ]
创建 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 ]
应用 Role
$ kubectl create -f role.yaml
roles.rbac.authorization.k8s.io "list-deployments" created
使用相同的命令创建 ClusterRole
$ kubectl create -f clusterrole.yaml
$ kubectl get role -n test
NAME CREATED AT
list-deployments 2021-01-18T00:54:00Z
验证 Role
$ kubectl describe roles -n test
Name: list-deployments
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
deployments.apps [] [] [get list]
请记住,你必须按命名空间而不是按用户创建 RoleBindings。 这意味着你需要为用户 auth-user 创建两个角色绑定。
以下是允许 auth-user 编辑和查看的示例 RoleBinding YAML 文件。
编辑
$ 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
查看
$ 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
创建这些 YAML 文件
$ kubectl create rolebinding-auth-view.yaml
$ kubectl create rolebinding-auth-edit.yaml
验证 RoleBindings 是否已成功创建
$ kubectl get rolebindings -n test
NAME ROLE AGE
auth-user-edit ClusterRole/edit 48m
auth-user-view ClusterRole/view 47m
设置好要求后,测试集群分区
[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"
以 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.
你可以查看和编辑 test 命名空间内的对象。 查看集群节点怎么样?
[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]$
你不能,因为用户 auth-user 的角色绑定规定他们只能访问查看或编辑 test 命名空间内的对象。
通过命名空间启用访问控制
命名空间使用 RBAC 和隔离为应用程序、用户或用户组提供访问控制的基本构建块。 但是,仅使用命名空间作为你的多租户解决方案在企业实现中是不够的。 建议你使用其他 Kubernetes 多租户原语来实现进一步的隔离并实施适当的安全性。
命名空间可以在你的 Kubernetes 集群中提供一些基本的隔离;因此,尽早考虑它们非常重要,尤其是在计划多租户集群时。 命名空间还允许你将资源逻辑隔离并分配给单个用户、团队或应用程序。
通过使用命名空间,你可以通过启用单个集群来用于各种工作负载来提高资源效率。
1 条评论