2025,每天10分钟,跟我学K8S(三十七)- RBAC

        我们在前面的章节,讲解了许多K8S中的对象,例如Pods、ConfigMaps、Deployments、Nodes、Secrets、Namespaces等,那如何对他们进行权限管理呢?

        假设我们有一个名为 zhangsan 的用户,想相对这些资源拥有权限,首先想到的就是针对每个资源针对用户进行赋权,例如create、get、delete、list、update、edit、watch、exec各种权限,那这时候又来了一个 lisi 的用户,需要想同的权限,那上述操作是不是需要再重复一次。有没有更简单的方法?当然有,首先创建一个用户 zhangsan(User), 然后创建一个角色(Role),最后将它们2个绑定到一次(RoleBinding)。这样后面想创建 lisi 的角色,也只需要创建完用户后,继续绑定到这个角色上即可。

一、RBAC 核心概念与架构

        RBAC 是 Kubernetes 中实现细粒度权限管理的核心机制,通过 ​角色(Role/ClusterRole)​ 和 ​绑定(RoleBinding/ClusterRoleBinding)​ 控制用户、服务账户等主体对集群资源的访问权限,允许管理员通过 Kubernetes API 动态配置策略,要启用RBAC,需要在 apiserver 中添加参数--authorization-mode=RBAC,如果使用的kubeadm安装的集群,目前版本都默认开启了RBAC,可以通过查看 Master 节点上 kube-apiserver.yaml查看是否启用:

cat /etc/kubernetes/manifests/kube-apiserver.yaml 

资源列表:

  • Pods
  • ConfigMaps
  • Deployments
  • Nodes
  • Secrets
  • Namespaces

操作权限:

  • create
  • get
  • delete
  • list
  • update
  • edit
  • watch
  • exec

角色讲解:

1.角色(Role)​

  • 作用范围:限定在单个命名空间内,定义对特定资源的操作权限(如 Pod 的增删改查)。
  • 示例配置
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # 核心 API 组(如 Pod、Node 等)
  resources: ["pods"] 
  verbs: ["get", "list", "watch"]  # 允许的操作类型

    ​2.角色绑定(RoleBinding)​


    将 ​Role 或 ​ClusterRole 绑定到主体(如用户、服务账户),限定在特定命名空间内生效。

    • 示例:将 pod-reader 角色绑定至服务账户 cicd-sa
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: cicd-pod-access
      namespace: default
    subjects:
    - kind: ServiceAccount
      name: cicd-sa
    roleRef:
      kind: Role
      name: pod-reader

    3.集群角色(ClusterRole)​

    1. 作用范围:全局生效,适用于跨命名空间或集群级资源(如节点、存储卷)。
    2. 典型场景:授予跨命名空间的 Deployment 只读权限。
    3. 示例配置
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: cluster-pod-reader
    rules:
    - apiGroups: [""]  # 核心 API 组(如 Pod、Node 等)
      resources: ["pods", "nodes"]
      verbs: ["get", "list", "watch"]  # 允许的操作类型

    4.​集群角色绑定(ClusterRoleBinding)​

    赋予主体集群级权限(如管理所有命名空间的 Secrets)。

    示例:将 cluster-pod-reader 角色绑定至服务账户 dev-team

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: cluster-pod-reader-binding
    subjects:
    - kind: Group
      name: dev-team  # 用户组名称(需与认证系统集成)
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: cluster-pod-reader  # 引用的 ClusterRole 名称
      apiGroup: rbac.authorization.k8s.io

            通过上面的觉得讲解可以看出来,有两种类型的角色和绑定,一种是Role&RoleBinding,一种是c&ClsterRoleBinding,这两者有什么区别?

            其实从字面就可以看出来,前者是角色,后者是集群角色,那后者权限一定是大于前者的。我们将在后面进行讲解。

    二、RBAC 应用场景与最佳实践

    1.普通用户dev-team,赋予指定权限

    场景:企业中存在开发、测试和运维团队,需确保各团队仅能访问其所属命名空间内的资源。这里创建一个dev-team的用户,规定只能访问名为dev的namespace下的pods和services,并且权限只有"get", "list", "create", "delete"
    实现方案

    1.创建普通用户:dev-team

    •  生成用户私钥与证书签名请求(CSR)
    # 生成私钥(2048位RSA密钥)
    openssl genrsa -out dev-team.key 2048
    
    # 创建证书签名请求(CN为用户标识,O为用户组)
    openssl req -new -key dev-team.key -out dev-team.csr -subj "/CN=dev-team/O=dev-group"
    • 使用集群 CA 签发用户证书
    # 使用 Kubernetes 集群 CA 签发证书(有效期 365 天)
    openssl x509 -req -in dev-team.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out dev-team.crt -days 365
    • 生成 kubeconfig 文件
    # 设置集群信息
    kubectl config set-cluster kubernetes \
      --certificate-authority=/etc/kubernetes/pki/ca.crt \
      --embed-certs=true \
      --server=https://<API-Server-IP>:6443 \
      --kubeconfig=dev-team.kubeconfig
    
    # 添加用户凭证
    kubectl config set-credentials dev-team \
      --client-certificate=dev-team.crt \
      --client-key=dev-team.key \
      --embed-certs=true \
      --kubeconfig=dev-team.kubeconfig
    
    # 创建上下文并设为默认
    kubectl config set-context dev-team-context \
      --cluster=kubernetes \
      --user=dev-team \
      --kubeconfig=dev-team.kubeconfig
    kubectl config use-context dev-team-context --kubeconfig=dev-team.kubeconfig

    2.创建Role:dev-team-role

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: dev
      name: dev-team-role
    rules:
    - apiGroups: [""]
      resources: ["pods", "services"]  # 允许访问 Pod 和 Service
      verbs: ["get", "list", "watch"]  # 仅授予只读权限

    3.创建RoleBinging:dev-team-binding

    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: dev-team-binding
      namespace: dev
    subjects:
    - kind: User
      name: dev-team      # 绑定对应的用户名
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: dev-team-role   #绑定对应的role名称
      apiGroup: rbac.authorization.k8s.io

    4. 应用配置

    kubectl apply -f dev-team-role.yaml
    kubectl apply -f dev-team-binding.yaml

    5.权限验证

    1. 验证权限范围
    # 检查 dev 命名空间 Pod/Service 访问权限
    kubectl auth can-i get pods --namespace=dev --kubeconfig=dev-team.kubeconfig    # 预期返回 yes
    kubectl auth can-i create pods --namespace=dev --kubeconfig=dev-team.kubeconfig # 预期返回 no
    
    # 检查其他命名空间权限
    kubectl auth can-i get pods --namespace=prod --kubeconfig=dev-team.kubeconfig  # 预期返回 no
    2. 实际操作测试
    # 查看 dev 命名空间的 Pod 和 Service(成功)
    kubectl get pods,svc -n dev --kubeconfig=dev-team.kubeconfig
    
    # 尝试删除 Pod(失败)
    kubectl delete pod  -n dev nginx-6b9f9cd485-456jb --kubeconfig=dev-team.kubeconfig
    Error from server (Forbidden): pods "nginx-6b9f9cd485-456jb" is forbidden: User "dev-team" cannot delete resource "pods" in API group "" in the namespace "dev"

    2.超级账号Boss用户,赋予最大权限

    场景:老板看大伙办事不力,准备亲自下场,现在要求给他创建一个最大权限的的账号。

    1. ​生成用户Boss

    # 生成私钥(RSA 2048位)
    openssl genrsa -out boss.key 2048
    
    # 创建证书签名请求(CN 必须与用户名一致)
    openssl req -new -key boss.key -out boss.csr -subj "/CN=boss/O=admin-group"
    
    # 使用集群 CA 签发证书(有效期 365 天)
    openssl x509 -req -in boss.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out boss.crt -days 365
    
    # 生成 kubeconfig 文件
    kubectl config set-cluster kubernetes \
      --certificate-authority=/etc/kubernetes/pki/ca.crt \
      --embed-certs=true \
      --server=https://172.21.176.3:6443 \
      --kubeconfig=boss.kubeconfig
    
    kubectl config set-credentials boss \
      --client-certificate=boss.crt \
      --client-key=boss.key \
      --embed-certs=true \
      --kubeconfig=boss.kubeconfig
    
    kubectl config set-context boss-context \
      --cluster=kubernetes \
      --user=boss \
      --kubeconfig=boss.kubeconfig
    kubectl config use-context boss-context --kubeconfig=boss.kubeconfig

    2、创建ClusterRole和ClusterRoleClusterRoleBinging

    这里可以有两种方式来操作,两种方式任选一种即可

    1.创建一个新的new-cluster-admin集群角色,并且手动赋予最大权限

    2.选择Kubernetes 默认提供 cluster-admin 集群角色,拥有对所有资源的完全控制权。

    2.1 手动创建:

    1、创建一个名为new-cluster-admin的最大权限

    # cat new-cluster-admin.yaml
    
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: new-cluster-admin
    rules:
    - apiGroups: ["*"]            # 覆盖所有 API 组(包括核心组、apps、networking 等)
      resources: ["*"]            # 所有资源类型(如 pods、nodes、secrets、services 等)
      verbs: ["*"]                # 允许所有操作(get、list、create、delete、patch 等)
    - nonResourceURLs: ["*"]      # 非资源端点(如 /healthz、/metrics、/api 等)
      verbs: ["*"]                # 允许访问所有非资源 URL

    2、绑定new-cluster-admin

    # cluster-admin-binding.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: boss-cluster-admin
    subjects:
    - kind: User
      name: boss
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: new-cluster-admin  # 预置超级管理员角色
      apiGroup: rbac.authorization.k8s.io

    3、绑定

    # kubectl apply -f new-cluster-admin.yaml
    clusterrole.rbac.authorization.k8s.io/new-cluster-admin unchanged
    # kubectl apply -f  new-cluster-admin-binding.yaml
    clusterrolebinding.rbac.authorization.k8s.io/boss-cluster-admin created
    
    2.2 绑定内置ClusterRole,通过 ​ClusterRoleBinding 直接关联用户:

    1、直接绑定 cluster-admin-binding

    # cluster-admin-binding.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: boss-cluster-admin
    subjects:
    - kind: User
      name: boss
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: ClusterRole
      name: cluster-admin  # 预置超级管理员角色
      apiGroup: rbac.authorization.k8s.io

    2、绑定cluster-admin-binding

    kubectl apply -f cluster-admin-binding.yaml

    3、权限验证

    3.1. ​基础权限检查
    # 验证集群级权限
    kubectl auth can-i '*' '*' --kubeconfig=boss.kubeconfig  # 预期返回 yes
    
    # 验证跨命名空间操作
    kubectl auth can-i delete pods -n kube-system --kubeconfig=boss.kubeconfig  # 预期返回 yes
    3.2. ​实际操作测试
    # 创建/删除集群级资源(如 Node 查看)
    kubectl get nodes --kubeconfig=boss.kubeconfig
    
    # 操作敏感资源(如 Secrets)
    kubectl get secrets -n kube-system --kubeconfig=boss.kubeconfig
    kubectl delete pod <pod-name> -n kube-system --kubeconfig=boss.kubeconfig

    3.两者的区别:

    Role:

    作用范围:Role 的作用范围限定在特定的命名空间内,例如 dev 或 prod,仅能控制该命名空间内的资源(如 Pod、Service)的访问权限

    可授权的资源类型:授权同一命名空间内的资源操作,例如在 dev 命名空间中管理 Pod 的增删改查

    绑定方式与权限复用: RoleBinding 引用 ClusterRole:如网页所述,ClusterRole 可以通过 RoleBinding 绑定到特定命名空间,此时其权限仅在该命名空间生效(例如将集群级角色限制在 prod 命名空间使用)

    典型应用场景:授权 dev 命名空间的 ServiceAccount 管理 Deployment(仅限该命名空间)

    ClusterRole:

    作用范围:ClusterRole 的权限覆盖整个集群,包括所有命名空间、集群级资源(如 Node、PersistentVolume)和非资源端点(如 /healthz

    可授权的资源类型:可授权集群级资源(如 Node、ClusterRole)和跨命名空间资源(如所有 Secrets),同时支持对非 RESTful API 端点的访问

    绑定方式与权限复用: 直接赋予全局权限,例如授权用户查看所有命名空间的 Pod(kubectl get pods --all-namespaces

    典型应用场景:予全局 Secret 读取权限,或跨命名空间 Pod 监控权限

    总结:

    • Role:适用于单一命名空间内的细粒度权限控制,例如开发团队的资源隔离。
    • ClusterRole:用于全局或跨命名空间的权限需求,如集群管理员、监控工具或跨团队资源共享。
    • 选择原则:优先使用 Role 满足最小权限原则,仅在需要跨命名空间或集群级操作时使用 ClusterRole

    二、RBAC 工作原理与授权流程

    1. 权限校验流程

      • 请求接收:用户或服务账户通过 kubectl 或 API 发起操作请求。
      • 鉴权匹配:API Server 根据 RBAC 规则验证主体是否具备执行操作的权限。
      • 权限决策:若权限匹配则放行,否则拒绝并记录审计日志。
    2. 规则定义逻辑

      • 资源与操作:通过 apiGroupsresourcesverbs 字段精确控制可访问的 API 资源及操作类型。
      • 例外控制:通过 resourceNames 限制对特定资源实例的操作(如禁止删除 critical-config ConfigMap)。

    三、RBAC 应用场景与最佳实践

    1. 典型应用场景

      • CI/CD 流水线权限:授予服务账户管理 Pod 的 get/list/watch 权限,支持自动化部署。
      • 多团队协作:通过命名空间隔离不同团队的资源访问权限。
      • 安全合规:限制运维人员仅能查看日志,禁止修改生产环境资源。
    2. 最佳实践

      • 最小权限原则:避免使用 verbs: ["*"],明确列出所需操作。
      • 使用内置角色:优先选择 view(只读)、edit(编辑)等预定义角色。
      • 定期审计:通过 kubectl auth can-i 检查权限有效性。
      • 服务账户管理:为每个微服务创建独立服务账户,避免共享默认 default 账户。
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值