Kubernetes 核心组件:API Server 概念/功能

API Server


1. 认证

2.鉴权

3.准入

  • Mutating
  • Validating
  • Admission

4.限流

所谓的api-server其实就是整个kubernetes集群控制面的api网关。针对于任何api网关,它都要做自我保护,第一你需要做认证,我要知道你这个请求来自哪里,鉴权我要知道一个请求有没有操作权限。

任何的请求都会以一个对象,object形式发过来,发到apiserver这一端,我还要去校验你这个请求的合法性,除了我要知道你是谁,你有没有这个操作权限还要看你的request是不是合法的,比如说你的属性设置错了,或者说需要对你的request里面某些属性做变形,比如有个值没填,那么我会给你填入一些默认值,上面这些事情都是准入去做的。准入就包含了mutating,validating。

限流也是apiserver自我保护的机制, 能够限制同一时间内,最大多少request,这样防止把自己打死。

kube-apiserver 是Kubernetes最重要的核心组件之一,主要提供以下的功能∶

  • 提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 APIServer 查询或修改数据,只有API Server 才直接操作 etcd)(在k8s技术栈里面,应该只有apiserver自己去连etcd,因为apiserver这边可以对etcd做些保护操作,比如限流的操作,认证鉴权的操作,它是挡在etcd之前的一个守护者apiserver这边又有缓存的机制,其实很多的读操作就在apiserver这边处理掉了,它不会再将请求转到etcd里面去,这样的话其实有效的减少了整个集群对etcd的并发请求)。

访问控制概览


 Kubernetes API的每个请求都会经过多阶段的访问控制之后才会被接受,这包括认证、授权以及准入控制(Admission Control)等。

从apiserver接收到请求,到数据存储到数据库,中间经历了哪些流转。

request发送到apiserver,首先最开始有HTTP handle,这个handle接收到这个请求之后,请求会被发送到认证鉴权两个模块,认证其实就是就是api网关最基础的能力,我要知道你是谁,这里提供了一系列的认证手段。

鉴权:我知道的你是谁之后,然后要知道你有没有操作权限。

认证鉴权之后,比如说某个请求属性没有设置,我希望给你一个默认值,或者修改你的属性值。这个时候我希望在apiserver端对你的request增加一些属性,这个对方就会走mutating,所谓的mutating就是变形,它是支持webhook的,除了kubernetes自身可以对你这个数据做一些修改,你还可以通过一些webhook来针对这些对象做一些修改。

mutating做完之后,就走入了k8s自定义的这些对象的schema validation,由于之前做过变形,我要去看变形之后的对象是不是合法的,是不是符合kubernetes的规范。

做完上面的之后,如果你还要去做一些附加的校验,比如说k8s规定的名字不能超过255,但是我希望名字在我自己的生产环境里面不超过63,那么你就可以附加一些最强的validation在webhook里面,通过validating admission plugin来调用你的webhook,把你的校验逻辑加上去。

最后所有的这些流转做完了之后,整个数据才会存放到etcd里面去,到此位置,数据的持久化就做完了。

访问控制细节


panic recovery 

apiserver在收到请求之后,进来之后是panic recovery,因为apiserver相对于一个服务器,它会启动不同的goroutine来处理不同的请求,当这些请求出现panic的时候,这时候就要确保某个goroutine panic不会将整个http server搞死,所以这里就有panic recovery的机制。

request-timeout

之后就是设置request-timeout,request超时时间,假设后面的请求没有被及时的处理,那么request就失败了,如果不设置request超时时间就意味着客户端这个connection一直连接着的。

认证/审计

接下来做认证,认证完了就去做审计,这里面会去记录谁对哪些对象做了哪些操作,所以审计很多时候是有效的,比如是平台的维护方,上面跑了很多的应用,很多时候经常有用户跑过来说为什么跑在你集群上面的对象我的业务无缘无故就消失了,肯定是你们做了什么操作,这个时候查auditlog,几乎百分之百就是客户自己删除的,因为作为运营方不会去碰用户的业务。

impersonation:它是一个request发送到http server这一端的时候,你可以为这个request加上header,这些header可以模拟这个request给谁用,request代表哪个用户,现在用的不太广泛。

在以前集群联邦的层面,我从联邦集群发下来的request,集群联邦连每一个member cluster的时候用的是root的kubeconfig,但是集群联邦的层面是代用户去分发这些request,通过impersonation我们就会将用户的真实的信息填在这个request里面,那么这个request发到集群下面的话,那么api server就会去读impersonation的信息来判断request是谁的,以此来做权限的校验,来判断用户有没有这个对象的操作权限。

限流

max-in-flight是原来做限流的,也就是apiserver里面能够最多处理多少个请求,如果超过就拒绝。

所谓的inflight就是在路上的请求,就是从request放到apiserver端到request还没返回客户端,这中间是有一个时间周期,也就是在这个时间周期在APIserver这边会有很多request是在被处理的过程中, max-in-flight也就是当前多少request在路上,如果到达了上限,还有新的request发过来,那么到这里面就拒绝了。

鉴权

限流之后完了就去做鉴权,鉴权去判断你有没有这个操作权限。

Aggregator/CRD

然后接下来会有一个比较重要的组件,kube-aggregator,因为apiserver本身是http处理器,它可以将request转走,在这里面aggregate就会判断说现在的request是不是标准的k8s对象,如果是,那么默认的apiserver就处理掉了,但是你想做扩展,比如说你自定义的k8s一些对象,然后你有另外的apiserver来支撑这些新对象,那么你就可以在这里面做些配置,k8s会去判断好像有些请求不是k8s内定的,通过读取配置将你的request转到其他地方,那么它就会将request发到aggregate apiserver,也就是它本身是一个代理了,有些请求就转出去了,没有转出去的request会被本地处理。

Conversion

到本地这里,之前的request都是json,这里面就要去做decoding,就是将这个对象给它反序列化,反序列化就变成了go的一个个对象了,这里需要做一个conversion,也即是将外部的结构转化为内部的结构,k8s任何的对象都有external version和internal version,external version是面向用户的,internal version是面向自己的实现,然后他就将对象转化为internal version,你可以理解将internal version存在了etcd里面。

Admission

先去做转换conversion,然后去做admission,admission就是有几个步骤,先去看有没有mutating webhook,有就调用,如果没有就走内置的validating这个流程,那么内置的validating k8s自己对象里面会去实现,比如对pod来说做哪些校验规则,它会去调用这些方法来校验这个pod是不是合法的,比如容器的image没有提供,那么这里面肯定是不过的。

做完内置的validating你想做附加的validating那么它就去看看你没有附加的validating webhook,如果有的话就去调用。(那么kubernets内部自己会去实现,比如pod里面就会定义一些策略,比如更新对象之前要做什么事情,比如还需要去做什么缴验,他还会去校验这个pod是否是合法的,比如容器的image没有提供,那么肯定是通过不了的)(做完了内置的validate之后,你想去附加validate,那么就去看有没有validate webhook,如果有那么就会去调用)

上面这些都通过了就存入到etcd,etcd存完了之后就返回客户端。

从认证,鉴权,准入,限流这些机制里面都过了之后,接下来就是存储在etcd里面了。

接下来就需要去了解apiserver的运作机制,比如存在etcd之前发送了什么事情,这样就将整个apiserver的能力模型,它背后的运作机制都理解清除了。这里就不得不提apimachinery这样一个组件,什么是apimachinery,它就是api的一个运作机制了。

 第一个就是typemetadata,它定义了这个对象是什么,它分为三类,叫做group kind version。

group就是根据对象所适应的业务场景,业务目的为其分类,分到一个一个的group里面去。其次就是kind我这个对象是什么,真正的它的类型是什么,比如pod,svc这些都是一个一个的kind,它们都属于kubernetes的core group。

上面所说的对象都是v1,任何社区的代码都是从v1 alpha1开始,一个新的对象出现的时候,它不可能就生产就绪了,所以社区这些所有的能力都是迭代的往前走。

第一个版本就是v1 alpha1,然后再初始的状态下,我们设计了一些能力,在这个v1 alpha1里面。随着版本的演进,要增加减少,对属性改名,或者structural要变一下。这样就涉及到了api的变换。kubernetes每年有3-4个版本。当你去做系统,你的api发生了变更,那么你一定要做向前兼容,所以它的任何版本迭代都是可以向前兼容的。

所以它要通过一种机制来向前兼容,通过版本转换来实现,当我们在谈v1 alpha1,v1 beta1,或者v1,这些带标号的版本,都叫做external version。所谓的external version是面向kubernetes集群外部,也就是作为客户端去访问apiserver的时候,这个时候访问的都是external version,针对于kubernetes apiserver的内部,它是叫做internal version。任何external version发过来的请求,在存入etcd之前将其转化为internal version。

也就是在接收到这个请求之后,会对这个对象做一个变换,就会将一个外部版本变化为内部的版本,这个内部版本简单理解就是可以存在etcd的版本。

一个对象某些版本在做变更的时候,在变更期间会支持多个版本,比如从v1 alpha -> v1 alph2,通过这两个版本去访问这个对象都是可以的,请求发到apiserver,你也是带着这个版信息的,那么在这些对象实现的时候,它都会去实现conversion的方法,你的每一个external version往internal转换的时候属性变换是怎么做的,这些都是要通过一个一个方法定义好的。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值