深入RBAC鉴权源码:从Role到Rule的四层匹配机制全解析

前言

上个月帮同事排查权限问题:他给ServiceAccount绑定了Role,但Pod还是无法访问ConfigMap。排查了半天,最后发现Role定义在default namespace,而Pod运行在production namespace。

这个看似简单的问题,让我意识到很多人对RBAC的理解还停留在表面。今天我们就深入源码,看看RBAC鉴权到底是怎么工作的——从ClusterRoleBinding到Rule匹配,完整走一遍四级鉴权流程。

RBAC模型:四种对象的关系

RBAC(Role-Based Access Control)是K8s最主要的鉴权方式,涉及四种核心对象:

┌─────────────────────────────────────────────────────────────────────┐
│                          RBAC模型                                    │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   用户/组/ServiceAccount                                              │
│          │                                                           │
│          │ 绑定 (Binding)                                             │
│          ▼                                                           │
│   ┌─────────────────┐    ┌─────────────────┐                        │
│   │ RoleBinding     │    │ ClusterRoleBinding                      │
│   │ (namespace级)    │    │ (集群级)        │                        │
│   └────────┬────────┘    └────────┬────────┘                        │
│            │                      │                                  │
│            │ 引用 (roleRef)        │                                  │
│            ▼                      ▼                                  │
│   ┌─────────────────┐    ┌─────────────────┐                        │
│   │ Role            │    │ ClusterRole     │                        │
│   │ (namespace级)    │    │ (集群级)        │                        │
│   │                 │    │                 │                        │
│   │ rules:          │    │ rules:          │                        │
│   │ - apiGroups     │    │ - apiGroups     │                        │
│   │ - resources     │    │ - resources     │                        │
│   │ - verbs         │    │ - verbs         │                        │
│   └─────────────────┘    └─────────────────┘                        │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

四种对象的职责

对象作用域职责示例
RoleNamespace定义namespace内的权限可以get Pod
ClusterRoleCluster定义集群级的权限可以get Node
RoleBindingNamespace将Role绑定到用户jane可以get Pod
ClusterRoleBindingCluster将ClusterRole绑定到用户jane可以get Node

重要特性

  • RoleBinding可以引用Role或ClusterRole
  • ClusterRoleBinding只能引用ClusterRole
  • ClusterRole被RoleBinding引用时,只在binding的namespace内生效

RBAC鉴权流程概览

用户请求
    │
    ▼
┌─────────────────────────────────────────────────────────────┐
│                   RBACAuthorizer                             │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Step 1: 获取用户身份信息                                     │
│  - 用户名                                                    │
│  - 用户组                                                    │
│  - namespace                                                 │
│                                                              │
│  Step 2: 查找匹配的ClusterRoleBinding                         │
│  - 遍历所有ClusterRoleBinding                                 │
│  - 检查subject是否匹配用户                                    │
│  - 获取ClusterRole的rules                                     │
│  - 遍历rules,检查是否允许请求                                │
│                                                              │
│  Step 3: 查找匹配的RoleBinding                               │
│  - 遍历指定namespace的所有RoleBinding                         │
│  - 检查subject是否匹配用户                                    │
│  - 获取Role的rules                                            │
│  - 遍历rules,检查是否允许请求                                │
│                                                              │
│  Step 4: 返回结果                                            │
│  - 如果任何rule匹配:DecisionAllow                           │
│  - 如果都不匹配:DecisionNoOpinion                           │
│                                                              │
└─────────────────────────────────────────────────────────────┘

源码解析:RBAC鉴权的实现

初始化入口

// pkg/kubeapiserver/authorizer/config.go
case modes.ModeRBAC:
    rbacAuthorizer := rbac.New(
        // Role列表器
        &rbac.RoleGetter{
            Lister: config.VersionedInformerFactory.Rbac().V1().Roles().Lister(),
        },
        // RoleBinding列表器
        &rbac.RoleBindingLister{
            Lister: config.VersionedInformerFactory.Rbac().V1().RoleBindings().Lister(),
        },
        // ClusterRole列表器
        &rbac.ClusterRoleGetter{
            Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoles().Lister(),
        },
        // ClusterRoleBinding列表器
        &rbac.ClusterRoleBindingLister{
            Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoleBindings().Lister(),
        },
    )
    authorizers = append(authorizers, rbacAuthorizer)

关键点:使用Informer的Lister,从本地缓存获取数据,避免每次都查询etcd。

RBACAuthorizer结构

// pkg/registry/rbac/authorizer/rbac.go

type RBACAuthorizer struct {
    authorizationRuleResolver rbacregistryvalidation.AuthorizationRuleResolver
}

// 创建RBACAuthorizer
func New(
    roles rbacregistryvalidation.RoleGetter,
    roleBindings rbacregistryvalidation.RoleBindingLister,
    clusterRoles rbacregistryvalidation.ClusterRoleGetter,
    clusterRoleBindings rbacregistryvalidation.ClusterRoleBindingLister,
) *RBACAuthorizer {
    return &RBACAuthorizer{
        authorizationRuleResolver: rbacregistryvalidation.NewDefaultRuleResolver(
            roles, roleBindings, clusterRoles, clusterRoleBindings,
        ),
    }
}

Authorize方法:鉴权入口

func (r *RBACAuthorizer) Authorize(
    ctx context.Context, 
    requestAttributes authorizer.Attributes,
) (authorizer.Decision, string, error) {
    
    // 创建visitor,用于检查每一条rule
    ruleCheckingVisitor := &authorizingVisitor{
        requestAttributes: requestAttributes,
    }
    
    // 遍历该用户的所有rule,调用visitor.visit检查
    r.authorizationRuleResolver.VisitRulesFor(
        requestAttributes.GetUser(),      // 用户信息
        requestAttributes.GetNamespace(), // namespace
        ruleCheckingVisitor.visit,        // 回调函数
    )
    
    // 如果visitor标记了allowed,说明有rule匹配
    if ruleCheckingVisitor.allowed {
        return authorizer.DecisionAllow, 
               ruleCheckingVisitor.reason, 
               nil
    }
    
    // 没有匹配的rule
    return authorizer.DecisionNoOpinion, 
           "no RBAC policy matched", 
           nil
}

VisitRulesFor:遍历所有Rule

这是RBAC鉴权的核心方法,负责遍历用户的所有Role/ClusterRole的rules:

// pkg/registry/rbac/validation/rule.go

func (r *DefaultRuleResolver) VisitRulesFor(
    user user.Info,
    namespace string,
    visitor RuleVisitor,
) {
    // ========== 第一步:检查ClusterRoleBinding ==========
    
    // 获取所有ClusterRoleBinding
    clusterRoleBindings, err := r.clusterRoleBindingLister.ListClusterRoleBindings()
    if err != nil {
        visitor(nil, nil, err)
        return
    }
    
    // 遍历每个ClusterRoleBinding
    for _, clusterRoleBinding := range clusterRoleBindings {
        // 检查subject是否匹配用户
        subjectIndex, applies := appliesTo(user, clusterRoleBinding.Subjects, "")
        if !applies {
            continue  // 不匹配,跳过
        }
        
        // 获取ClusterRole的rules
        rules, err := r.GetRoleReferenceRules(clusterRoleBinding.RoleRef, "")
        if err != nil {
            if !visitor(nil, nil, err) {
                return
            }
            continue
        }
        
        // 遍历rules,调用visitor检查
        sourceDescriber := &ruleSourceDescriber{
            binding: clusterRoleBinding,
            subject: &clusterRoleBinding.Subjects[subjectIndex],
        }
        
        for i := range rules {
            if !visitor(sourceDescriber, &rules[i], nil) {
                return  // visitor返回false,停止遍历
            }
        }
    }
    
    // ========== 第二步:检查RoleBinding ==========
    
    if len(namespace) > 0 {
        // 获取该namespace的所有RoleBinding
        roleBindings, err := r.roleBindingLister.ListRoleBindings(namespace)
        if err != nil {
            visitor(nil, nil, err)
            return
        }
        
        // 遍历每个RoleBinding
        for _, roleBinding := range roleBindings {
            // 检查subject是否匹配用户
            subjectIndex, applies := appliesTo(user, roleBinding.Subjects, namespace)
            if !applies {
                continue
            }
            
            // 获取Role的rules
            rules, err := r.GetRoleReferenceRules(roleBinding.RoleRef, namespace)
            if err != nil {
                if !visitor(nil, nil, err) {
                    return
                }
                continue
            }
            
            // 遍历rules,调用visitor检查
            sourceDescriber := &ruleSourceDescriber{
                binding: roleBinding,
                subject: &roleBinding.Subjects[subjectIndex],
            }
            
            for i := range rules {
                if !visitor(sourceDescriber, &rules[i], nil) {
                    return
                }
            }
        }
    }
}

appliesTo:Subject匹配逻辑

判断用户是否匹配RoleBinding/ClusterRoleBinding的subject:

// pkg/registry/rbac/validation/policy_comparator.go

func appliesTo(
    user user.Info, 
    subjects []rbacv1.Subject, 
    namespace string,
) (int, bool) {
    for i, subject := range subjects {
        if appliesToUser(user, subject, namespace) {
            return i, true
        }
    }
    return 0, false
}

func appliesToUser(
    user user.Info, 
    subject rbacv1.Subject, 
    namespace string,
) bool {
    switch subject.Kind {
    case rbacv1.UserKind:
        // 普通用户:直接比较用户名
        return user.GetName() == subject.Name
        
    case rbacv1.GroupKind:
        // 用户组:检查用户是否在该组
        return has(user.GetGroups(), subject.Name)
        
    case rbacv1.ServiceAccountKind:
        // ServiceAccount:比较格式化后的用户名
        // ServiceAccount的用户名格式:system:serviceaccount:<namespace>:<name>
        saNamespace := namespace
        if len(subject.Namespace) > 0 {
            saNamespace = subject.Namespace
        }
        if len(saNamespace) == 0 {
            return false
        }
        return serviceaccount.MatchesUsername(
            saNamespace, 
            subject.Name, 
            user.GetName(),
        )
    }
    return false
}

ServiceAccount用户名匹配

// pkg/serviceaccount/util.go

const (
    ServiceAccountUsernamePrefix    = "system:serviceaccount:"
    ServiceAccountUsernameSeparator = ":"
)

// MatchesUsername检查用户名是否匹配namespace和name
func MatchesUsername(namespace, name, username string) bool {
    // 检查前缀
    if !strings.HasPrefix(username, ServiceAccountUsernamePrefix) {
        return false
    }
    username = username[len(ServiceAccountUsernamePrefix):]
    
    // 检查namespace
    if !strings.HasPrefix(username, namespace) {
        return false
    }
    username = username[len(namespace):]
    
    // 检查分隔符
    if !strings.HasPrefix(username, ServiceAccountUsernameSeparator) {
        return false
    }
    username = username[len(ServiceAccountUsernameSeparator):]
    
    // 检查name
    return username == name
}

// 示例:
// namespace="default", name="my-sa", username="system:serviceaccount:default:my-sa"
// 返回:true

Rule匹配逻辑

当找到匹配的Role/ClusterRole后,需要检查具体的rule是否允许请求。

PolicyRule结构

// staging/src/k8s.io/api/rbac/v1/types.go

type PolicyRule struct {
    Verbs         []string  // 操作类型:get, list, create, update, delete, *
    APIGroups     []string  // API组:""(core), "apps", "rbac.authorization.k8s.io"
    Resources     []string  // 资源类型:pods, services, deployments
    ResourceNames []string  // 特定资源名(可选)
    NonResourceURLs []string // 非资源URL(如/metrics, /healthz)
}

Rule匹配:RuleAllows

// pkg/registry/rbac/validation/policy_comparator.go

func RuleAllows(requestAttributes authorizer.Attributes, rule *rbacv1.PolicyRule) bool {
    if requestAttributes.IsResourceRequest() {
        // 资源请求匹配
        return VerbMatches(rule, requestAttributes.GetVerb()) &&
            APIGroupMatches(rule, requestAttributes.GetAPIGroup()) &&
            ResourceMatches(rule, requestAttributes.GetResource(), requestAttributes.GetSubresource()) &&
            ResourceNameMatches(rule, requestAttributes.GetName())
    }
    
    // 非资源请求匹配(如/metrics)
    return VerbMatches(rule, requestAttributes.GetVerb()) &&
        NonResourceURLMatches(rule, requestAttributes.GetPath())
}

1. Verb匹配

func VerbMatches(rule *rbacv1.PolicyRule, requestedVerb string) bool {
    for _, ruleVerb := range rule.Verbs {
        // * 通配符匹配所有verb
        if ruleVerb == rbacv1.VerbAll {
            return true
        }
        if ruleVerb == requestedVerb {
            return true
        }
    }
    return false
}

// 示例:
// rule.Verbs = ["get", "list", "watch"]
// requestedVerb = "get"  → 匹配
// requestedVerb = "*"    → 不匹配(rule中没有*)

2. API Group匹配

func APIGroupMatches(rule *rbacv1.PolicyRule, requestedGroup string) bool {
    for _, ruleGroup := range rule.APIGroups {
        // * 通配符匹配所有group
        if ruleGroup == rbacv1.APIGroupAll {
            return true
        }
        if ruleGroup == requestedGroup {
            return true
        }
    }
    return false
}

// 示例:
// rule.APIGroups = ["", "apps"]  // ""表示core group
// requestedGroup = ""        → 匹配(core)
// requestedGroup = "apps"    → 匹配
// requestedGroup = "batch"   → 不匹配

3. Resource匹配

func ResourceMatches(
    rule *rbacv1.PolicyRule, 
    requestedResource, 
    requestedSubresource string,
) bool {
    // 组合resource和subresource(如 pods/status)
    combinedResource := requestedResource
    if len(requestedSubresource) > 0 {
        combinedResource = requestedResource + "/" + requestedSubresource
    }
    
    for _, ruleResource := range rule.Resources {
        // * 通配符匹配所有resource
        if ruleResource == rbacv1.ResourceAll {
            return true
        }
        if ruleResource == combinedResource {
            return true
        }
        // 处理子资源匹配(如rule中有pods,可以匹配pods/status)
        if ruleResource == requestedResource {
            return true
        }
    }
    return false
}

// 示例:
// rule.Resources = ["pods", "services"]
// requestedResource="pods", requestedSubresource=""        → 匹配
// requestedResource="pods", requestedSubresource="status"  → 匹配(pods匹配)
// requestedResource="pods", requestedSubresource="log"     → 匹配(pods匹配)
// requestedResource="deployments"                          → 不匹配

4. ResourceName匹配

func ResourceNameMatches(rule *rbacv1.PolicyRule, requestedName string) bool {
    // 如果没有指定ResourceNames,允许所有name
    if len(rule.ResourceNames) == 0 {
        return true
    }
    
    // 检查是否匹配特定的resource name
    for _, ruleName := range rule.ResourceNames {
        if ruleName == requestedName {
            return true
        }
    }
    return false
}

// 示例:
// rule.ResourceNames = ["my-pod", "my-configmap"]
// requestedName = "my-pod"     → 匹配
// requestedName = "other-pod"  → 不匹配

5. 非资源URL匹配

func NonResourceURLMatches(rule *rbacv1.PolicyRule, requestedURL string) bool {
    for _, ruleURL := range rule.NonResourceURLs {
        // * 通配符匹配所有URL
        if ruleURL == rbacv1.NonResourceAll {
            return true
        }
        if ruleURL == requestedURL {
            return true
        }
        // 通配符后缀匹配(如/healthz/*匹配/healthz/ready)
        if strings.HasSuffix(ruleURL, "*") && 
           strings.HasPrefix(requestedURL, strings.TrimRight(ruleURL, "*")) {
            return true
        }
    }
    return false
}

// 示例:
// rule.NonResourceURLs = ["/healthz", "/metrics", "/api/*"]
// requestedURL = "/healthz"      → 匹配
// requestedURL = "/metrics"      → 匹配
// requestedURL = "/api/v1/pods"  → 匹配(/api/*)
// requestedURL = "/debug"        → 不匹配

Visitor模式的应用

RBAC鉴权使用了Visitor模式来遍历和检查rules:

// Visitor函数类型
type RuleVisitor func(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool

// authorizingVisitor实现
type authorizingVisitor struct {
    requestAttributes authorizer.Attributes
    allowed           bool
    reason            string
    errors            []error
}

func (v *authorizingVisitor) visit(
    source fmt.Stringer, 
    rule *rbacv1.PolicyRule, 
    err error,
) bool {
    if err != nil {
        v.errors = append(v.errors, err)
        return true  // 继续遍历
    }
    
    // 检查rule是否匹配请求
    if rule != nil && RuleAllows(v.requestAttributes, rule) {
        v.allowed = true
        v.reason = fmt.Sprintf("RBAC: allowed by %s", source.String())
        return false  // 找到匹配的rule,停止遍历
    }
    
    return true  // 继续遍历下一个rule
}

Visitor的好处

  • 将遍历逻辑与检查逻辑分离
  • 支持提前终止(找到匹配就停止)
  • 收集所有错误信息

使用Informer提升性能

为什么需要Informer?

如果没有Informer,每次鉴权都要从etcd查询:

  • List所有ClusterRoleBinding
  • List所有RoleBinding
  • Get每个Role/ClusterRole

这会造成严重的性能问题。

Informer的工作原理

// 使用SharedInformerFactory创建Lister
versionedInformers.Rbac().V1().Roles().Lister()
versionedInformers.Rbac().V1().RoleBindings().Lister()
versionedInformers.Rbac().V1().ClusterRoles().Lister()
versionedInformers.Rbac().V1().ClusterRoleBindings().Lister()

Informer的工作流程

etcd ──Watch──→ Informer ──缓存──→ Lister
                      │
                      │ 本地内存访问
                      ▼
                 RBACAuthorizer

优势

  • 本地缓存:所有数据在内存中,查询速度极快
  • 实时同步:通过Watch机制保持数据最新
  • 共享Informer:多个组件共享同一个Informer,减少apiserver压力

实际案例分析

案例1:ServiceAccount访问ConfigMap

# Role定义
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: configmap-reader
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]

---
# RoleBinding定义
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-configmaps
  namespace: production
subjects:
- kind: ServiceAccount
  name: my-app
  namespace: production
roleRef:
  kind: Role
  name: configmap-reader
  apiGroup: rbac.authorization.k8s.io

鉴权流程

请求:GET /api/v1/namespaces/production/configmaps/my-config
用户:system:serviceaccount:production:my-app

Step 1: 检查ClusterRoleBinding
  - 遍历所有ClusterRoleBinding
  - 没有找到匹配的subject

Step 2: 检查RoleBinding(namespace=production)
  - 找到RoleBinding: read-configmaps
  - subject匹配: ServiceAccount my-app
  - 获取Role: configmap-reader
  - 检查rules:
    - apiGroups: [""] 匹配 (core group)
    - resources: ["configmaps"] 匹配
    - verbs: ["get"] 匹配
  - ✓ 鉴权通过!

案例2:用户访问跨namespace资源失败

# Role定义在default namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default  # ← 注意这里是default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

---
# RoleBinding也在default namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
roleRef:
  kind: Role
  name: pod-reader

问题:用户jane在production namespace下访问Pod

请求:GET /api/v1/namespaces/production/pods
用户:jane

Step 1: 检查ClusterRoleBinding
  - 无匹配

Step 2: 检查RoleBinding(namespace=production)
  - production namespace下没有绑定jane的RoleBinding
  - 鉴权失败!返回DecisionNoOpinion

解决方案:使用ClusterRoleBinding或ClusterRole。

踩坑实录:RBAC常见问题

坑1:Role和RoleBinding的namespace不一致

现象:用户绑定了Role,但无法访问资源

根因:Role和RoleBinding在不同的namespace

# 错误示例:Role在default,RoleBinding在production
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default  # Role在default
  name: pod-reader

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: production  # RoleBinding在production

解决方案:确保Role和RoleBinding在同一namespace,或者使用ClusterRole。

坑2:resource使用复数形式

现象:rule中写了resource: pod,但权限不生效

根因:应该使用复数形式pods

# 错误
rules:
- apiGroups: [""]
  resources: ["pod"]  # 应该是pods
  verbs: ["get"]

# 正确
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get"]

坑3:subresource没有配置

现象:可以get pod,但不能get pod logs

根因:pod/logs是subresource,需要单独配置

# 错误:缺少logs子资源
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get"]

# 正确:包含pods和pods/log
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get"]

坑4:ClusterRole被RoleBinding引用时的作用域

现象:用RoleBinding绑定ClusterRole,但用户可以在所有namespace操作

误解:ClusterRole被RoleBinding引用后,只在RoleBinding的namespace内生效

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: production  # 只在production生效
subjects:
- kind: User
  name: jane
roleRef:
  kind: ClusterRole
  name: pod-reader

坑5:ServiceAccount的用户名格式错误

现象:给ServiceAccount绑定了Role,但Pod无法访问

排查

# 查看ServiceAccount的实际用户名
kubectl auth can-i get pods --as=system:serviceaccount:default:my-sa -n default

# 检查RoleBinding的subject
kubectl get rolebinding -n default -o yaml

常见错误:在RoleBinding中ServiceAccount没有指定namespace

# 错误
subjects:
- kind: ServiceAccount
  name: my-sa
  # 缺少namespace!

# 正确
subjects:
- kind: ServiceAccount
  name: my-sa
  namespace: default  # 必须指定namespace

RBAC最佳实践

1. 最小权限原则

# 不要这样做
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]

# 应该这样做
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]  # 只给需要的权限

2. 使用ClusterRole + RoleBinding组合

# 定义一个通用的ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: configmap-reader
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]

---
# 在每个namespace使用RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-configmaps
  namespace: production
subjects:
- kind: ServiceAccount
  name: my-app
roleRef:
  kind: ClusterRole
  name: configmap-reader

优点

  • 避免重复定义Role
  • 统一管理权限策略
  • 减少配置错误

3. 避免使用cluster-admin

# 不要这样做
roleRef:
  kind: ClusterRole
  name: cluster-admin  # 太危险了!

# 应该创建专用角色
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-operator
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

4. 定期审计权限

# 查看谁有cluster-admin权限
kubectl get clusterrolebindings -o yaml | grep cluster-admin

# 查看ServiceAccount的权限
kubectl auth can-i --list --as=system:serviceaccount:default:my-sa

# 检查未使用的Role
# 使用工具:kubectl-who-can, rbac-lookup等

总结

通过今天的分析,我们深入理解了RBAC鉴权机制:

  1. 四种对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding
  2. 四级匹配:ClusterRoleBinding → ClusterRole → RoleBinding → Role
  3. 五级Rule匹配:Verb → APIGroup → Resource → ResourceName
  4. Subject匹配:User、Group、ServiceAccount
  5. 性能优化:使用Informer缓存数据

RBAC是K8s权限管理的基石,理解其工作原理对集群安全至关重要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

加倍巴巴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值