kube-apiserver鉴权源码简析
创始人
2024-02-02 10:40:44
0次

1 概述

1.1 环境

版本信息如下:
a、操作系统:centos 7.6
b、kubernetes版本:v1.15.0


1.2 鉴权Authorization

4A包括账号Account、认证Authentication、鉴权Authorization、审计Audit,是一个IT系统的一个基础的非业务性的通用功能。后台鉴权一般分为接口权限和数据权限,接口权限在在controller层的拦截器中实现,数据权限在dao层中实现。
kube-apiserver是一个http web服务,显然接口鉴权的工作也是在controller层的拦截器中实现。

1.3 kube-apiserver中的RBAC鉴权思路

kube-apiserver支持ABAC和RBAC,但RBAC往往使用得最广泛,因此本文只讨论RBAC。
对于RBAC而言,kubernetes的Role对象和ClusterRole对象,保存着一组权限,而权限就是谓语(action,或者叫verb)和宾语(object)(例如:get是谓语,pod是宾语)。kube-apiserver从http request对象的tls信息中获得主语(subject),从http mechod和http path推断出谓语和宾语,具备了主语、谓语和宾语后,遍历所有ClusterRole对象和Role对象中的权限信息,逐一对比,匹配正确则放行请求,不匹配则返回403响应。

2 源码

2.1 在拦截器链中注册鉴权相关的两个拦截器

鉴权拦截器是genericapifilters.WithAuthorization( ),而推断了主语、谓语和宾语的拦截器是genericapifilters.WithRequestInfo( )。在拦截器链中,因为genericapifilters.WithRequestInfo( )是较后配置的,因此是较先执行的。

# kubernetes/staging/src/k8s.io/apiserver/pkg/server/config.go
func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler {handler := genericapifilters.WithAuthorization(apiHandler, c.Authorization.Authorizer, c.Serializer)/*其他拦截器*/handler = genericapifilters.WithRequestInfo(handler, c.RequestInfoResolver)/*其他拦截器*/return handler
}

2.2 拦截器genericapifilters.WithRequestInfo( )

将http request的信息解析之后,得到k8s对象的gvr信息、namespace、verb等信息,并保存到名称为info且类型为RequestInfo结构体的对象中,这些信息会在authorize阶段中被使用到。

func WithRequestInfo(handler http.Handler, resolver request.RequestInfoResolver) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {ctx := req.Context()// 解析http请求的path和query参数,形成info对象,info对象会在authorize阶段中被使用到info, err := resolver.NewRequestInfo(req)if err != nil {responsewriters.InternalError(w, req, fmt.Errorf("failed to create RequestInfo: %v", err))return}// 将info对象放入http request中的ctx对象中req = req.WithContext(request.WithRequestInfo(ctx, info))handler.ServeHTTP(w, req)})
}
// RequestInfo holds information parsed from the http.Request
type RequestInfo struct {IsResourceRequest boolPath stringVerb stringAPIPrefix  stringAPIGroup   stringAPIVersion stringNamespace  stringResource stringSubresource stringName stringParts []string
}

2.3 拦截器genericapifilters.WithAuthorization( )

func WithAuthorization(handler http.Handler, a authorizer.Authorizer, s runtime.NegotiatedSerializer) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {ctx := req.Context()// 从request的ctx对象中提取数据attributes, err := GetAuthorizerAttributes(ctx)// 使用鉴权器进行鉴权,这行代码是重点authorized, reason, err := a.Authorize(attributes)// 鉴权结果是通过,则放行请求if authorized == authorizer.DecisionAllow {handler.ServeHTTP(w, req)return}// 服务器内部发生错误,返回5xx响应if err != nil {responsewriters.InternalError(w, req, err)return}// 鉴权结果是不通过,返回403响应responsewriters.Forbidden(ctx, attributes, w, req, reason, s)})
}

RBAC鉴权器的主要逻辑如下:

func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) {ruleCheckingVisitor := &authorizingVisitor{requestAttributes: requestAttributes}// VisitRulesFor(  )从http request的ctx对象中拿出info对象,然后遍历ClusterRoleBinding和RoleBinding找出所有role// 最终逐一进行比对role中表示的权限r.authorizationRuleResolver.VisitRulesFor(requestAttributes.GetUser(), requestAttributes.GetNamespace(), ruleCheckingVisitor.visit)// 鉴权结果是一个布尔值,放在ruleCheckingVisitor的属性allowed中if ruleCheckingVisitor.allowed {return authorizer.DecisionAllow, ruleCheckingVisitor.reason, nil}/*其他代码*/return authorizer.DecisionNoOpinion, reason, nil
}

3 小结

kube-apiserver是一个普通web http服务,鉴权逻辑清晰易懂,先是从http request中提取主语、谓语和宾语,在鉴权阶段就拿着刚获得的主谓宾信息去逐一匹配所有ClusterRole和Role对象中包含的权限信息。

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...