01 JAN

Kubernetes如何降低云的复杂性

Kubernetes过度用于安全性和基础设施,但未充分用于自动化。那些最需要它的人并没有意识到它的潜力。

不久前,我宣布Kubernetes赢得了容器编排大战。虽然我一贯持正确观点,但云计算行业的很多人已将Kubernetes视为解决所有问题的终极技术。

因此,我们滥用Kubernetes来解决所有的安全问题和基础设施问题,甚至完全成了正在寻觅下一个舒适区的科技公司的战略。真是三句不离Kubernetes。

身为云计算的实践者,以及在本地云和公共云中利用Kubernetes的人,我可以告诉你,Kubernetes的大部分优点都是真的。但是,我还可以告诉你,人们并不认为Kubernetes有助于解决2020年面临的核心问题——云复杂性。

云复杂性有两个主要成因:

首先,人们在选择云平台时过度使用异构性。虽然多云是个好主意,但将为数众多的API混入一个统一的平台中,这使得开发人员的工作和操作任务变得更为困难。

其次,在没有适当规划的情况下部署云解决方案。如果要以最小的风险部署到多云解决方案,你至少要了解你现在的出发点,你的目的地以及如何达到目的地。大多数企业都无法回答这些问题,却继续在消极被动的状态下运营。

云复杂性也同样有两种解决方案:

首先是抽象。使用具有共同特征的抽象层可以使你不必直接处理云原生工具和接口的复杂性。

第二,自动化。自动化接口的使用可以使操作更轻松,因此不再那么复杂。

Kubernetes解决了自动化问题。 Kubernetes生态系统(包括最近发布的Anthos)的本质就是抽象容器内的应用程序和数据。其真正的价值就在于以高度可扩展的方式将这些容器自动化,同时降低复杂性。

我担心的是,必须处理复杂性的人不了解自动化或不了解Kubernetes如何解决这些问题。他们专注于专用工具,而不是Kubernetes所隐含的理念,Kubernetes更像是一个元概念而不是一套工具。

如果你正在处理云复杂性,那么你必须关注自动化的价值,特别是新兴的支持技术,如Kubernetes。Kubernetes并不是解决云复杂性问题的万灵药,但它是一个概念,这个概念可以分解为有用的工具和方法,而且是专用的。

在Kubernetes实践的过程中,积累了一些填坑经验,希望能对准备或正在使用Kubernetes的小伙伴提供帮助。

滚动升级之更新太慢

默认情况下,滚动升级是逐个更新的,当有几十上百个Pod需要更新时,再加上就绪检测,整个过程将会更慢。如果你想和更多Kubernetes技术专家交流,可以加我微信liyingjiese,备注『加群』。群里每周都有全球各大公司的最佳实践以及行业最新动态

解决方法:

rollingUpdate:    maxSurge: 20% #每个滚动更新的实例数量    maxUnavailable: 10% #允许更新过程中有多少实例不可用

就绪检测之无损更新

通常,服务重启的时候会有一小段时间是无法正常提供服务的。

为了避免这个过程中有请求的流量进来,我们可以使用就绪检测来检测服务是否就绪可正常接收并处理请求。

......         readinessProbe:           httpGet:             host: api.xxx.com             path: /             port: 80           initialDelaySeconds: 3 # 容器启动3秒后开始第一次检测           periodSeconds: 60 # 每隔60s检测一次           timeoutSeconds: 3 # http检测请求的超时时间           successThreshold: 1 # 检测到有1次成功则认为服务是`就绪`           failureThreshold: 1 # 检测到有1次失败则认为服务是`未就绪` ......

就绪检测之全面瘫痪

就绪检测是把双利剑,用不好,反而容易出大问题,比如服务全面瘫痪。

我们可以看到上面就绪检测的配置,漏洞百出。

比如:超时,高并发情况下,请求处理不过来,个别服务很容易导致检测请求的超时(504),立马被认为未就绪,于是流量被转移到其它服务,进而让本来就高负荷的其它服务出现同样情况,恶性循环,很快,所有服务都被认为是未就绪,结果产生全面瘫痪现象。

解决方法:设置更长的超时时间,以及更高的失败次数。

重新部署,这种情况可能是误操作,也可能是其它异常导致服务挂了。总之,你需要在用户还在不断尝试请求你服务的时候重启。你会惊讶的发现,一直无法正常启动为就绪状态,所有服务都是未就绪。同样的原因,服务启动过程不是一次全部起来,而是逐批启动,这样每批服务启动后都无法hold住流量,于是还是恶性循环,全面瘫痪。

解决方法:先去掉就绪检测再重新部署。

自动扩展之瞬时高峰

自动扩展POD虽然好用,但如果扩展的指标(CPU、内存等)设置的过高,如:50%以上,那么,当突然有翻倍的流量过来时,根本来不及扩展Pod,服务直接就超时或挂掉。

解决方法:尽可能的把指标设置在一个较小的值,对以往流量做参考评估,确保了当有2倍、3倍甚至5倍的流量突袭时不至于hold不住。

自动伸缩之提前扩容

通常,节点的自动伸缩依赖于Pod的自动扩展时资源是否充足。然而在面对定时突然流量高峰的业务时,这种伸缩显然来不及,甚至常常出现高峰10分钟后才扩容的机器,流量已经回到低谷,完全启不到作用。并且,流量到底是因为业务属性很快回落,还是因为扩容不及时导致的流失?

解决方法:根据自身业务,参考以住流量数量及推广时间,找到规律,提前或定时触发自动扩容。

容器运行之僵尸进程

这是一个Docker旧版(<1.13)已知问题,有些容器启动后会出现defunct进程(ps aux | grep defunct),而且会越来越多,称为僵尸进程,可能导致内存泄漏,而且kill不掉,除非重启容器。

解决方法:tini

集群节点之移除节点

如何安全地移出节点?这个节点上面部署了你的业务,甚至包括kube-system的东西。

解决方法:kubectl drain,可以先把节点上的Pod驱逐到其它节点,然后再移出该节点。