k8s权限管理(RBAC)

您所在的位置:网站首页 账号绑定和角色绑定的区别 k8s权限管理(RBAC)

k8s权限管理(RBAC)

2024-07-15 20:55| 来源: 网络整理| 查看: 265

1:安全认证 1、访问控制概述 客户端 useraccount,一般是独立于k8s之外的其他服务管理的用户账号 serviceaccount,k8s管理的账号,用于为pod中的服务进程在访问k8s时提供身份标识

服务账户:

service account adminsion controller: 对于pod进行修改,创建

img img

授权裁决 api请求的k8s授权在api服务器内进行,api服务器根据所有策略评估所有的请求属性,然后允许或拒绝请求 api的请求的所有部分,都必须通过某种授权来允许机制以便继续访问,默认情况下拒绝访问 2、核心概念 1、角色(Role)与集群角色(ClusterRole)

用于定义对资源的访问权限

角色(Role)---命名空间下的权限的设置(增删改查)

role是一种kubernetes对象,它定义了特定命名空间内资源的一组权限,这些权限可以是创建,读取,更新和删除等操作,针对特定的API资源对象(Pod,Service,CongifMap等)

role对象只在特定的命名空间内生效,即它定义的权限只适用于该命名空间内的资源

集群角色(ClusterRole)---对于整个集群的权限的设置

ClusterRole也是一种k8s对象,与Role类似,但是作用的范围更广泛,可以应用于整个集群,而不限于特定的命名空间

ClusterRole定义了对集群范围内的资源的权限,可以包括所有命名空间中资源,也可以包含集群级别的资源,例如,节点,命名空间等

二者的区别

role的作用范围只有对名称空间,而ClusterRole作用的与整个集群的资源 img 2、角色绑定(RoleBinding)与集群角色绑定(ClusterRoleBinding)

在kubernetes中,角色绑定和集群角色绑定用于将用户,组,或服务账户与角色或集群角色关联起来,从而赋予他们相应的权限,他们的作用就是将权限分配给特定的实体,使其能够执行定义在角色或集群角色中的操作

角色绑定(RoleBinding)

RoleBinding是一种kubernetes对象,用于将特定的角色(role)与特定的用户,组,或者服务账户绑定在一起,从而赋予他们在某个命名空间内的资源上执行操作的权限

例如,可以创建一个RoleBinding,将角色(editor)与用户alice绑定在一起,这样alice就具有在特定命名空间内编辑资源的权限

集群角色绑定(ClusterRoleBinding)

作用范围更加的广,将集群角色与用户,组,服务账户绑定在一起,赋予他们在整个集群范围内执行操作的权限

例如,可以创建一个ClusterRoleBind,将集群角色管理员(ClusterAdmin)与用户组"管理员组"绑定在一起,这样管理员组就具有在整个集群中执行管理员操作的权限

通过角色绑定,kubernetes管理员可以灵活的控制不同用户,组,服务账户对集群资源的访问权限,从而实现安全的权限管理 img

3、主体(Subject)

在kubernetes中,主体(Subject)是具有身份的实体,通常是用户,组,或服务账户,主体通过角色绑定或者集群角色绑定与角色或者集群角色关联在一起,从而获取对kubernetes资源的访问权限

主体

用户:k8s中与外部身份验证服务集成,以允许使用基于用户和密码的身份验证机制登录到集群中,登录成功后,用户被视为主体,并根据被分配角色获得相应的权限

组:在某些情况下,将一组用户组织在一起,并且为整个组分配权限可能更加的方便,不用一个一个的用户分配权限,他们加入到一个组中,然后对于这个组分配权限;可以通过角色绑定或集群角色绑定将组与角色或者集群角色关联起来,从而将权限分配给组内的所有成员,快捷

服务账户:服务账户是k8s一种特殊类型的身份,用于表示正在运行的容器或pod,他们通常用于实现应用程序和其他k8s部署的自动化任务,通常为服务账户分配适当的角色或集群角色,可以确保他们具有执行操作所需的权限

总之

主体在k8s中代表了具有身份的实体,通过角色绑定,或集群角色绑定相关联,从而获得对k8s资源的访问权限 3、RBAC在k8s中实现 1、k8s api server与RBAC组件

kubernetes api server与RBAC组件之间实现认证授权机制过程如下

认证(Authentication)

当用户或服务向api server发起请求时,首先会经过认证阶段,认证过程验证请求的身份是否合法,并确定请求的发起者是谁,哪一个主体(用户,组,服务账户)

k8s支持多种认证方式,包括基本验证,客户端证书认证,Token认证等,用户可以根据需求选择适合的认证方式

认证成功后,api server将为请求分配一个身份标识,用于后续的操作

授权(Authorization)---流程

在认证成功后,api server 会将请求与RBAC规则进行匹配,以确定请求是否被允许执行,这个过程被称为授权

RBAC规则由Role,ClusterRole,RoleBinding和ClusterRoleBinding定义,用于描述用户,组或服务账户在集群中的访问权限

当请求达到API server后,api server会将请求中包含的身份信息,以及RBAC规则中定义的权限来决定是否允许执行请求所涉及的操作

如果请求的身份与RBAC规则匹配且有足够的权限,则api server授权请求执行操作,否则,请求被拒绝,并返回相应的错误信息

总之 综上所述,api server与RBAC组件之间实现认证授权机制过程包括认证和授权2个阶段,认证阶段用于验证请求的身份,确定请的发起者是谁;授权阶段则用于根据RBAC规则检查请求的权限,决定是否运行执行操作,这个2个阶段共同构成了k8s的访问控制机制, 确保请求的合法性和安全性 img 2、RBAC权限检查流程

RBAC(基于角色的访问控制),在k8s中权限检查流程如下

认证

用户或服务通过身份验证机制(证书,令牌等)与api server建立连接

授权:一但用户或服务通过认证,api server对请求的进行授权检查,授权检查的过程包括以下步骤

识别主体,api server根据认证信息识别请求的主体,即发送请求的用户,服务或实体

确定请求的操作和目标资源,api server解析请求中包含的操作(例如,get,post,delete等)和目标资源(pod,deploy等)

查询RBAC规则,api server根据主体和请求的操作的资源,查询与之相关的RABC规则,这些规则通常存储在集群中的role,ClusterRole,rolebinding和clusterrolebinding中

匹配规则,api server会将查询到的规则与请求的进行匹配,如果存在请求匹配的规则,则请求被授权执行,否则,请求被拒绝

执行请求:如果请求同构了授权检查,api server将hi执行请求所代表的操作,列如创建,更新,删除资源等

通过以上的流程,RBAC系统实现了对用户和服务细粒度访问控制,确保只有经过授权的和服务才能执行特定的操作 img

img

2、操作 1、Role资源的编写 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: pod-reader #角色的名称 namespace: dev #名称空间的权限设置 rules: - apiGroups: [""] #管理的资源组 resources: ["pods"] #具体的资源 verbs: ["get","list"] #具体的操作 #rule只能对于一个名称空间设置权限,然后赋予用户的,这个用户对于这名称空间的话,就只有get,list的权限了 #其余的资源的编写跟这个一样, 3、创建普通用户和服务账户 1、创建普通用户

原理:通过创建证书和切换上下文环境的方式来创建和切换用户

#创建证书 ##创建私钥 [root@master ~]# openssl genrsa -out devuser.key 2048 ##利用私钥创建一个csr(证书请求)文件 openssl req -new -key devuser.key -subj "/CN=devuser" -out devuser.csr ##私钥加上请求文件生成证书 openssl x509 -req -in devuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out devuser.crt -days 365 #生成账号 [root@master ~]# kubectl config set-credentials devuser --client-certificate=./devuser.crt --client-key=./devuser.key --embed-certs=true User "devuser" set. #设置上下文参数,这里设置名称空间没有直接的关系,并不是这个用户只能在这个名称空间下面操作,其他的空间也可以,要设置权限 kubectl config set-context devuser@kubernetes --cluster=kubernetes --user=devuser --namespace=dev #查看上下文 [root@master ~]# kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE devuser@kubernetes kubernetes devuser dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin #切换为创建的用户的上下文环境中 [root@master ~]# kubectl config use-context devuser@kubernetes Switched to context "devuser@kubernetes". #发现看不了,因为没有设置这个用户的相关的权限 [root@master ~]# kubectl get pod -n dev Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "dev" #对账号进行授权,先切换回来 kubectl config use-context kubernetes-admin@kubernetes #授权文件 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: devuser-role namespace: dev rules: - apiGroups: ["*"] resources: ["pods"] verbs: ["list"] #这里只设置了list这个权限,就是查看名称空间下面的所有资源 --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: devuser-rolebinding namespace: dev subjects: - kind: User name: devuser apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: devuser-role apiGroup: rbac.authorization.k8s.io [root@master role]# kubectl create -f devuser.yaml role.rbac.authorization.k8s.io/devuser-role created rolebinding.rbac.authorization.k8s.io/devuser-rolebinding created #切换到创建的新用户上面,切换上下文件环境 #发现只有获取这个名称空间下面资源的权限,其余的权限都没有赋予 [root@master role]# kubectl config use-context devuser@kubernetes Switched to context "devuser@kubernetes". [root@master role]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE centos 1/1 Running 0 21h [root@master role]# kubectl delete pod -n dev centos Error from server (Forbidden): pods "centos" is forbidden: User "devuser" cannot delete resource "pods" in API group "" in the namespace "dev" 2、创建组 创建组与与创建用户一样 只不过是yaml文件格式有一点区别而已,就是kind这里注意一下即可 ubjects: - kind: User name: my-user - kind: Group name: my-group # 将用户添加到组中,有多个话,也这样添加即可 3、创建服务账户

是一种身份验证和授权的机制,用于k8s集群内部进行服务间通信和资源访问的身份的认证

k8s中每个pod都有一个服务账户相关联,默认的情况下,pod使用其所属命名空间中默认服务账户(创建一个名称空间,默认会创建一个default的服务账户),服务账户通过为pod分配身份,使其能够与api 进行交互并访问其他的资源

[root@master pod]# kubectl describe pod -n dev centos | grep -i service Service Account: default #默认是这个账户

适用的场景

pod需要与api交互,获取或修改资源的信息,获取自己和别人的信息,还能修改,只要有足够的权限

pod需要访问其他的k8s资源,configmap,secret或者其他的pod

pod需要执行某些身份认证的操作,例如通过serviceaccount获取其他的api资源

详细的介绍

service account服务账户是给运行在pod里面程序使用的身份认证,pod里面的进程需要访问api server时,用的就是service account账户

service account仅局限在namespace,只有该namespace下的pod引用这个service account才有权限,然后关联这个secret,这个里面有service account的相关信息(token,ca,等),访问api server时用的token,ca,这些信息都会被挂载到容器里面去

#这些secret里面的信息就会挂载到容器里面,这些就是server account凭证, #就是容器启动后都会挂载对应的service account引用的token,namespace,ca这些 [root@centos /]# cd /var/run/secrets/kubernetes.io/serviceaccount [root@centos serviceaccount]# ls ca.crt namespace token #思路就是这个pod访问api server获取一些资源,然后验证它是什么身份,然后这个身份绑定了什么样的权限,能否执行这样的操作 如果pod不指定的service account,就会自动的引用默认的service account.这样就能访问api server 注意

在名称空间中创建Pod的时候,不指定pod所用的service account将会默认使用默认的serviceaccount(也就是默认名称空间下面有一个服务账户)

service account为服务提供了一种方便的认证机制,但是service account不关心授权问题,pod绑定了service account之后,仅仅是能够访问api server了,但是能访问api server中的哪些资源了(pod,deploy,configmap)需要配合RBAC来为service account授权,

#创建一个service account [root@master pod]# kubectl create serviceaccount -n dev s1 serviceaccount/s1 created #创建一个sercret并且关联到这个server account [root@master serviceaccount]# kubectl create -f s1-secret.yaml secret/s1-secret created [root@master serviceaccount]# cat s1-secret.yaml apiVersion: v1 kind: Secret metadata: name: s1-secret namespace: dev type: Opaque data: username: czE= password: MTIz #对于这个service account(s1)不进行授权的操作 #创建一个pod,关联到s1账户上面去 [root@master serviceaccount]# cat s1-pod.yaml apiVersion: v1 kind: Pod metadata: name: s1-pod namespace: dev spec: serviceAccountName: s1 containers: - name: centos image: centos imagePullPolicy: IfNotPresent command: ["/bin/bash","-c","while true;do sleep 3600;done"] [root@master serviceaccount]# kubectl create -f s1-pod.yaml pod/s1-pod created #这个pod绑定到service account上面去了 [root@master serviceaccount]# kubectl describe pod -n dev s1-pod | grep -i service Service Account: s1 /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hpccw (ro) #进入这个容器里面进行访问api server [root@master serviceaccount]# kubectl exec -ti -n dev s1-pod -n dev -- /bin/bash [root@s1-pod /]# ls ##查看这个secret信息挂载到这个pod里面去了,访问api server时,拿着这些东西进行验证登操作,通过https的请求访问apiserver了 [root@s1-pod ~]# cd /var/run/secrets/kubernetes.io/serviceaccount [root@s1-pod serviceaccount]# ls ca.crt namespace token #发现没有权限 [root@s1-pod serviceaccount]# curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods { "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "pods is forbidden: User \"system:serviceaccount:dev:s1\" cannot list resource \"pods\" in API group \"\" in the namespace \"dev\"", "reason": "Forbidden", "details": { "kind": "pods" }, "code": 403 #表示没有权限,无法进行访问 } #出现上面的原因就是没有给s1这个服务账户绑定一些权限,所以就显示这样的信息 能够访问api server,但是还是需要通过RBAC为service account授权,来决定这个用户有权限访问api server中的哪些资源(deploy,pod,configmap等资源) #对于这个service account进行授权的操作 ##权限和权限绑定 [root@master serviceaccount]# kubectl apply -f s1-role.yaml role.rbac.authorization.k8s.io/s1-role created rolebinding.rbac.authorization.k8s.io/s1-rolebinding created [root@master serviceaccount]# cat s1-role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: s1-role namespace: dev rules: - apiGroups: ["*"] resources: ["pods"] verbs: ["*"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: s1-rolebinding namespace: dev subjects: - name: s1 kind: ServiceAccount namespace: dev apiGroup: "" #这个值就是对于service account的值 roleRef: kind: Role name: s1-role apiGroup: rbac.authorization.k8s.io #进入pod容器里面进行访问 [root@master serviceaccount]# kubectl exec -ti -n dev s1-pod -- /bin/bash [root@s1-pod /]# curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt --header "Authorization:Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods { "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion": "25226" }, "items": [ { "metadata": { "name": "centos", "namespace": "dev", "uid": "c535288f-5894-45db-bcca-340936c895fd", "resourceVersion": "5503", "creationTimestamp": "2024-05-26T03:12:03Z", "managedFields": [ #省略信息 上面命令参数的详细介绍 #参数详细的介绍 `--cacert` 用于指定一个ca证书文件,用于验证服务器ssl证书 `--header` 参数用于添加http请求头,Authorization:Bearer$这个是bearer令牌 https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods #这个是请求的url,指向k8s中api服务器 $KUBERNETES_SERVICE_HOST 和 $KUBERNETES_SERVICE_PORT 是环境变量,分别代表 Kubernetes API 服务器的主机名和端口号 /api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods 是 API 路径,指定了要查询的资源: #读取这个名称空间下面的所有pod 3、账户相关的操作 #查看上下文 [root@master ~]# kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE devuser@kubernetes kubernetes devuser dev * kubernetes-admin@kubernetes kubernetes kubernetes-admin #查看用户相关的权限,查看绑定的相关 [root@master ~]# kubectl get rolebindings --all-namespaces | grep devuser [root@master ~]# kubectl get clusterrolebindings | grep devuser

img

4、参数的配置 1、kind为role,clusterrole资源 1、verbs参数 #Role,ClusterRole Verbs可以配置参数,定义的是操作 * 包含所有的 get --- 读取单个资源的详细信息,kubectl get pod my-pod -o yaml list --- 列出这个名称空间下面的所有资源,kubectl get pods watch --- 用于监视资源的变化事件(添加,删除,更新),kubectl get pods --watch create --- 创建新的资源实例,kubectl create -f pod.yaml update --- 用于更新现有的配置信息,kubectl apply -f pod.yaml patch --- 更新部分现有的数据,kubectl patch pod my-pod -p '{"spec":{"containers":[{"name":"my-container","image":"my-new-image"}]}}' delete --- 删除数据,kubectl delete pod my-pod exec --- 在容器内执行命令,kubectl exec -it my-pod -- /bin/bash 2、resource参数 * 包含所有的资源类型 “services”, “endpoints”, “pods”,“secrets”,“configmaps”,“crontabs”,“deployments”,“jobs”,“nodes”,“rolebindings”,“clusterroles”,“daemonsets”,“replicasets”,“statefulsets”,“horizontalpodautoscalers”,“replicationcontrollers”,“cronjobs” 3、apigroup参数 #定义的是api资源,不同的类型 "*" --- 核心api组,pods,service,endpoint,namespace,nodes等 "apps" --- 控制器资源,deployments,daemonsets,statefulsets,replicasets等 "autoscaling" --- API 组包含用于自动调整工作负载规模的资源,horizontalpodautoscalers (HPA) "batch" --- API 组包含用于批处理任务的资源,jobs: 一次性任务,确保一个或多个 Pods 成功完成。 cronjobs: 基于时间调度的作业。 2、RoleBinding和ClusterRoleBinding参数 1、subject参数 subjects: - kind: ServiceAccount #认证账户,服务账户,还有别的参数User name: mark #名字 namespace: default #会在这个名称空间下面查找这个用户的 apiGroup: "" #这个*为service account的值, 2、roleRef参数 roleRef: #绑定角色的方式 kind: ClusterRole #集群角色绑定 name: pod-clusterrole #角色的名字 apiGroup: rbac.authorization.k8s.io #api 资源类型 5、理解 1、角色,集群角色,角色绑定,集群角色绑定 角色和集群角色的作用范围不同,一个是针对的名称空间一个是针对集群的 角色绑定只能绑定角色,有一个范围,名称空间 集群角色绑定只能绑定集群角色 2、关于主体

Service account

service account就是有一个关联的secret,挂载到了pod里面的容器里面了,访问api server获取(操作),靠的就是这些secret

创建pod的时候指定service account,这样secret就能挂载上去了

角色绑定service account,这样这个账户就能获取权限了,随之里面的pod也能获取相应的权限

每一个pod里面都有一个相关联的service account

User

创建用户比较的麻烦,创建用户之后,绑定了角色,就能获取在这个名称空间下面操作权限了

Group

同上 3、请求 理解的点

在k8s中任何的请求与api server进行交互的时候,需要进行验证身份

然后进行授权(权限鉴别),是否有操作

更加精确的访问控制

记住是任何的请求

4、认证和授权流程

当有一个创建pod的请求发送过来时

先判断他的身份是什么,用户还是,服务账户,认证成功后,与api server建立连接

通过了认证的阶段,然后进行RBAC权限的鉴定,判断这个用户或者服务账户绑定的角色或者集群角色是否有创建Pod的权限,有则执行,没有则拒绝(reject)

这就是认证和授权的流程,

关于服务账户的话

服务账户就是为了pod而活的

进入pod里面,向api server发送请求(比如列出这个名称空间下面的所有pod),判断这个pod的service account的角色绑定是否有这个权限,有则通过,

这个目的主要就是管理pod而用的

最重要的就是每个pod都必须有一个相关联的service account账户

5、疑问 关于集群角色

集群角色中的名称空间和绑定有没有影响,对于这个集群角色?

就是集群角色是整个集群内,跟名称空间没有关系,但是可以通过集群角色绑定来绑定到一个名称空间内,这样的话就只能在这个名称空间下面使用该权限了

集群角色中有这个namespace的参数,但是这个不影响它,主要就是靠集群角色绑定到名称空间下来进行影响的

如果不设置名称空间的话,那么在所有名称空间内都有这个权限

6、认证和通信的流程

身份认证 1、客户端使用客户端证书和私钥与K8s api服务器进行通信,服务器验证客户端证书有效性,以确定客户端的身份

证书认证

客户端在请求api服务器时,使用包含在配置文件中的客户端证书和私钥进行认证

api服务器使用他的CA整数来验证客户端证书的签名,以确保客户端是被信任的实体

加密通信

通信使用tls进行加密,确保数据在传输的过程中不会被窃听或篡改 6、题目 #创建一个用户,分配权限(只有看和删除的权限) ## 首先生成一个私钥key openssl genrsa -out devuser.key 2048 ##使用生成的私钥创建证书请求文件(csr文件) openssl req -new -key devuser.key -subj "/CN=devuser" -out devuser.csr ##签署证书请求生成证书(crt文件) openssl x509 -req -in devuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out devuser.crt -days 365 -CA /etc/kubernetes/pki/ca.crt 这个指定CA证书文件,用于签署devuser.csr -CAkey /etc/kubernetes/pki/ca.key 指定CA私钥文件,用于签署devuser.csr -CAcreateserial 自动生成CA序列号 -out devuser.crt 用户证书 ##生成账号 kubectl config set-credentials devuser --client-certificate=./devuser.crt --client-key=./devuser.key --embed-certs=true kubectl config set-credentials: 这是 kubectl 用于设置用户凭证的命令。 --client-certificate=./devuser.crt: 这是客户端证书文件的路径,kubectl 使用这个证书来验证用户的身份。 --client-key=./devuser.key: 这是客户端私钥文件的路径,与客户端证书配对使用。 --embed-certs=true: 这表示证书和私钥将嵌入到 kubectl 配置文件中,而不是引用外部文件。这对于移动配置文件或在不同环境中使用非常方便。 ##设置上下文参数 kubectl config set-context devuser@kubernetes --cluster=kubernetes --user=devuser


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3