27.5 重要组件
如果现在从头设计一套容器集群管理平台,可能不同人最终设计出来的方案是不相同的,但相信大部分都能想到如下几个方面的需求:
·要采用分布式架构,保证良好的可扩展性;
·控制平面要实现逻辑上的集中,数据平面要实现物理上的分布;
·得有一套资源调度系统,负责所有的资源调度工作,要容易插拔;
·对资源对象要进行抽象,所有资源要能实现高可用性。
Kubernetes中的节点包括两种类型:Master节点负责控制,Node节点负责干活,各自又通过若干组件组合来实现。
Master节点上组件主要有Etcd、apiserver、scheduler、controller-manager,以及ui、DNS等可选插件:
·Etcd:作为数据库,存放所有集群相关的数据;
·kube-apiserver:Kubernetes系统的对外接口,提供RESTful API供客户端和其他组件调用,支持水平扩展。
·kube-scheduler:负责对资源进行调度,具体负责分配某个请求的Pod到某个节点上;
·kube-controller-manager:对不同资源的管理器,包括节点管理器、复制管理器、服务管理器、权限管理器等;
·kube-ui:自带的一套用来查看集群状态的Web界面;
·DNS:记录启动的容器组和服务地址;
其他组件:包括容器资源使用监控、日志记录、setup脚本等。这些组件可以任意部署在相同或者不同机器上,只要可以通过标准的HTTP接口相互访问到即可,这意味着对Kubernetes的管理组件进行扩展将变得十分简单。
Node节点上主要包括kubelet、kube-proxy、容器引擎和一些辅助组件:
·kubelet:节点上最主要的工作代理,汇报节点状态并实现容器组的生命周期管理;
·kube-proxy:代理对抽象的应用地址的访问,负责配置正确的转发规则;
·容器引擎:本地的容器依赖,目前支持Docker和rkt;
·辅助组件:supervisord用来保持kubelet和docker进程运行,fluentd用来转发日志等。
下面分别介绍这些组件的作用和基本用法。
27.5.1 Etcd
Kubernetes依赖Etcd数据库服务来记录所有节点和资源的状态。可以说,Etcd是Kubernetes集群中最重要的组件。apiserver的大量功能都是通过跟Etcd进行交互来实现。关于Etcd数据库的详细信息,请参考之前的第22章。
27.5.2 kube-apiserver
作为REST API服务端,kube-apiserver接收来自客户端和其他组件的请求,更新Etcd中的数据,是响应对API资源操作的最前端组件。一般推荐部署多个kube-apiserver来提高可用性。
可以通过kube-apiserver-h命令查看服务端支持的参数选项,其中比较重要的配置选项参见表27-1。
表27-1 kube-apiserver配置选项

27.5.3 kube-scheduler
kube-scheduler负责具体的资源调度工作,对节点进行筛选和过滤。当收到资源请求后,负责按照调度策略选择最合适的节点运行Pod。
kube-scheduler是以插件形式存在的,支持各种复杂的调度策略,确保Kubernetes集群服务的性能和高可用性。kube-scheduler在调度上考虑服务质量、软硬件限制、(抗)亲和性(affinity)、locality、工作负载交互等多个方面。
可以通过kube-scheduler-h命令查看支持的参数选项,其中比较重要的配置选项参见表27-2。
表27-2 kube-scheduler配置选项

27.5.4 kube-controller-manager
提供控制器服务,监视集群的状态,一旦不满足状态则采取操作,让状态恢复正常,常见的控制器包括:
·复制(replication)控制器:确保指定Pod同时存在指定数目的实例;
·端点(endpoint)控制器:负责Endpoints对象的创建,更新;
·节点(Node)控制器:负责节点的发现,管理和监控;
·命名空间(namespace)控制器:响应对命名空间的操作,如创建、删除等;
·服务账户(ServiceAccounts)控制器:管理命名空间中的ServiceAccount,确保默认账户存在于每个正常的命名空间中。
可以通过kube-controller-manager-h命令查看支持的参数选项,其中比较重要的配置选项见表27-3。
表27-3 kube-controller-manager配置选项

27.5.5 kubelet
kubelet是Node节点上最重要的工作程序,它是负责具体干活的,将给定的Pod运行在自己负责的节点上。
如果kubelet出现故障,则Kubernetes将用人工使该Node变得不可用。因此,在生产环节中推荐对kubelet进程进行监控,并通过诸如supervisord这样的软件来及时重启故障的进程。
另外,一般要通过—system-reserved和—kube-reserved参数为系统和Kubernetes组件预留出运行资源,避免耗尽后让节点挂掉。
可以通过kubelet-h命令查看支持的参数选项,其中比较重要的配置选项见表27-4。
表27-4 kubelet配置选项


27.5.6 kube-proxy
kube-proxy会监听在每一个Node节点上,负责把对应服务端口来的通信映射给后端对应的Pod。简单的说,它既是一个NAT(支持TCP和UDP),同时也有负载均衡(目前仅支持TCP)的功能。
例如,服务test-service定义服务端口为80,实际映射到大量Pod的8080端口上:
- {
- "kind": "Service",
- "apiVersion": "v1",
- "metadata": {
- "name": "test-service"
- },
- "spec": {
- "selector": {
- "app": "webapp"
- },
- "ports": [
- {
- "protocol": "TCP",
- "port": 80,
- "targetPort": 8080
- }
- ]
- }
- }
则kube-proxy会自动配置本地的iptables rales规则,一旦有网包(client)想访问服务的80端口,将到达的网包转发到某个绑定Pod的8080端口。在1.2.0版本开始,kube-proxy已经默认完全通过iptables来配置对应的NAT转发过程,自身不再参与转发过程,如图27-4所示。

图27-4 kube-proxy运行机制
kube-proxy默认采用轮询的负载均衡算法,并且支持亲和性。例如如果配置service.spec.sessionAffinity为ClientIP,则同一个客户端发过来的多个请求会转发给同一个后端的Pod,保证了会话一致性。具体实现上,在早期版本中采用用户态的程序来转发,现在已经逐渐转换到基于Linux Iptables的更高效转发机制。
可以通过kube-proxy-h命令查看支持的参数选项,其中比较重要的配置选项参见表27-5。
表27-5 kube-proxy配置选项

