kubernetes设计思考

766 阅读3分钟

因为现在公司做云计算的,所以最近接触kubernetes比较多,学习和思考了一些kubernetes相关的东西,由于不成体系,可能所叙述的内容没有连续性,权当在这里做一个记录。

  • kubernetes集群设计思路
  • 边车模式
  • kube-proxy的作用
  • apiserver插件责任链

kubernetes集群设计思路

kubernetes设计思路上来讲,K8S集群其实就是传统业务系统加上反向代理和自动运维调度系统。这种设计思路和现代化的运维一体化很契合。具体来看和反向代理一样,服务有它的在集群内的地址和端口;服务后边会放置多个实例(在kubernetes集群中就是pod)作为其后端实例,这些后端实例可以单独向外部提供服务。就像下图一样,图中的负载均衡指的就是kubernetes中的Service,后端实例指的就是kubernetes中的Pod。

单点负载均衡

边车模式

了解过grpc,微服务,服务网格的同学可能对边车这个概念很熟悉了。微服务和服务网格的职责,就是处理服务间通讯,这正是服务治理的核心所在。服务与服务之间,服务与负载均衡器之间有着明确的界限,也即服务网格独立于具体的服务而存在(本质上是为了从根本上解决了微服务框架在代码侵入方面存在的问题)。

那你可能会问,这和之前提到的反向代理模式有什么关系吗?其实边车模式就是遵循这种设计思路的。kubernetes在实际实现中,上文提到的这个反向代理,并不是部署在集群某一个节点上,而是作为集群节点的边车,部署在每个节点上的。可谓是一对一并行部署边车进程,接管该服务实例所有对外的网络通讯(参见下图)。这样就去除了代理模式下中心化架构的瓶颈。同时,借助于良好的框架封装,运维成本也可以得到有效的控制。其实K8S集群原始服务的实现,就是基于边车模式的。

kube-proxy的作用

按照这种设计,kubernetes中这个组件叫kube-proxy,是K8S集群的一个控制。简单来说,kube-proxy作为部署在集群节点上的控制器,它们通过集群API Server监听着集群状态变化。当有新的服务被创建的时候,kube-proxy则会把集群服务的状态、属性,翻译成反向代理的配置。如下图所示:

apiserver插件责任链

Kubernetes的apiServer中有个组件的设计很像spring-mvc框架中的责任链模式,这个组件叫 AdmissionController,也是一个插件化的组件,责任链中的每个插件针对 apiserver 收到的请求做一些操作或校验。举两个插件的例子:

  • DefaultStorageClass,为没有声明 storageClass 的 PVC 自动设置 storageClass
  • ResourceQuota,校验 Pod 的资源使用是否超出了对应 Namespace 的 Quota

AdmissionController插件化是通过webhook来实现的,kubernetes把webhook 分成了两类:

  • MutatingAdmissionWebhook:控制api对象
  • ValidatingAdmissionWebhook,校验api对象

这样就能灵活的组合不同的Webhook来达到自己的定制化流程。另外Istio使用了MutatingAdmissionWebhook来实现了envoy 容器的注入的。这种责任链的模式具有非常强的扩展能力,能非常干净地解决问题,可以与与其它逻辑做到很好的解耦。

当然了,Kubernetes 中还有非常多的扩展点,从 kubectl 到 apiserver,scheduler,kubelet(device plugin,flexvolume),自定义 Controller 再到集群层面的网络(CNI),存储(CSI)可以说是处处可以做事情。以后对这些得加以深入研究分析。