支撑大规模公有云的Kubernetes改进与优化 (3) 上篇

勿忘初心2018-11-08 15:46

此文已由作者刘超授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验


这一篇我们来讲网易为支撑大规模公有云对于Kubernetes的定制化。


一、总体架构



网易的Kubernetes集群是基于网易云IaaS平台OpenStack上面进行部署的,在外面封装了一个容器平台的管理层,负责统一的账号,计费等。


Kubernetes集群当然是要高可用的,因而会有多个Master节点。


其中APIServer前端有负载均衡器haproxy,需要有一个VIP,在两台haproxy之间进行漂移,保证一台啊挂了,另外一台能够使用同一个VIP接上。



这种漂移使用的协议为VRRP。


Scheduler和Controller也是有多份的,但是只能有一个Leader,需要通过etcd进行选举。


另外网易自身实现的部分放在单独的进程里NeteaseController,用于处理和IaaS层联动的功能。


二、一个还是多个Kubernetes集群?



一般有IaaS平台的公有云或者私有云部署Kubernetes采用的是左面的样子。也即通过调用IaaS层的API,自动化部署多个Kubernetes平台,每一个Kubernetes平台仅仅属于一个租户。


这样的好处是不同的租户的Kubernetes之间是完全隔离的。


坏处也很多:

  • 当租户非常多的时候,Kubernetes集群非常多,非常难以维护

  • 每个Kubernetes集群的规模非常小,完全不能发挥容器平台的优势,容器平台相对于IaaS平台比较轻量级,按最佳实践是能够管理比IaaS更大的集群的,例如几万或者几十万个节点,然而这种方式会将Kubernetes集群限制在很小的规模。

  • 虽然很多云平台提供Kubernetes集群的自动化部署工具,但是仅仅自动化的是安装过程,一旦这个集群交给客户了,云平台就不管了,这样Kubernetes的升级,修复,运维全部要客户自己来,大大提升了运维成本。

  • Kubernetes集群规模需要提前规划阶段数目,添加新的节点数目需要手动进行。


网易采用的是右面的方式,整个IaaS层上面只有一个Kubernetes平台,Kubernetes平台的运维,升级,修复全部由云平台运维人员进行,运维成本较低,而且不需要用户自己操心。


对于用户来讲,看到的就只是容器,不用关心容器平台。当用户创建容器的时候,当Kubernetes集群资源不足的时候,Netease Controller会自动调用IaaS层API创建虚拟机,然后在虚拟机上部署容器,一切自动进行。


当然这种方式的一个缺点是一个Kubernetes的不同租户之间的隔离问题。



采取的方式是不同的租户不共享虚拟机,不同的租户不共享虚拟网络,这样租户之间就隔离了,容器的内核也隔离了,二层网络也隔离了。


当然这个方式的另一个问题是Kubernetes的集群数目非常大,这在下面会详细说这个事情。


还有一个问题是容器放在虚拟机里面,虚拟机的启动速度就成了很大的问题,如果启动速度很慢,则会拖慢容器的敏捷性。


三、APIServer认证模块接Keystone解决复杂的租户管理问题


Kubernetes有基于keystone的用户名和密码进行认证的默认机制,然而每次用用户名和密码进行认证是效率很低的。


网易通过定制化认证流程,使得apiserver也采用类似nova的认证方式。


APIServer在keystone里面注册一个service角色的账号,并从keystone获取临时管理员的Token。


客户请求到来的时候,通过用户名密码到Keystone进行认证,获取一个token,并且带着这个token到APIServer进行认证,APIServer带着这个token,连同自己的临时管理员的Token进行联合认证,如果验证通过则获取用户信息,并且缓存到etcd里面。


当客户通过获取的token来请求的时候,先从etcd里面读取这个token进行验证,为了使用本地缓存,加一个listwatch实时同步etcd里面的内容到本地缓存。


如果token过期,则从新到keystone里面revoke。



四、从APIServer看集群的规模问题


随着集群规模的扩大,apiserver的压力越来越大。


因为所有的其他组件,例如Controller,Scheduler,客户端,Kubelet等都需要监听apiserver,来查看etcd里面的变化,从而执行一定的操作。


很多人都将容器和微服务联系起来,从Kubernetes的设计可以看出,Kubernetes的模块设计时非常的微服务化的,每个进程都仅仅干自己的事情,而通过apiserver松耦合的关联起来。


而apiserver则很像微服务中的api网关,是一个无状态的服务,可以很好的弹性伸缩。



为了应对listwatch,apiserver用了watchcache来缓解压力,然而最终的瓶颈还是在etcd上。


最初用的是etcd2,这个时候listwatch每次只能接受一个事件,所以压力很大。为了继续使用etcd2,则需要使用多个etcd2的集群来解决这个问题,通过不同的租户分配到不同的etcd2集群来分担压力。


将来会迁移到etcd3有了事件的批量推送,但是从etcd2到etcd3需要一定的迁移工作。


五、通过优化Scheduler解决并行调度的问题


对于大的资源池的调度是一个很大的问题,因为同样一个资源只能被一个任务使用,如果并行调度,则存在两个并行的调度器同时认为某个资源空闲,于是同时将两个任务调度到同一台机器,结果出现竞争的情况。


当OpenStack遇到这种问题,采取的方法是重新调度的方式进行。


而Mesos则采取了更为聪明的两层调度的算法。



详情见文章号称了解mesos双层调度的你,先来回答下面这五个问题!


Mesos首先通过第一层的调度Allocator,将不同的节点分给不同的Framework,则不同的Framework就能看到不同的节点了,不同Framework里面的调度器是第二层调度,是能够并行调度的,并且即便并行调度,不同的Framework也是不会调度到冲突的节点的。


Mesos的双层调度策略,使得Mesos能够管理大规模的集群,例如tweeter宣称的几十万的节点,因为对于某一个Framework来讲,不会同时在几十万个节点中选择运行任务的节点,而是仅仅在其中mesos分配给他的一部分中进行调度,不同的framework可以并行调度。


还记得前面我们提到的,为了租户隔离,不同的租户是不共享虚拟机的,这样不同的租户是可以参考Mesos的机制进行并行调度的。因为不同的租户即便进行并行调度,也不会出现冲突的现象,每个租户不是在几万个节点中进行调度,而仅仅在属于这个租户的有限的节点中进行调度,大大提高了调度策略。


并且通过预过滤无空闲资源的Node,调整predicate算法进行预过滤,进一步减少调度规模。



相关阅读:

支撑大规模公有云的Kubernetes改进与优化 (1)

支撑大规模公有云的Kubernetes改进与优化 (2)

支撑大规模公有云的Kubernetes改进与优化 (3) 下篇


容器服务是网易云提供的无服务器容器服务,让企业能够快速部署业务,轻松运维服务。容器服务支持弹性伸缩、垂直扩容、灰度升级、服务发现、服务编排、错误恢复及性能监测等功能。点击可免费试用


免费体验云安全(易盾)内容安全、验证码等服务

更多网易技术、产品、运营经验分享请点击