kubernetes——RBAC鉴权

简介

基于角色的访问控制(RBAC)是一种基于组织中各个用户的角色来调节对计算机或网络资源的访问的方法。

目的:防止k8s里的pod(会运行程序)能随意获取整个集群里的信息和访问集群里的资源

概念

  • Rule:规则,一组属于不同 API Group 的操作集合;
  • Role:角色,用于定义一组对 Kubernetes API 对象操作的一组规则,范围限定在 namespace;
  • ClusterRole:集群角色,该角色不受 namespace 的限制;
  • Subject:对象,也就是规则作用的对象;
  • RoleBinding:将角色和对象进行绑定,范围限定在 namespace;
  • ClusterRoleBinding:将集群角色和对象进行绑定,不受 namespace 限制
  • Serviceaccount: 服务账户--》pod--》apiserver
     

UserAccount和ServiceAccount介绍

架构图 

实验步骤(serviceaccoount使用案例介绍)

1.创建sa并绑定到pod

[root@k8smaster ingress]# kubectl create sa sa-lay
serviceaccount/sa-lay created
[root@k8smaster ~]# kubectl get sa
NAME      SECRETS   AGE
default   1         103d
sa-lay    1         2d3h

2.创建pod

[root@k8smaster sa]# cat sa-pod.yaml
 
apiVersion: v1
kind: Pod
metadata:
  name: sa-lay
  namespace: default
  labels:
    app: sa-lay
spec:
  serviceAccountName: sa-lay
  containers:
  - name: sa-nginx
    ports:
    - containerPort: 80
    image: nginx
    imagePullPolicy: IfNotPresent
    
[root@k8smaster sa]# kubectl apply -f sa-pod.yaml 
pod/sa-lay created

3.验证(拒绝访问)

访问apiserver,没权限

sa能通过https方式成功认证API,但是没有权限访问k8s资源,所以code状态码是403,表示没有权限操作k8s资源

[root@k8smaster sa]# kubectl exec -it sa-lay -- bash
#因为pod 会去访问k8s集群的apiserver,所以需要进入到pod里
root@sa-lay:/# cd /var/run/secrets/kubernetes.io/serviceaccount
root@sa-lay:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt	namespace  token
#执行下面的命令去访问我们的apiserver 
root@sa-lay:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes/api/v1/namespaces/kube-system
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    
  },
  "status": "Failure",
  "message": "namespaces \"kube-system\" is forbidden: User \"system:serviceaccount:default:sa-lay\" cannot get resource \"namespaces\" in API group \"\" in the namespace \"kube-system\"",
  "reason": "Forbidden",
  "details": {
    "name": "kube-system",
    "kind": "namespaces"
  },
  "code": 403

4.对sa做授权

cluster-admin   这是一个权力非常大的clusterrole 集群角色
这个角色是k8s系统内部就有的,这是一个内置的集群角色 

[root@k8smaster sa]# kubectl create clusterrolebinding sa-test-admin --clusterrole=cluster-admin --serviceaccount=default:sa-lay
将default命名空间里的sa-lay服务账号绑定到 集群角色 cluster-admin 上
clusterrolebinding.rbac.authorization.k8s.io/sa-test-admin created
[root@k8smaster sa]# kubectl get clusterrolebinding  #查看有哪些服务账号进行了集群角色绑定
NAME                                                   ROLE                                                                               AGE
calico-kube-controllers                                ClusterRole/calico-kube-controllers                                                11d
calico-node                                            ClusterRole/calico-node                                                            11d
cluster-admin                                          ClusterRole/cluster-admin                                                          11d
ingress-nginx                                          ClusterRole/ingress-nginx                                                          99m
ingress-nginx-admission                                ClusterRole/system:certificates.k8s.io:certificatesigningrequests:selfnodeclient   11d
kubeadm:node-proxier                                   ClusterRole/system:node-proxier                                                    11d
metrics-server:system:auth-delegator                   ClusterRole/system:auth-delegator                                                  8d
sa-test-gaoshuo                                        ClusterRole/cluster-admin                                                          16s
system:basic-user                                      ClusterRole/system:basic-user                                                      11d
system:controller:attachdetach-controller              ClusterRole/system:controller:attachdetach-controller                              11d
system:controller:certificate-controller               ClusterRole/
[root@k8smaster sa]# 

 

5.再次请求验证

再次请求,使用绑定好的集群角色 

[root@k8smaster sa]# kubectl exec -it sa-lay -- bash
root@sa-lay:/# cd /var/run/secrets/kubernetes.io/serviceaccount
root@sa-lay:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes/api/v1/namespaces/kube-system
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "kube-system",
    "uid": "1afd57db-8217-4eab-9015-42629f340013",
    "resourceVersion": "17",
    "creationTimestamp": "2023-05-15T12:19:01Z",
    "managedFields": [
      {
        "manager": "kube-apiserver",
        "operation": "Update",
        "apiVersion": "v1",
        "time": "2023-05-15T12:19:01Z",
        "fieldsType": "FieldsV1",
        "fieldsV1": {"f:status":{"f:phase":{}}}
      }
    ]
  },
  "spec": {
    "finalizers": [
      "kubernetes"
    ]
  },
  "status": {
    "phase": "Active"
  }

自定义角色

[root@k8smaster sa]# kubectl get clusterroles
NAME                                                                   CREATED AT
admin                                                                  2023-03-23T09:58:17Z
calico-kube-controllers                                                2023-03-23T10:02:38Z
calico-node                                                            2023-03-23T10:02:38Z
cluster-admin                                                          2023-03-23T09:58:17Z
[root@k8smaster sa]# kubectl describe  clusterroles cluster-admin
Name:         cluster-admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  rbac.authorization.kubernetes.io/autoupdate: true
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  *.*        []                 []              [*]
             [*]                []              [*]

Resources  代表这个角色可以访问的资源  *.* 代表任意命名空间里的任意资源

Verbs : 可以采取的动作 :  get  list  watch

1.创建角色,控制权限 

[root@k8smaster sa]# cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
[root@k8smaster sa]# kubectl apply -f role.yaml 
role.rbac.authorization.k8s.io/pod-reader created

2.角色绑定

 sa绑定role

[root@k8smaster sa]# kubectl create rolebinding sa-test-lay --role=pod-reader --serviceaccount=default:sa-lay
rolebinding.rbac.authorization.k8s.io/sa-test-lay created

查看已经绑定的rolebinding 

[root@k8smaster sa]# kubectl get rolebinding
NAME          ROLE              AGE
sa-test-lay   Role/pod-reader   38s

3. 创建一个clusterrole

[root@k8smaster sa]# vim clusterrole.yaml 
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name: secret-reader
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]
[root@k8smaster sa]# kubectl apply -f clusterrole.yaml 
clusterrole.rbac.authorization.k8s.io/secret-reader created
[root@k8smaster sa]# 
[root@k8smaster sa]# kubectl get clusterrole
secret-reader                                                          2023-04-04T08:51:10Z

4. 将sa-lay 绑定到secret-reader 的集群角色上

[root@k8smaster sa]# kubectl create clusterrolebinding sa-test-lay-2  --clusterrole=secret-reader  --serviceaccount=default:sa-lay
clusterrolebinding.rbac.authorization.k8s.io/sa-test-lay-2 created
[root@k8smaster sa]#
[root@k8smaster sa]# kubectl get clusterrolebinding
NAME                                                   ROLE                                                                               AGE
calico-kube-controllers                                ClusterRole/calico-kube-controllers    
sa-test-lay                                       ClusterRole/cluster-admin                                                          26m
sa-test-lay-2                                      ClusterRole/secret-reader                                                          38s

5. 验证:

启动就是进入sa-lay启动的pod,去访问apiserver里的pod资源和secret资源

[root@k8smaster sa]# kubectl get pod
NAME                               READY   STATUS    RESTARTS   AGE
dapi-test-pod                      0/1     Error     0          4d23h
mypod                              1/1     Running   2          30h
nginx-configmap-test               1/1     Running   3          3d23h
sa-lay                             1/1     Running   0          43m
[root@k8smaster sa]# kubectl exec -it sa-lay  -- bash
root@sa-gaoshuo:/# 
root@sa-gaoshuo:~# cd /var/run/secrets/kubernetes.io/serviceaccount/
root@sa-gaoshuo:/var/run/secrets/kubernetes.io/serviceaccount# 
root@sa-gaoshuo:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt  -H "Authorization: Bearer $(cat ./token)"  https://kubernetes/api/v1/pods  
root@sa-gaoshuo:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt  -H "Authorization: Bearer $(cat .token)"  https://kubernetes/api/v1/secrets

FastAPI本身不提供RBAC鉴权系统,但是可以通过第三方库来实现。这里介绍一种使用FastAPI和Pydantic实现RBAC鉴权系统的方法。 首先,需要定义用户模型和角色模型: ```python from typing import List from pydantic import BaseModel class User(BaseModel): id: int username: str password: str role_ids: List[int] = [] class Role(BaseModel): id: int name: str permissions: List[str] = [] ``` 然后,需要定义一个获取当前用户的函数,可以使用FastAPI的依赖注入功能实现: ```python from fastapi import Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from jwt import decode, exceptions from datetime import datetime, timedelta security = HTTPBearer() def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)) -> User: token = credentials.credentials try: payload = decode(token, "SECRET_KEY", algorithms=["HS256"]) username = payload.get("sub") if username is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials") user = get_user_by_username(username) if user is None: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid username") return user except exceptions.DecodeError as e: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid authentication credentials") except exceptions.ExpiredSignatureError as e: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Token has expired") ``` 这个函数会从HTTP请求头中获取JWT令牌,并验证令牌的有效性和过期时间。如果验证通过,则返回当前用户对象。需要注意的是,这里的"SECRET_KEY"应该替换成真正的密钥。 接下来,需要定义一个检查权限的函数: ```python def check_permission(user: User, permission: str) -> bool: roles = get_roles_by_ids(user.role_ids) for role in roles: if permission in role.permissions: return True return False ``` 这个函数会检查当前用户是否拥有某个权限。需要根据用户的角色列表获取角色对象,然后检查角色是否拥有该权限。 最后,需要在路由定义中使用这些函数来进行鉴权: ```python from fastapi import FastAPI, Depends, HTTPException, status app = FastAPI() @app.get("/protected") def protected(user: User = Depends(get_current_user)): if not check_permission(user, "read_protected_data"): raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You don't have permission to access this resource") return {"data": "This is protected data."} ``` 这个路由定义会使用get_current_user函数获取当前用户对象,然后使用check_permission函数检查是否拥有"read_protected_data"权限。如果没有权限,则返回HTTP 403 Forbidden错误。 需要注意的是,这里只是一个简单的示例,实际的RBAC鉴权系统可能会更加复杂。还需要考虑如何管理用户、角色和权限的数据,以及如何将鉴权逻辑集成到具体的业务逻辑中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值