基于 K8s 的应用探索实践,新浪团队有话说

百家 作者:QingCloud 2020-01-17 13:46:15

<iframe class="video_iframe rich_pages" data-vidtype="1" data-cover="http%3A%2F%2Fshp.qpic.cn%2Fqqvideo_ori%2F0%2Fr3047dl1jj7_496_280%2F0" allowfullscreen="" frameborder="0" data-ratio="1.7777777777777777" data-w="864" data-src="https://v.qq.com/iframe/preview.html?width=500&height=375&auto=0&vid=r3047dl1jj7"></iframe>


我们在做 K8s 的过程中遇到很多问题,今天希望能够将我们实践过程中的经验,踩过哪些坑分享给大家。

                  

今天的内容分为五部分:

 

第一,我们目前 K8s 集群的结构,机房分布和网络。

 

第二,业务上线到 K8s 的步骤。希望可以给大家做一些参考。

 

第三,K8s 业务中的监控和报警。包括上线容器之后以及之前纯物理服务器上做的一些事情。

 

第四,K8s 中的业务日志和日志分析。

 

第五,实践中我们遇到的问题,避免大家踩坑。

                        

这个时间轴是我们从研究容器技术开始,一直到大规模应用 K8s 的时间线:

 

一是学习阶段。我们从 Cgroup、Namespace、Docker、Swarm、Mesos 开始研究,后来我们发现 Swarm mode 和 mesos 跟现在的业务不太吻合。

 

2017 年时 Kubernetes 已经成为容器编排领域的事实标准,于是我们开始研究 Kubernetes 。

 

2018 年,我们开始上线测试集群做 Kubernetes 相关的研究,开始部署业务、测试。

 

2019 年我们开始大规模应用,现在有 4 个集群,每个集群都是独立部署,互相之间没有干扰。

 

为什么要这么做?

 

因为大家知道分布式系统有网络分区的问题,如果你在所谓的这种可用区里部署跨机房集群,机房专线宕掉了,其中有一个可用区某一个机房的流量可能会出问题,你能承载的容量可能扛不住,运维人员就开始要开始切。此时另外的可用区可能承载不了这样的流量,那怎么办呢?我们就让它在每一个机房部署相同的 Kubernetes 集群,同时让容量单位变小,切的时候就会比较容易,影响面也比较小。

 

在此过程中,我们支撑 Kubernetes 应用时要对现有的运维系统做一些改造。中间提到 AOS 系统、kingfisher 系统是我们自研的,算是支撑 K8s 的工具。中间的 AOS 系统是我们以前的系统,它是部署在物理环境下的。在此过程中,我们要让 AOS 支撑 K8s 这种业务的上线,在 AOS 上做了改造。后面的 Kingfisher 系统是纯粹管理 K8s 的工具,支持多集群管理、KubeCTL Web Console以及相关的功能。

                        

这是我们的一些思考。K8s 帮我们解决什么问题?

 

首先,提高服务器的利用率。

 

以前 12-16G 的机器只部署一个服务,你发现你的 CPU Load 是 0.01,这个机器上面还不能部署别的服务。此时就会很苦恼,因为利用率跑不上去。

 

其次,缩短业务发布的时间。

 

在物理服务器上要部署一个服务,你要搞机器、各种申请,没有一两天服务上不了线。

 

第三,解决标准化不足。

 

各种各样的业务要上线,环境不一样,最起码要通过配管去管理它。如果通过容器,我们通过Jenkins把所有东西屏蔽掉,从镜像这一层把所有东西屏蔽掉,因为容器是标准的。

 

第四,容量的弹性伸缩。

 

我们是新闻类的企业,会有很多明星的事件发生,这些事件发生时会带来特别大的突发流量,此时扩容是很麻烦的。上容器之后,就会容易很多。

 

虽然解决了很多问题。但是 K8s 很复杂,肯定会给你带来一些问题,比如 K8s 本身的学习成本比较高,K8s 更复杂,管理、运维的成本更高。

 

业务方面,业务方对容器的不认可、不配合,你要给业务方讲明白上容器后有什么好处,优势是什么等等。我们以前在内部开发很多运维工作系统,这些系统也要跟 K8s 做结合做适配。


1

K8s 集群部署结构

      


上图是我们现在的部署结构。最右边是我们 AOS 系统和 kingfisher 系统,管控我们现在的 4 个集群。当然我们现在还在建设其他的集群,每一个集群是一个机房,我们有北方移动机房、北方电信机房、北方联通机房和南方电信机房。现在我们覆盖这样的网络结构,未来我们会建更多点,一个机房里将有两个 K8s 集群或者更多。

                        

这张图是我们 K8s 部署的模块和辅助 K8s 工作的工具。左边第二排框下面有一个 LVS,这是新浪内部的 LVS,包括 80 和 443 的流量都是从它调度到 K8s 集群。

 

K8s 集群的流量入口是什么?就是 Ingress Nginx Controller。选 Ingress Nginx Controller 的原因是它能够自动帮我们把 K8s 里的服务发布出去。实际上七层的负载均衡不需要自己管了。

 

下面是 K8s 的集群,目前我们每一个集群会有三个 Master,这三个 Master 分别对应一个 ETCD 集群。

 

往下部署了什么模块?Core Dns是一定要有的,Calico BGP网络,这个是需要和公司网络组一起协商去做的。集群内的Prometheus、Metric Server、Custom Metric Server、Fluentd,还有其他我们开发的组件都在这里面。

 

往下是 Ceph 集群,还有 Registry。所有机房用一个Registry,现在我们没有做分布式的 Registry。Ceph Cluster 每个机房一个,每个的 K8s 调度自己的 ceph cluster 集群。也是为了当你发现存储问题时影响不会太大。

 

监控和日志,我们有一个集群之外的 Prometheus 存储。我们会把所有K8s 集群里的 Prometheus 数据拉到外边做统一的监控报警、展示。

 

下面的 Spark、ELK Stack 和 Kafka,这是我们做日志收集相关的。以前在物理服务器上都有的,我拿过来复用一下。

 

最左边的 Kibana 是用来做展示的,我们可能要把监控数据展示给开发和监控组。下面 Alert Manager 和 webhook 是我们自研对接 Prometheus 的报警插件,新浪有自己的报警系统,我们要通过新浪的报警方式来报,通过报警接口直接调用。

 

用到的工具是 KubeCTL、AOS、Kingfisher、K8s DashBoard、Kibana/Debug。其中AOS、Kingfisher 是我们现在主要用的。


2

业务上线到 K8s 集群的步骤

                   

我们业务上线到 K8s 的步骤是怎样的?


大概为三块:一是构建镜像;二是部署业务,三是配置上线系统,也就是我们刚刚说的 AOS 系统,这里需要我们运维人员做一些配置才能让业务上线。


上线这一步骤主要配给开发用,开发通过 AOS 系统,自动把业务上线。AOS 系统这里面有很多审核的流程,包括灰度测试,分布上线,领导审批,回滚等等功能。 

                        


构建镜像


我们通过 Jenkins 做构建镜像,Jenkins 里有 SVN 插件,可以管理配置仓库,运维仓库和开发仓库要提供两种不同的东西,我们运维提供的是运行环境,开发提供的是代码,我们俩提供的东西是不一样的。


运维提供的东西和开发提供的东西,通过 Jenkins scm 插件结合在一起打成最终的镜像。


打成最终的镜像后,通过 Jenkins Docker 的插件执行 Build、Tag、Push、Docker、Delete 进行操作。确定镜像没有问题后,我们 AOS 拿到被 Jenkins 打成的镜像,开始调用 kingfisher 系统去部署到 k8s 集群上。


中间为什么要通过 kingfisher 系统调用 K8s?


我们的 kingsisher 系统可以管理多集群,调用 kingsisher 系统可以控制我的业务调度到哪些集群。

                        


部署业务


我要管理很多 Yaml 文件,Depolyment、Service、Ingress、Configmap 等,还有一些存储相关的东西。我把这些东西全部存到 Git 里面。


现在我们的 kingfisher 系统对 Yaml 文件做了很多抽象,未来我们通过 kingfisher 系统来部署,就不需要运维人员自己维护 yaml 文件了。

                        


配置上线系统


配置上线系统会配置什么东西?(上线系统指的是我们的 AOS 系统)一是 Jenkins,配置你的 Jenkins 任务名,你的任务名和你的业务管理在一起,这个任务名里提供的镜像是我们要发布的镜像。


配置仿真上线,业务上线到 K8s 之前,我们在物理环境上要先发布到测试的机器,上到容器后,我们在每个集群里开一个 Namespace。


在这里部署测试镜像,我们通过泛解析域名解析到 K8s 集群的入口,比如 x.c.cn 是我们的域名,我们会给你的业务分配一个仿真域名,比如叫 a.x.c.cn,让你做业务测试。


开始配置我们正式上线的东西,我们要部署在哪个 Namespace,用哪个镜像,什么版本。另外你担心它一次发布上去后业务影响,你要给它做灰度上线。比如把步长设置成 1,在我们的 AOS 系统点五次才能完成上线,我们也提供一个功能,你点了两次后发现没什么问题,可以点击全部上线跳过分步的过程。 


3

K8s 中的业务监控和报警

                        

我们的 K8s 集群使用的是物理服务器,跑在裸机上,物理服务器上有 zabbix agent,把物理服务器的数据传输到 Zabbix Server。

 

K8s 集群内的数据通过 Prometheus discovery configuration 机制自动获取进群内的监控数据。

 

Prometheus Storage,是我们在集群外部的 Prometheus,通过它把集群内的 Prometheus 数据要拿出来。我们自己开发了一个 Prometheus Exporter 插件用来获取业务监控的指标。


4

K8s 中的业务日志和日志分析

                        

日志的传输用容器内的 rsyslog 收集到 kafka cluster,然后通过 ELK Stack,将日志结构化可视化,然后存起来。下面有一个 Spark,实时分析所有的用户日志,保证你的业务在第一时间,两三分钟时间内把相关联的日志做分析,然后以报警的方式发给你,这样可以第一时间告诉你,你的业务发生什么问题,大致因为什么东西引起的。


5

实践中遇到的问题

                   


多了一层负载均衡


我们以前是产品运维为主,以前是不管负载均衡的,负载均衡跟我们一点关系都没有,我们只是用。


接入 K8s 后,通过Ingress Nginx Controller ,我们需要管这个东西,比如你的 http 请求 Header 各个业务方用到的不一样,比如你的 Bodysize 设置成 5K。但它可能有 post 的请求,我要上传 100 兆,完蛋了,它挂了。


这时候怎么办?你一定要支持,你要单独给它这个业务改,允许它传 100 兆。


同时,七层的负载均衡要做变更影响也特别大,你改了其中一个配置后,你所有的业务都要 Reload。你可能要变更一个配置才能支持它的业务,你的变更对所有人都有影响。现实中我们变更时没有发生什么大问题,理论上还是存在的。你变更时,有些特别重大的可能会造成影响。

                        


增加各种依赖资源的监控


你这边的业务上容器了,别人没上。当你业务出问题时,你需要先检查自己的容器是不是出问题了?Dns 解析是不是出问题了?每次都要检查,你检查不过来。怎么办?


我们做了很多依赖资源的探测,包括 Memcached、Redis、API 等所有的东西,业务上线之前我们都要调过来对你的业务进行探测。

 

探测什么东西?比如 PING 是否正常,如果是正常,排除网络没问题。Traceroute,路由没问题。DNS 解析,DNS 也没问题。

 

模拟你所有线上业务的操作,模拟完后发现这些都没问题,这时候再去查其他可能存在的问题。

 

第二个问题是上 K8s 后,你的邮件会变得巨多。这还没上 Istio,Istio 更多,最后你崩溃了,改了一个配置文件后,再改别的,回来发现一个问题该改在哪儿?不知道了。


你想回馈时怎么办?我们把它存在 Git 里做版本的管理,让我们快速回退。K8s 里很多重要的 Yaml 文件,比如 Calico 的网络配置。你跟网络做 BGP 的邻居关系,如果你要进行变更的话,你写错了,完蛋了,K8s 的网络瞬间不通了,这很要命的,需要快速回滚才行。

                        


node 节点的管理


第三个问题是你的物理节点需要管,你的物理服务也需要管。在 K8s 里很多东西都是自动的,物理节点的管理跟不上也是很头疼的。


我们自己通过封装 saltstack 实现了自己的一套配置管理系统。已经在 GitHub 开源,叫 saltshaker,大家可以搜索一下,我们大概在 2015 年开始做的。


右边是 Kingfisher 和 KubeCTL 管理 Node,kingfisher 系统里我们提供 Node 节点相关的管理。

                        


其他细节


还有一些其他的细节,比如 coredns,以前我们是配两个 DNS,其实 core dns 它是随机在里面选一个,如果你的 DNS 配置用了跨机房的或者其中一个比较慢,就会引起 DNS 解析变慢,后来我们知道这个机制后,禁止跨机房 DNS 配置。


Prometheus 过快的数据拉取,导致监控数据延迟或者丢失。我们 K8s 集群里的 Prometheus 只存一两天时间,不会有什么问题。集群之外的 Prometheus 拉取所有集群的数据,它的压力很大。5 秒或者 10 秒拉一次数据,它的压力特别大。后来我们把它数据拉取的频率降低了,为什么可以降低?我的监控、采集频率只有一分钟,15 秒拉取一次数据没什么意义。


基础镜像提前同步到 Node 节点,减少业务镜像拉取的时间。当业务规模变大后,业务镜像共同依赖的基础镜像在节点初始化的时候就把基础的镜像同步了,上线时间就会变少。加速拉镜像的其他方式,我们也正在做。


容器网络的连通性检测、可用性检测,每个集群有 ceph 存储,存储挂了,业务就会挂了,业务就没有了。你一定要检测它,它出问题的时候快速切换服务,想办法恢复。 


扫码或点击阅读原文查看 KubeSphere 项目



本文是「KubeSphere 技术分享及最佳实践」专题的内容,该专题在持续更新中,欢迎大家保持关注?



- FIN -


关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接