1

kubernetes中多用户的实践

 2 years ago
source link: https://staight.github.io/2019/09/29/kubernetes%E4%B8%AD%E5%A4%9A%E7%94%A8%E6%88%B7%E7%9A%84%E5%AE%9E%E8%B7%B5/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

kubernetes中多用户的实践

发表于

2019-09-29 更新于 2019-10-03

有时候需要多个用户共用一个集群,这种情况需要为其分配一个新的用户;为了集群的安全性还需要限制新用户的权限范围;多个用户难免会有资源竞争的情况,这时还需要限制其资源使用。

Kubernetes提供了一系列机制以满足多用户的使用,包括多用户,鉴权,命名空间,资源限制等等。

接下来将创建一个名为staight的用户,其拥有practice命名空间下的管理员权限,该命名空间有着CPU,内存,Pod数量等限制。


Kubernetes中的用户创建大体包括静态创建和动态创建两类。其中静态创建需要apiserver启动时提供用户信息文件;动态创建则可以在apiserver启动后动态添加。

动态创建的认证方式包括客户端证书认证和Service Account Token认证。如果能够登录至master的话建议使用客户端证书认证,这里尝试使用Service Account Token认证方式创建用户。

Service Account隶属于命名空间之下,因此首先创建namespace/practice:

[root@node k8s]# kubectl create namespace practice
namespace/practice created

每创建一个命名空间,都会为其新建一个serviceaccount/default,不过这里新建serviceaccount/staight:

[root@node k8s]# kubectl create -n practice serviceaccount staight
serviceaccount/staight created

此时一个新的用户staight就已经创建好了,只不过在apiserver看来,他的用户名全称应为:system:serviceaccount:practice:staight


创建用户后还需要切换至该用户,kubectl命令提供了config子命令以完成这一目的,该命令本质上是修改了位于~/.kube/config的kubeconfig文件,因此也可以为新用户创建一个新的Linux用户,为其放置kubeconfig文件,以实现针对不同Linux用户使用不同的Kubernetes用户。

首先需要获取serviceaccount/staight用户的token:

[root@node k8s]# kubectl describe -n practice serviceaccount/staight |grep Token
Tokens: staight-token-fhd4c
[root@node k8s]# kubectl describe -n practice secret/staight-token-fhd4c
Name: staight-token-fhd4c
Namespace: practice
Type: kubernetes.io/service-account-token

Data
====
ca.crt: 1025 bytes
namespace: 8 bytes
token: <TOKEN_CONTENT>

<TOKEN_CONTENT>就是serviceaccount/staight的token,设置kubeconfig的user,其名称为staight:

[root@node k8s]# kubectl config set-credentials staight --token=<TOKEN_CONTENT>
User "staight" set.

然后设置context,名称为practice-context,引用user为staight,cluster为默认的local,命名空间为practice(使用kubectl命令时如不指定namespace,则默认为practice):

[root@node k8s]# kubectl config set-context practice-context --user=staight --cluster=local --namespace=practice
Context "practice-context" created.

最后,切换至该context:

[root@node k8s]# kubectl config use-context practice-context
Switched to context "practice-context".

尝试获取pod列表,发现无权限,不过可以验证用户切换成功:

[root@node k8s]# kubectl get pod
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:practice:staight" cannot list resource "pods" in API group "" in the namespace "practice"

新创建的用户没有任何权限,因此需要为其授予权限,Kubernetes提供了多种权限授予方式,包括ABAC,Webhook,RBAC等等。

RBAC为Kubernetes默认且推荐的权限授予方式,如果想要使用其他方式,需修改apiserver启动参数。这里使用RBAC模式。

首先需要新建一个Role/ClusterRole资源并指定允许的权限,Kubernetes预设了clusterrole/admin,允许单个命名空间内除了资源配额和命名空间本身的写访问,很适合作为单个命名空间的管理员使用。因此这里不再新建role。

如果想知道clusterrole/admin到底授予了什么样的权限,可以使用describe命令查看:

[root@node k8s]# kubectl describe clusterrole admin
Name: admin
Labels: kubernetes.io/bootstrapping=rbac-defaults
Annotations: rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
...

接下来需要将clusterrole/admin绑定至serviceaccount/staight上:

[root@node k8s]# kubectl create rolebinding practice-admin --clusterrole=admin --serviceaccount=practice:staight --namespace=practice
rolebinding.rbac.authorization.k8s.io/practice-admin created

如上,为staight用户授予了practice命名空间的admin角色,如果需要让该用户管理多个命名空间,更改--namespace参数再次创建即可。

切换至staight用户,尝试获取practice命名空间下的Service Account:

[root@node k8s]# kubectl config use-context practice-context 
Switched to context "practice-context".
[root@node k8s]# kubectl get serviceaccounts
NAME SECRETS AGE
default 1 54m
staight 1 49m

成功获取,授权成功。

大部分情况下,完成新用户对单个命名空间的管理权限就已经可以了,不过如果需要对其资源使用做进一步的限制的话,还需修改命名空间的资源配额。


资源配额是一个用于限制一个命名空间下资源使用的机制,其包括如下两个对象:

  • ResourceQuota:限制单个命名空间下的资源使用量。包括CPU,内存,存储,资源对象的个数等等。
  • LimitRanger:为容器的Limits和Requests设置默认值和范围约束。

ResourceQuota

示例:为practice命名空间设置资源配额

apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: practice
spec:
hard:
pods: "2"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi

如上,对pod数量和使用的requests与limits值做了限制。可以使用describe命令查看目前的资源使用量和限制:

[root@node k8s]# kubectl describe resourcequotas 
Name: compute-resources
Namespace: practice
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
pods 0 2
requests.cpu 0 1
requests.memory 0 1Gi

尝试创建两个Pod,再次创建后报错:

[root@node k8s]# kubectl create -f pod.yml 
Error from server (Forbidden): error when creating "pod.yml": pods "alpine2" is forbidden: exceeded quota: compute-resources, requested: pods=1, used: pods=2, limited: pods=2

resourcequota对相当多的资源提供了限制,详细内容可参考文档:https://kubernetes.io/docs/concepts/policy/resource-quotas/#compute-resource-quota

LimitRanger

LimitRanger用于为容器设置默认的requests和limits值,以及限制其范围。

示例:限制practice命名空间下容器的requests值和limits值

apiVersion: v1
kind: LimitRange
metadata:
name: memory-range
namespace: practice
spec:
limits:
- max: # 限制容器最大limits值
memory: 20Mi
min: # 限制容器最小limits值
memory: 10Mi
default: # 默认limits值
memory: 10Mi
defaultRequest: # 默认requests值
memory: 10Mi
type: Container

如上,如创建Pod时未指定limits和requests值,则自动为其添加requests.memory: 10Milimits.memory: 10Mi;如创建时limits.memory值小于10Mi或大于20Mi,则会拒绝该请求:

[root@node k8s]# kubectl create -f pod.yml 
Error from server (Forbidden): error when creating "pod.yml": pods "alpine2" is forbidden: maximum memory usage per Container is 20Mi, but limit is 30Mi.

Kubernetes多用户的实践包括创建用户,授予权限,资源配额。本文章做了一个初步的演示,但在实际环境中,应当对用户认证方式的选择,授予什么样的权限,和资源的配额做更为周全的打算。


Resource Quotas:https://kubernetes.io/docs/concepts/policy/resource-quotas/

RBAC——基于角色的访问控制:https://jimmysong.io/kubernetes-handbook/concepts/rbac.html

Configure Memory and CPU Quotas for a Namespace:https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-memory-cpu-namespace/

Configure Minimum and Maximum Memory Constraints for a Namespace:https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-constraint-namespace/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK