Kubernetes笔记–02

Overview

前言

上一次写Kubernetes笔记时,版本还是1.9,现在都出到1.11了,更新速度非常快,但前段时间看到京东在使用1.6的版本,感觉安心了一些,因为我们现在还在使用1.5版本。

最近给老集群添加了一台新节点,需要用到这个两年前的老版k8s,相关的cni插件和镜像几乎都找不到,折腾了一个下午才把机子加入了集群。最初的计划是理顺一下整个系统,也过了一遍后台代码准备迁移Kubernetes。现在的想法是老版本也挺好的,因为升级新版本并不能解决当下的问题,最好的方式还是让老集群继续稳定运行下去。

折腾过后,总结一下与之前使用Vultr主机完全不同,主要是防火墙导致k8s相关程序及安装过程中拉取的镜像都无法访问,我认为最佳的方式是重编译k8s修改所需镜像地址,自建软件源供安装升级k8s,自建镜像中心供集群使用,这些都需要占用很多CPU、内存和硬盘资源。所以,在机器数量没有达到一定程度的情况下,最好不要使用k8s。这一次也不再讲具体的k8s内容,而是我们在使用k8s过程中的一些感受。

微服务

之前的团队使用单体架构,用nginx做负载均衡,分发请求给后端的两台机器,每台机器只跑一个服务,数据存储单独放置在其他机器上,最早需要自行写SQL获取数据,后来架构改变,由统一的基础数据部门编写接口,每次升级服务都需要等晚上10点以后,首先升级一台机器,查看是否有错误日志,接着升级另一台,然后验证APP。记得最糟糕的一次上线经历,我们的服务升级失败,因为依赖的数据服务挂了,找人修复后继续升级,接着数据服务所在的机器挂了,最后还在回家路上的同事都被喊了回来,三个组的人马折腾了两个多小时没有成功,把升级操作延后一天。

现在的团队使用微服务架构(当然我无法确定是否完全符合微服务的定义),单体应用被拆分成多个服务,依旧使用nginx暴露服务到公网,facade提供对外接口,其他服务提供具体操作,zookeeper提供服务注册与发现,升级则通过Docker打包,推送到镜像中心,然后在k8s上修改版本号,滚动升级服务,每台机器上都部署了日志收集服务,错误日志通过elasticsearch处理,推送到钉钉。这里也提一下最糟糕的一次升级,由于阿里云变动ECS内网IP,导致集群内部失联,所有服务挂掉,包括zookeeper,即使在集群恢复后,服务间也处在失联状态,只能重新部署,然后注册到zookeeper。

这两者有没有比较大的差别呢?从运维和开发的角度讲,前者基本不需要运维,让开发者自行升级两台机器就好,而后者对运维提出了很高的要求,所有的机器是一个整体,升级的对象改为服务。在机器数量和高可用没有达标的情况下,一个核心服务的崩溃可能意味着整个系统的崩溃,与单体应用没有差别,定位问题的难度却更大,接口升级不再是单个服务的问题,依赖的一连串服务也需要做出调整,举两个例子,有一次MySQL的prepare语句超出上限,导致一些服务异常,在排查所有使用了prepare语句的服务后才发现问题,另一次支付接口异常,由于涉及到一连串的事务操作,同样需要逐一排查所有相关服务,修复问题需要较多的工作量。

云服务提供商

在文章开头就提到,机器数量没有达到一定程度的情况下,最好不要使用k8s,我们都知道Master节点相当于k8s集群的心脏,最好的方式就是独立出来做高可用,但受限于机器数量,我们只有一台Master节点,那次事故就是Master节点被重启并变更内网IP。

源自服务提供商引发的故障,就像拔掉台式机电源一样恐怖,即便服务提供商保证提供99.9999%的可靠性,剩下的那0.0001%都存在致命性打击。我们的域名解析、VPS、数据库、对象存储都使用了阿里云的服务,图片和静态资源的存储使用了七牛云。

阿里云最让人无奈的一点,就是提示用户升级已购买的服务,比如经典网络升级VPC,升级只是开始,你会发现升级完VPC,还需要升级数据库,因为数据库也区分经典网络与VPC,此外还需要变更安全组规则。这么多可能引起所有服务挂掉的操作,都是阿里云为了提高ECS性能、安全性及稳定性,但它并没有详细说明具体的提升额度。

七牛云让人无奈的地方则有很多,简陋缓慢的后台,同样缓慢的事故处理,以及不断缩水的SSL服务,目前遇到过两次事故,一次是http链接遭到拦截,出现不和谐内容导致公众号被封,另一次是七牛云全面瘫痪,官方没有任何响应,到很久之后才发布一个事故说明。

对于部署k8s,最佳的方式应该是自建机房,分配固定的IP,其次是通过增加Master和Node的数量做高可用服务,预防物理故障引起的瘫痪,另外很重要的一点,将数据服务从集群中完全分离,很遗憾之前并没有做到,依旧用Docker来部署redis与MongoDB的节点,以至于在升级服务期间,CPU和内存压力达到峰值时,Docker崩溃重启,数据服务的节点也一并瘫痪,万幸的是崩溃的只是备份节点。

写在最后

在最后已经没有内容可写,因为在最初动笔的时候,已经明白选择这套架构并不是合适的,对于不合适的架构,有适应的方式,也有无数的弥补方式,但也改变不了它的本质,除非来一次大规模重构。首先将数据服务如MongoDB、Redis等彻底分离出集群,其次将MQTT、RabbitMQ、ZooKeeper等也分离出集群,而后修改相关调用代码,测试上线,接着升级k8s,搭建高可用的集群。即使用脚趾头想,都会认识到这些操作的风险和难度有多大,所以目前的还是保持现状,增加工作节点来极少集群内的节点压力。也许在最早,就应该参与整个集群搭建,摸清整个系统,很遗憾的是自己并不懂Java,Go的经验也是从去年年初开始,而现在我都快忘记自己是个iOS软件工程师了。

今天早上醒来时才发现自己发烧了,在OA上请假去看病,结果回来后倒头就睡,一直到下午四五点才醒来,索性把下午的假一起提了。因为低烧做了漫长又奇怪的梦,梦见自己去一家珠宝店面试,但书面考的是算法和车辆检测,而后又手工编了两串珠子,通过了面试,到了上班的那天,进了珠宝店才发现里面是员工宿舍。和自己现在的情况差不多,学习了各门的手艺,完成了各种各样奇怪的任务,最后被划入三教九流,接下来会专心回归编程,毕竟这个是让自己生存的手艺。