查看原文
其他

K8S的SDN容器网络解决方案【机制篇】

Karl CSDN云计算 2019-02-23

戳蓝字“CSDN云计算”关注我们哦!


编者按:关于容器网络的解决方案业界已经有较多的讨论,笔者无意继续赘述。本文从K8S的网络实现入手,重点阐述SDN在容器网络中的应用价值。K8S及其网络模型体现了鲜明的解耦设计思想,采用SDN技术实现K8S容器网络,并与相应的生态组件形成SDN监管控一体化解决方案,可以更好地提高整个系统的运营水平,更有效地提升企业的核心竞争力。本篇将谈论的是K8S的机制原理。

综述:K8S的基本机制是以“对象-控制器”架构模式为基础设计与实现的。组件API server与etcd的主要功能是实现对各种资源对象REST风格的增删改查CRUD、盯Watch操作。组件controller-manager包括了各种内置控制器,其功能是确保整个系统处于预期的状态。这种数据存储与应用逻辑分离的模式是各功能组件实现无状态服务架构的关键。K8S集群针对基本操作单元Pod对象的处理主要是通过scheduler和kubelet实现的。实际上我们可以把scheduler看作是集群层面的Pod对象控制器,把kubelet理解为是节点层面Pod对象的创建与维护的控制器。

K8S场景下实现Pod互联等的容器网络特别是其数据转发面遵循并适用网络技术的一般性原则与实现。当前主流的容器网络基本解决方案主要包括以Calico为代表的基于经典的三层路由/Netfilter模型的实现,和以OpenShift的SDN实现为代表的二层SDN/OVS模型的实现。而容器网络的特殊性则主要体现在管理控制面实现、以及基于K8S扩展机制的SDN控制器云原生部署等方面。K8S及其网络模型体现了鲜明的解耦设计思想,不论是在K8S与网络组件之间,还是在容器网络与Pod接入容器网络之间等各方面。

狭义地讲SDN的核心技术主要包括数据转发面特别是流表流水线的设计和相应的基于SDN控制器平台的应用的设计与实现等。SDN控制器与各节点上的SDN代理相配合完成系统容器网络的项目租户、网络子网路由、安全策略与服务、SLA/QoS的管控,以及监控可视化等各项操作。而CNI-Plugin的主要功能则是在kubelet创建Pod时将之挂接到容器网络上。在K8S场景下,SDN的价值同样体现在与各种生态组件的集成,实现一体化监管控解决方案,可以更好地提升整个系统的运营水平。

图1 K8S系统核心组件构成

K8S基本机制

K8S集群提供了以Pod为基本操作单元的容器化应用的部署、维护、扩展等功能。主要由主节点上的API server、etcd、controller-manager、scheduler等,以及工作节点上的kubelet、容器运行时等功能组件构成。命令行kubectl可以在主节点上也可以部署在远程运行,并通过API server调用与K8S交互。etcd集群可以采用与主节点分离的方式进行部署。另外,即使是主节点不参与业务Pod的分配与创建,也需要运行有一个kubelet实例。

对象处理组件与功能

kube-apiserver:API server通过Web Service端点处理函数的注册与相应的访问请求相关联,实现REST机制对资源对象的增删改查CRUD盯Watch等的操作功能,是系统对外访问的统一入口。而K8S集群内部各功能组件之间的互动也主要是通过API server 的Watch机制实现的。API server本身实现了无状态服务架构模式。Web Service端点以API Group来管理分组和版本适配,分组包括核心组、扩展组、其他的auto scaling组、metrics组等。而Proxy类API server接口的作用是代理REST请求,并转发给相应节点的kubelet进行实际的操作处理。此外API server还提供有各种web hook扩展机制。

etcd集群:etcd是Go语言编写的基于raft分布式协议的高可用key-value存储系统,作为API server的后台用于K8S存储各种资源对象包括外部扩展定制资源对象(CRD - Custom Resource Definition)等配置与状态信息,支持典型的消息发布与订阅机制,即Watch机制。etcd是K8S组件API server等实现无状态服务架构的基础。K8S集群内任何对资源对象的增删改查CRUD盯Watch操作等都通过API server的storage接口统一与etcd交互,各组件不会直接操作etcd。

控制器架构模式及组件功能

控制器模式是K8S各组件功能实现的基本框架,其基础主要是基于etcd特性在API server内部实现的List-Watch机制和相应的client-go客户端平台库函数。

List-Watch机制:该机制是基于etcd本身的Watch特性的,属于API server对资源对象CRUD操作的体系化扩展。API server内部向etcd发起的Watch只能订阅某个对象的创建、删除事件,无法设置过滤条件的,不能针对对象的属性进行过滤;而API server实现对外部各种K8S功能组件发起的Watch请求的处理,并能够针对对象属性进行过滤。在集群运行过程中组件向API server发送REST请求进行Watch订阅,告诉API server对什么资源对象及发生什么样的变化事件感兴趣。而每一个Watch操作的生命周期对应相应的HTTP REST请求的生命周期。

库函数client-go包括了访问API server的客户端,以及支持控制器实现所需的相关平台机制List-Watch的客户端informer和事件队列workqueue等。这样控制器的设计与实现只需专注应用逻辑,只需提供对象的事件回调函数和相应的队列处理功能即可。

图2 K8S控制器架构模式

控制器架构模式:一个典型的控制器实现通过API server的List-Watch机制的客户端informer与API server保持交互,跟踪特定的资源对象的状态与变化。对象变化的事件由informer调用相应的callback完成一些基本的处理,然后把相关的变更及对象信息放到workqueue里面。控制器的应用逻辑实现在worker协程里面。控制器可启动多个worker协程来处理workqueue里的对象事件。根据对象的期望状态和当前系统的实际情况进行相应的处理,并通过clients向API server发送行动请求。实际上也是通过对其他相关下游资源对象的设置,以实现整个集群向期望的状态演进。此外,为缓解各组件模块对API server的访问压力、提高处理性能,控制器的内部实现也都采用了缓存机制的支持。

kube-controller-manager:K8S内置了一系列的控制器,基本上都是嵌入在controller-manager进程里的。其中,Replication Controller的功能是确保集群中有且仅有指定个数的Pod实例在运行,可以通过调整RC中的副本数量来实现系统扩容或缩容,通过改变RC中的Pod模板来实现系统的滚动升级;Endpoints Controller中的Endpoints表示某个Service对应的所有Pod副本的访问地址。此控制器的功能是通过监听Service和对应的Pod副本的变化,负责生成和维护所有Endpoints对象。而工作节点上的kube-proxy就是通过监听Service和Endpoints来配置相应的数据面实现相应的转发和负载均衡功能。我们可以理解Endpoints Controller是K8S除Pod以外最重要的资源对象服务Service的集群层面的控制器,而kube-proxy则是相应节点层面的控制器;Namespace Controller的功能是在后台实现优雅地删除某Namespace下的Service Account、RC、Pod等资源对象及此Namespace本身;Service Accounts Controller的功能是为每个Namespace维护一个默认的Service Account,并与Token Controller配合实现K8S集群内部Pod访问API server的认证功能。

K8S除本身内置的这些控制器外,也支持各种用户自定义扩展。控制器可以运行在K8S主节点上,也可以运行在工作节点上;可以运行在K8S集群内,甚至运行在集群外。

图3 Pod调度、创建、CNI-Plugin挂接容器网络的处理时序

Pod处理组件与功能

基本上K8S的资源对象与控制器都是相互对应、配合起来完成相应的功能的。但如果注意到的话,在controller-manager中并没有针对Pod对象操作的控制器。实际上K8S决定把Pod放到哪个节点上是由组件scheduler按照相应的策略决策的,而Pod的实际创建与维护是由kubelet完成的。所以我们可以理解为scheduler是Pod集群层面的控制器,kubelet则是Pod节点层面的控制器。

具体的来说,就是scheduler通过API server提供的Watch等接口,监听并获取到未调度的Pod和节点等的相关信息,通过过滤和优先级算分对节点筛选,选择出最合适的节点,将Pod与此节点绑定,并把结果通过API server存储到etcd中。在相应工作节点上的kubelet会去实际创建Pod的SandBox,调用CNI-Plugin进行相应的网络配置挂接SandBox网络名字空间到容器网络上,创建和运行Pod所属的init容器,最终创建和运行Pod的常规业务容器。

关于K8S的机制今天就先介绍到这里,接下来我们将介绍容器网络的具体实现。


 

1.微信群:

添加小编微信:color_ld,备注“进群+姓名+公司职位”即可,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


2.征稿:

投稿邮箱:liudan@csdn.net;微信号:color_ld。请备注投稿+姓名+公司职位。


推荐阅读


点击“阅读原文”,打开 CSDN App 阅读更贴心!

喜欢就点击“好看”吧!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存