暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mac 上学习k8s系列(22)rbac 源码学习(part II)

kubernetes中角色分为Role和ClusterRole,Role是namespace级别的,ClusterRole是集群级别的。回想下mac 上学习k8s系列(17)rbac 源码学习(part I)中的类图:


具体的结构体定义中在pkg/apis/rbac/types.go,我们先看下Role和对应的RoleBinding

        type Role struct 
    metav1.TypeMeta
    metav1.ObjectMeta
    Rules []PolicyRule

    role 包含一系列的的PolicyRule

      type PolicyRule struct 
      Verbs []string
      APIGroups []string
      Resources []string
      ResourceNames []string
      NonResourceURLs []string

      而RoleBinding定义了role和subject之间的绑定关系:

            type RoleBinding struct 
        metav1.TypeMeta
        metav1.ObjectMeta
        Subjects []Subject
        RoleRef RoleRef

        当然包含的对象也分两部分

              type Subject struct 
          Kind string
          APIGroup string
          Name string
          Namespace string
                type RoleRef struct
            APIGroup string
            Kind string
            Name string

            这两个结构体主要看两个属性值,第一个是Subjects,它是绑定的对象,包括User、Group、ServiceAccount;第二个是RoleRef,它是绑定的角色。

                     文件里也定义了对应的list

                  type RoleBindingList struct
              metav1.TypeMeta
              metav1.ListMeta
              Items []RoleBinding
                type RoleList struct
                Items []Role

                针对集群的rbac 相关对象定义如下,它没有namespace

                    type ClusterRole struct
                  Rules []PolicyRule
                  AggregationRule *AggregationRule
                        type AggregationRule struct 
                    ClusterRoleSelectors []metav1.LabelSelector

                    也有对应的ClusterRoleBinding

                          type ClusterRoleBinding struct 
                      Subjects []Subject
                      RoleRef RoleRef

                      和对应的list

                        type ClusterRoleBindingList struct 
                        Items []ClusterRoleBinding
                          type ClusterRoleList struct
                          Items []ClusterRole

                          ClusterRole与Role的结构体定义基本是类似的,角色里面都是关联的Rules规则,一个角色有哪些权限,通过Rules去定义。下面是Rule的结构体定义,主要控制访问的资源、访问URL的限制。

                          那么角色是怎么和使用者或者服务账号绑定的呢?这就要看ClusterRoleBinding和RoleBinding。RoleBinding是把角色在namespace中对资源的权限授权给使用者或服务账号;ClusterRoleBinding允许使用者或服务账号在整个集群中的授权访问。ClusterRoleBinding与RoleBinding的功能是一致的,只是有着更宽的使用范围。

                                除了rbac,k8s还有很多种权限控制模式,比如abac:

                          pkg/apis/abac/types.go

                                type Policy struct {
                            type PolicySpec struct

                            在kubernetes中,所有的请求都会经由apiserver进行处理。在初始化apiserver时,若指定了鉴权模式包括了RBAC后,将会注册一个RBAC的Handler模块。这样,在apiserver接收请求并处理时,将会调用该Handler,来判断该请求的调用者是否有权限请求该资源。

                            staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go

                              func WithAuthorization(handler http.Handler, a authorizer.Authorizer, s runtime.NegotiatedSerializer) http.Handler 
                                    return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
                              attributes, err := GetAuthorizerAttributes(ctx)
                              authorized, reason, err := a.Authorize(ctx, attributes)

                              该Handler做了两件事,一是根据http request提取出鉴权所需的信息,通过函数GetAuthorizerAttributes()实现,二是根据提取出的信息,执行鉴权的核心操作,去判断请求的调用者是否有权限操作相关资源,通过函数Authorize()处理。

                              vendor/k8s.io/apiserver/pkg/endpoints/filters/authorization.go

                                func GetAuthorizerAttributes(ctx context.Context) (authorizer.Attributes, error) 
                                requestInfo, found := request.RequestInfoFrom(ctx)

                                        主要包括请求的APIGroup、APIVersion、Resource、SubResource、Verbs、Namespace等这些在PolicyRule结构体中定义的信息。

                                plugin/pkg/auth/authorizer/rbac/rbac.go

                                  func (r *RBACAuthorizer) Authorize(ctx context.Context, requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) 
                                  r.authorizationRuleResolver.VisitRulesFor(requestAttributes.GetUser(), requestAttributes.GetNamespace(), ruleCheckingVisitor.visit)

                                  pkg/registry/rbac/validation/rule.go

                                    func (r *DefaultRuleResolver) VisitRulesFor(user user.Info, namespace string, visitor func(source fmt.Stringer, rule *rbacv1.PolicyRule, err error) bool) 
                                           clusterRoleBindings, err := r.clusterRoleBindingLister.ListClusterRoleBindings();
                                           subjectIndex, applies := appliesTo(user, clusterRoleBinding.Subjects"")
                                          rules, err := r.GetRoleReferenceRules(clusterRoleBinding.RoleRef"")
                                          for i := range rules {
                                    if !visitor(sourceDescriber, &rules[i], nil) {
                                    return
                                    }
                                    }

                                    获取所有的ClusterRoleBindings,并对其进行遍历操作;

                                    根据请求调用者的信息,判断该调用者是否被绑定在该ClusterRoleBinding中;若绑定在该ClusterRoleBinding中,将通过函数GetRoleReferenceRules()获取绑定的Role所控制的访问的资源;将Role所控制的访问的资源,与从API请求中提取出的资源进行比对,若比对成功,即为API请求的调用者有权访问相关资源;若在所有的ClusterRoleBinding中,都没有获得鉴权成功的操作,将会判断提取出的信息中是否包括了namespace的信息,若包括了,将会获取该namespace下的所有RoleBindings。获取了该namesapce下的所有RoleBindings之后,所执行的操作将与ClusterRoleBinding类似,对其进行遍历,获取对应Role控制的访问的资源,与从API请求中提取的资源信息进行比对。若在遍历了所有CluterRoleBindings,及该namespace下的所有RoleBingdings之后,仍没有对资源比对成功,则可判断该API请求的调用者没有权限访问相关资源。



                                    文章转载自golang算法架构leetcode技术php,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                    评论