k8s rbac机制

1、认证,授权,准入控制

  1. 流程

    • 对于认证,授权,访问控制精细化的设置

    • api-server是集群访问控制的唯一入口

    • 在部署应用程序的时候,通过nodeport暴露程序,访问的时候,认证–>>授权—>>准入控制

  2. 认证

    • 对客户端的认证,用户名和密码进行验证
  3. 授权

    • 判断你是否有操作资源的权限,比如,你要创建一个pod的请求,授权会检查这个名称空间下的pod的创建你是否有权限进行该操作,没有的话,则为无法实现该操作
  4. 准入控制机制

    • 位于apserver中,一般用来做身份验证和授权

    • 2个控制器,来进行验证,最后一次的验证

1、认证

  1. 认证的种类:

    1. 令牌认证(token)

      • 需要一对密码下来,客户端登录的时候使用这个密码即可进行登录,k8s提供了一个resetful接口,所有服务都是通过这个http协议提供的
    2. ssl认证

  2. k8s上的账号

    • user account, 人可以进行登录的账号,客户端对apiserver发出了一个请求,apiserver判断这个用户是否有操作的权限,不同账户有不同的权限

    • service account 方便pod里面的进程调用k8s api的一种资源,创建名称空间后,默认会创建一个sa类型,创建pod的时候没有指定sa的话,会自动的使用默认的sa账号

    • sa的局限性就是只在自己的名称空间下面有效

    • 之前的版本的时候,创建sa的时候,会创建一个token和secret,但是之后的版本就不会创建secret

  3. 认证

    • 就是一个apiserver信任这个账户的过程

img

#查看默认的sa
[root@master pv]# kubectl get sa 
NAME      SECRETS   AGE
default   0         17h

[root@master pv]# kubectl create sa test
serviceaccount/test created

[root@master pv]# kubectl describe sa  test
Name:                test
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   <none>
Tokens:              <none>
Events:              <none>

2、授权

  1. 授权的种类

  2. rbac控制

    • role和rolebinding关系,只对一个名称空间有权限,通过这个用户绑定到这个角色,但是不对这个其他的名称空间有权限

    • clusterrole和clusterrolebinding关系,集群角色,对所有的名称空间都有操作的权限

    • 三种绑定的方式

      • role和rolebinding之间的绑定

      • clusterrole和clusterrolebinding绑定

      • rolebinding绑定clusterrole

        • 如果有n个名称空间的话,就需要创建n个role和n个rolebindging进行绑定,非常的不方便,只需要定义一个集群角色(clusterrole)与rolebinding进行绑定,对clusterrole进行授权,这样的话,就会对自己的名称空间下面有管理员的权限

        • 这样的话,用户通过集群角色与角色绑定进行关联的话,对于所有的名称空间下面都会有操作的权限,rolebinding只对自己的名称空间有权限,需要新创建一个role,只需要一个clusterrole即可

3、准入控制

4、rbac授权策略

1、role角色和rolebinding集群角色
#role只能对一个名称空间
[root@master rbace]# cat role.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-read
  namespace: test
rules:
  - apiGroups: [""]  #支持的api组列表
    resources: ["pods"]  #支持的资源对象列表,pods等
    resourceNames: []  #指定资源的名称
    verbs: ["get","watch","list"]  #最资源对象的操作

#定义一个集群角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-cluster
rules:
  - apiGroups: [""]
    resources: ["pods"]
    resourceNames: []
    verbs: ["get","watch","list"]
2、角色绑定和集群角色绑定
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: rolebind
  namespace: test
roleRef:  #绑定的角色
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-role

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: clusterrolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: pod-cluster
subjects:  #绑定的主体,可以是用户,service account等

5、操作

1、命令行创建



2、限制不同用户对k8s的操作
#切换用户的时候只能查看名称空间下面的内容,其他的不能进行查看
#将配置文件里面admin的信息删除即可,拷贝到家目录下即可

#创建证书
##创建私钥
[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 test
Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "test"


#只能devuser只能在test空间下面查看pod,其他空间不行
[root@master test]# cat devuser.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: devuser-role
  namespace: test
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: devuser-rolebinding
  namespace: test
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: devuser-role
subjects:
- name: devuser  
  kind: User #用户绑定上面
  apiGroup: rbac.authorization.k8s.io

#现在这个就有查看pod权限了
[root@master test]# kubectl config use-context devuser@kubernetes 
Switched to context "devuser@kubernetes".
[root@master test]# kubectl get pod -n test
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          8m51s

#创建一个devuser用户,将./kube/config文件中的admin删除掉,只留下一个devuse拷贝到devuser家目录下面
[root@master devuser]# cp -ar /root/.kube/ .

[root@master devuser]# su - devuser 
Last login: Thu Sep 19 08:21:18 UTC 2024 on pts/0
[devuser@master ~]$ kubectl get pod -n test
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          24m
#只能看test名称空间下面的内容,其他空间都不能查看
[devuser@master ~]$ kubectl get pod -n default
Error from server (Forbidden): pods is forbidden: User "devuser" cannot list resource "pods" in API group "" in the namespace "default": RBAC: role.rbac.authorization.k8s.io "devuser-role" not found



3、对于service account授权
  • 这个sa就是为pod服务的,决定着里面pod的权限

  • 创建一个sa后,会有一个token,还要创建一个secret绑定一下即可

#创建sa和secret
[root@master sa-role]# cat sa-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: se1
  namespace: test
  annotations:
    kubernetes.io/service-account.name: sa1
data:
  username: YWRtaW4=
  password: YWRtaW4=
type: Opaque
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa1
  namespace: test
secrets:
- name: se1

#创建pod,关联sa
[root@master sa-role]# cat sa-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: sa-pod
  namespace: test
spec:
  containers:
  - name: buxybox
    image: docker.io/library/busybox:1.28
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","sleep 36000"]
  serviceAccount: sa1

#默认的token会挂在到/var/run/secrets/kubernetes.io/serviceaccount这个路径下面,但是自定义的secre需要自己手动指定

#创建一个pod文件,并且将secret挂载到里面去
[root@master sa-role]# cat sa-pod.yaml 
[root@master sa-role]# cat sa-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: sa-pod
  namespace: test
spec:
  containers:
  - name: buxybox
    image: docker.io/library/tomcat
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /tmp/config
      name: sa-1
  serviceAccount: sa1
  volumes:
  - name: sa-1
    secret:
      secretName: se1


#secret被挂载到里面了      
[root@master sa-role]# kubectl exec -ti -n test sa-pod -- /bin/bash
root@sa-pod:/usr/local/tomcat# cd /tmp/config/
root@sa-pod:/tmp/config# ls
password  username
root@sa-pod:/tmp/config# 

#sa的token信息
root@sa-pod:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt	namespace  token

#pod里面进行访问的时候,发现没有权限
root@sa-pod:/var/run/secrets/kubernetes.io/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:test:sa1\" cannot list resource \"pods\" in API group \"\" in the namespace \"test\"",
  "reason": "Forbidden",  #权限禁止了
  "details": {
    "kind": "pods"
  },
  "code": 403

#sa添加权限
[root@master sa-role]# cat sa-role.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: sa-role
  namespace: test
rules:
- apiGroups: ["*"]
  resources: ["pods"]
  verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: sa-rolebinding
  namespace: test
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: sa-role
subjects:
- kind: ServiceAccount
  name: sa1
  apiGroup: ""   #这个值就是sa的值

#输出信息省略
[root@master sa-role]# kubectl exec -ti -n test sa-pod -- /bin/bash
root@sa-pod:/usr/local/tomcat#  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": "144207"
  },
  "items": [

创建一个service account绑定一个secret 然后创建pod的时候不授权,就没有权限

创建pod的时候授权的话,就会有权限

2、rbac字段

1、role和clusterrole

rules:
- apiGroups: ["*"]  #核心的api组,
  resources: ["pods"]  #常见的资源类型,pods,services,deployment等
  verbs: ["*"] 

#verbs
  - get 获取资源

  - list 列出资源

  - watch 监视资源

  - create 创建资源

3、总结

  1. 主体为用户的话

    • 需要创建用户等一系列的操作,证书等
  2. 主体为sa的话

    • 需要创建一个secret进行关联

    • sa就是为了pod服务的,通过这个来进行通信

    • 对sa赋予权限,pod就能做出各种操作

  3. 角色和集群角色

    • 角色只作用于单个名称空间

    • 集群角色作用于所有的名称空间

  4. 主体

    • sa,k8s的账号,pod访问k8s时的身份标识

    • user 独立于k8s之外的账号

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

    1.认证

    • 用户或服务通过身份验证机制(证书,令牌等)与api server建立连接
      2.授权:一但用户或服务通过认证,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系统实现了对用户和服务细粒度访问控制,确保只有经过授权的和服务才能执行特定的操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值