Kubernetes核心组件介绍(二)
一、Kube-APIServer
提供kubernetes各类资源(如pod、replicaset、deployment、service等)的增、删、改、查及watch的Rest接口,成为集群内各模块数据交互和通信的中心枢纽,是整个系统的数据总线和数据中心,还有以下特性:
1)集群管理的API入口
2)资源配额控制的入口
3)提供集群的安全机制
默认情况下在本机的8080端口下提供Rest服务,可以同时启动HTTPS的安全端口8443来启动安全机制
Proxy API接口
在浏览器输入:http://localhost:8080/api/v1/proxy/namespaces/default/pods/myweb-g9pmm 这个地址就可以访问到myweb-g9pmm的pod容器,他的请求过程是kube-apiserver把收到的rest请求转发到对应的node上的kubelet守护进程的Rest端口上,由kubelet负责响应。
集群各模块之间的通信
集群中的各模块通过ApiServer将信息存入etcd,当需要获取或操作这些数据时,则通过API Server提供的Rest接口(GET LIST WATCH)等方法来实现,从而实现各模块间的信息交互。
比如kubelet跟apiserver间的交互,每个节点上的kubelet进程每隔一个时间间隔,就会调用API Server的REST接口报告自身状态,API Server收到这些信息后,将节点状态信息更新到etcd中。此外,kubelet通过也通过API Server的WATCH接口监听Pod信息,如果监听到新的pod副本被调度绑定到本节点,则执行pod对应的容器创建和启动逻辑。如果监听到pod删除,则删除本节点上相应的pod容器,如果监听到pod修改,则kubelet会修改本节点相应的pod容器。
还有kube-controller-manager与API Server的交互,kube-controller-manager中的node controller通过API Server的WATCH接口,实时监控node的信息,并作相应的处理。
还有kube-scheduler与API Server的交互,当Scheduler通过WATCH接口监听到新建pod副本的消息后,它会检索所有符合该pod要求的node列表,开始执行pod的调度逻辑,调度成功后将pod绑定到目标节点上。
为了缓解各模块对API Server的访问压力,各功能模块都通过缓存机制来来缓存数据,各功能模块定时从API Server获取指定的资源对象信息(通过LIST、WATCH方法),然后将信息保存到到本地缓存,功能模块在某些情况下不直接访问API Server,而是通过访问缓存间接访问API Server。
二、Kube-Controller-Manager
集群内部的控制管理中心,负责集群内的Node,Pod副本,服务端点(Endpoint)、命名空间(namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)等的管理。当某个Node宕机时,ControllerManager会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。通过API Server提供的接口实时监控集群中每个资源对象的当前状态,当发生故障导致系统状态变化ControllerManager都会试着将系统”当前状态"修正到“预期状态"。
Replication Controller:副本控制器,确保集群在任何时候RC所关联的pod的副本数量保持预设值;删除RC不会影响它所创建的Pod,如果想删除Pod,只需设置RC的副本数量等于0;最好不要直接创建Pod,通过RC管理Pod副本,实现自动创建、替换、补足、删除Pod副本,这样能提高系统的容灾能力。即使是只有一个人pod副本,也通过RC来创建。
Replication Controller的职责:
1)确保集群中有且仅有N个pod副本;
2)通过调整RC的spec.replicas属性值来实现系统扩容或者缩容;
3)通过改变RC的Pod模板(主要是镜像版本)来实现系统的滚动升级;
Node Controller:从API Server实时获取Node相关信息,实现管理和监控集群中的各个Node节点,
ResourceQueta Controller:资源配额管理确保指定的资源对象在任何时候不会超量占用系统资源,避免由于部分业务进程的设计缺陷导致整个系统紊乱或意外宕机。
kubernetes资源限制层次:
1)容器级别:对CPU和内存进行限制;
2)Pod级别:对Pod内所有资源进行限制;
3)namespace级别:为namespace(多租户)进行限制;
Namespace Controller:
Service Controller:是kubernetes集群与外部云平台之间的一个接口控制器,Service Controller监听Service的变化,如果Service是一个loadbanlancer类型的service,则Service Controller确保外部云平台上该Service对应的loadbalancer实列被相应的创建、删除及更新路由转发表
Endpoints Controller:Endpoints表示一个Service对应所有Pod副本的访问地址,Endpoints Controller就是负责生成和维护Endpoints对象。负责监听Service和对应Pod副本的变化,如果监测到Service被删除,则对应的Endpoints也会删除,如果Service被创建或者修改,则根据Service获得相关的pod列表,然后创建或者更新对应的Endpoints对象,Endpoints是被每个节点上的Kube-proxy进程使用,kube-proxy进程获取每个service的endpoints,以实现Service的负载均衡功能。
三、Kube-Scheduler
Kube-Scheduler的作用是将待调度的Pod(新建的pod、ControllerManager为补足副本创建的pod)按照特定的算法和特点的策略绑定到一个合适的node节点上,并将信息存入etcd。随后,目标节点上的kubelet进程通过API Server监听到kube-scheduler产生的Pod绑定事件,获取对应的Pod清单,让后下载image镜像,并启动容器。
kube-sheduler目前默认提供的调度流程分为两步:
1)预选调度过程:遍历所有的node节点,通过预选策略筛选出符合要求的候选节点,内置了多种策略供用户选择;
2)确定最优节点:采用优选策略计算出每个候选节点的积分,积分高的胜出。
Scheduler是通过插件的方式加载"调度算法提供者"来具体实现的。
预选策略有:
NoDiskConfict:遍历所有备选pod的Volume信息与备选节点上的所有pod的每个volume进行比较,检查是否有冲突;
PodFitsResource:判断备选节点的资源是否满足pod的需求,计算备选pod和目标节点已存在pod的内存和cpu的总和;
PodSelectorMatches:判断备选节点是否含有pod标签选择器指定的标签;
PodFitsHost:判断备选pod的spec.nodename域所指定的节点名称跟备选节点的名称是否一致;
CheckNodeLabelPresence:检查备选节点的标签列表信息;
CheckServiceAffinity:检查备选节点是否含有策略指定的标签;
PodFitsPorts:判断备选Pod的端口在备选节点上是否已经被占用;
优选策略有:
LeastRequestedPriority:从备选节点列表中选择资源消耗最小的节点,计算备选节点上所有运行的pod和备选的pod所有的cpu和内存使用量总和;
CalculateNodeLabelPriority:判断备选节点的标签是否在优选策略标签列表中;
BalancedResourceAllocation:从备选节点中选择各项资源使用最均衡的节点;
四、kubelet
在每个node节点上都会启动一个kubelet服务进程,该节点处理从Master节点下发到该node节点上的任务,管理Pod和Pod中的容器;每个kubelet进程都会向API Server注册自身的节点信息,并定期向Master节点报告节点本身的资源使用情况,并通过cAdvisor监控容器和节点资源。
节点管理
设置kubelet的启动参数"--register-node"来决定是否向API Server注册自己,在集群运行过程中遇到资源不足的情况用户很容易添加机器并通过kubelet自注册的模式来实现扩容;
如果没用选择自注册的模式,用户需要自己去配置node的资源信息。kubelet在启动时通过API Server注册节点信息,并定时向API Server发送节点的新消息,API Server在接到这些信息后,将这些信息写入etcd。kubelet通过启动参数”--node-status-update--frequency“设置每个多少时间向API Server报告自己的信息,默认是10s
Pod管理
kubelet通过以下几种方式获取自身node上所要运行的pod清单:
1)定时检查配置文件(/etc/kubernetes/mainifests)
2)定时请求Http端点
3)通过API Server监听etcd目录,来同步更新Pod列表
所有非API Server方式创建的Pod都叫static pod
一般是使用kubelet通过API Server Client使用Watch加List的方式监听”/registry/nodes/当前节点名“ 和"/registry/pods/"目录,将获取到的信息同步到本地缓存中;
kubelet读取监听到的信息,如果是创建或修改Pod的任务,则做如下处理:
1)为该Pod创建一个数据目录;
2)从API Server读取Pod清单信息;
3)为该Pod挂载外部Volume;
4)下载Pod用到的secret;
5)检查在节点运行的Pod,如果Pod没有容器或pause容器没有启动,则先停止Pod里所有的容器
6)用”kubernetes/pause“为每个Pod创建一个容器,Pause容器用于接管Pod中其他容器的网络,没创建一个新的Pod都会创建一个Pause容器,然后创建其他容器
7)用容器额名称去查询对应Docker容器,如果容器的hash值不相同则停止docker容器,如果相同则不做任何处理;如果容器被终止并且容器没有设置重启策略,则不做任何处理;最后调用docker client下去容器镜像,并调用docker client运行容器;
容器健康检查
Pod通过两类探针来检查容器的健康状态
1)LivenessProbe探针:用于判断容器是否健康,告诉kubelet容器什么时候处于不健康状态,如果探针检查到容器不健康,则kubelet会删除该容器,并根据容器的重启策略作相应的处理,如果容器没有设置LivenessProbe探针,则kubelet认为该容器LivenessProbe探针的返回值永远是success;
2)ReadinessProbe探针:用于判断容器是否启动成功,并准备接收请求;如果ReadinessProbe探针检测到失败,则Pod的相应状态会被修改,
kubelet定期调用LivenessProbe探针来检查容器的健康状态,探针的三种实现:
1)ExecAction:在容器内执行一个命令如果命令的退出状态码=0 则认为容器健康;
2)TCPSocketAction:通过容器的IP地址和端口执行TCP检查;
3)HTTPGetAction:通过容器提供的Http端点来检查,如果返回的状态码>=200 && <=400,则认为容器健康;
cAdvisor资源监控
kubelet通过cAdvisor工具获取每个容器的使用统计信息
五、kube-proxy
为了支持集群的水平扩展和高可用性,kubernetes抽象出了Service的概念,Service就是一组Pod的抽象,Service会根据访问策略(负载均衡)来访问这组Pod;
kubernetes在创建一个Service时会创建一个虚拟的IP地址,客户端通过这个虚拟IP地址来访问Service,则Service负责将请求转发到后端Pod上(类似一个反向代理的功能,因为是虚拟的IP地址,从外面访问还需做别的处理)。Service只是一个逻辑概念,其背后的实现靠的是kube-proxy进程。
kubernetes集群的每个节点都会运行一个kube-proxy进程,这个进程充当Service的透明代理和负载均衡器,其核心功能就是将某个请求转发到后端某个Pod实例上。默认是Round Robin
Service的Cluster IP和NodePort等概念是kube-proxy通过iptables的NAT转换实现的,在运行过程中动态创建与Service相关的iptables规则,这些规则实现了从ClusterIP及NodePort的请求流量重定向到kube-proxy进程上对应服务的代理端口的功能。由于iptables是针对的是本地kube-proxy端口,所有每个Node都要运行kube-proxy组件,这样在集群内部,可以在任意节点对Service发起访问请求。
访问Service的请求,不管是ClusterIP+TargetPort,还是节点机IP+NodePort的方式,都被节点机的iptables规则重定向到kube-proxy监听Service的服务代理端口。

kube-proxy实现细节:
kube-proxy通过查询和监听API Server中Service和Endpoints的变化,为每个Service建立一个服务代理对象,并自动同步。kube-proxy也会创建一个负载均衡器LoadBalancer,LoadBalancer保存了Service对应后端EndPoints列表的动态转发路由表。具体的路由选择取决于负载均衡算法。
针对变化的Service,kube-proxy会逐个处理,具体流程如下:
1)如果Service没有设置集群IP,则不做任何处理,否则,获取该Service所有端口定义列表(spec.ports)
2)逐个读取Service服务端口定义列表的所有端口信息,通过Service名称、端口名称、Namespace来判断本地是否存在服务代理对象,如果不存在则新建,如果存在并且Service端口被修改则先删除iptables中和该Service端口相关的规则,关闭代理服务对象,然后新建,即为Service端口分配代理服务对象并为该Service创建相应的iptables规则。
3)更新负载均衡组件中的Service对应的Endpoints的转发地址列表,对应新建的Service,确定转发策略;
4)对已经删除的Service进行清理


浙公网安备 33010602011771号