关于分布式:有道-Kubernetes-容器API监控系统设计和实践

40次阅读

共计 5164 个字符,预计需要花费 13 分钟才能阅读完成。

本期文章,咱们将给大家分享有道容器服务 API 监控计划,这个计划同时具备轻量级和灵活性的特点,很好地体现了 k8s 集群化治理的劣势,解决了动态配置的监控不满足容器服务监控的需要。并做了易用性和误报消减、可视化面板等一系列优化,目前曾经超过 80% 的容器服务曾经接入了该监控零碎。

起源 / 有道技术团队微信公众号
作者 / 郭超容 王伟静
编辑 / hjy

1. 背景

Kubernetes 曾经成为事实上的编排平台的领导者、下一代分布式架构的代表,其在自动化部署、监控、扩展性、以及治理容器化的利用中曾经体现出独特的劣势。

在 k8s 容器相干的监控上,咱们次要做了几块工作,别离是基于 prometheus 的 node、pod、k8s 资源对象监控,容器服务 API 监控以及基于 grafana 的业务流量等指标监控。

在物理机时代,咱们做了分级的接口性能监控——域名级别接口监控和机器级别监控,以便在某个机器呈现问题时,咱们就能疾速发现问题。

上图中,右边是物理机时代对应的性能监控,包含域名级别接口监控和 3 台物理机器监控。左边是对应的 k8s 环境,一个 service 的流量会由 k8s 负载平衡到 pod1,pod2,pod3 中,咱们别离须要增加的是 service 和各个 pod 的监控。

因为 K8s 中的所有资源都是动静的,随着服务版本升级,生成的都是全新的 pod,并且 pod 的 ip 和原来是不一样的。

综上所述,传统的物理机 API 不能满足容器服务的监控需要,并且物理机性能监控须要手动运维治理,为此咱们冀望设计一套适配容器的接口性能监控零碎,并且可能高度自动化治理监控信息,实现 pod API 主动监控。

2. 技术选型

为了满足以上需要,咱们初期思考了以下几个计划。

1. 手动保护各个 service 和 pod 监控到目前物理机应用的 podmonitor 开源监控零碎。

2. 重新制定一个蕴含 k8s 目录树结构的零碎,在这个零碎外面看到的所有信息都是最新的,在这个零碎外面,能够做咱们的目录树中指定服务的公布、性能监控、测试演练等。

3. 沿用 podmonitor 框架,反对动静获取 k8s 集群中最新的服务和 pod 信息,并更新到监控零碎中。

+ 计划剖析 +

针对计划一,思考咱们服务上线的频率比拟高,并且 k8s 设计思维便是可随时主动用新生成的 pod(环境)顶替原来不好用的 pod,手动保护 pod 监控效率太低,该计划不可行。

第二个计划应该是比拟零碎的解决办法,但须要的工作量会比拟大,这种思路根本全本人开发,不能很好的利用已有的性能监控零碎,迁徙老本大。

于是咱们抉择了计划三,既能兼容咱们物理机的接口性能监控计划,又能动静生成和保护 pod 监控。

3. 整体设计思路

k8s 监控包含以下几个局部:

其中 API 性能监控,是咱们保障业务性能正确性的重要监控伎俩。

通常业务监控零碎都会蕴含监控配置、数据存储、信息展现,告警这几个模块,咱们的 API 性能监控零碎也不例外。

咱们沿用 apimonitor 框架性能,并联合了容器服务性能监控特点,和已有的告警体系,造成了咱们容器 API 性能监控系统结构:

首先介绍下目前咱们物理机应用的 apimonitor 监控:一个开源的框架
https://gitee.com/ecar_team/a…

能够模仿探测 http 接口、http 页面,通过申请耗时和响应后果来判断零碎接口的可用性和正确性。反对单个 API 和多个 API 调用链的探测。

如下图所示,第一行监控外面监控的是图片翻译服务域名的地址,后边的是各台物理机的 ip:端口。

点开每条监控

咱们沿用 apimonitor 框架的大部分性能,其中次要的适配和优化包含:

1. 监控配置和存储局部:一是制订容器服务 service 级别监控命名规定:集群. 我的项目. 命名空间. 服务;(和 k8s 集群目录树保持一致,不便依据 service 生成 pod 监控),二是依据 service 监控和 k8s 集群信息动静生成 pod 级别监控,

2. 监控执行调度器局部不必改变

3. 信息展现局部,减少了趋势图和谬误汇总图表

4. 告警局部,和其它告警应用对立告警组。

4. 具体实际操作

4.1 增加 service 级别 API 监控告警

须要为待监控服务,配置一个固定的容 service 级别监控。

service 级别监控命名规定:集群. 我的项目. 命名空间. 服务

以词典查词服务为例,咱们配置一条 service 级别的多 API 监控(也能够是单 API 监控)

· 单 API:一个服务只须要加一条 case 用

· 多 API:如果一个服务须要加多条性能 case

其中“所属零碎”是服务所属的告警组,反对电话、短信、popo 群、邮件等告警形式(和其它监控告警通用)

工作名称:取名规定,rancher 中k8s 集群名字. 我的项目名字. 命名空间名字.service 名字(一共四段)

告警音讯的字段含意:

docker-dict: 告警组,订阅后会收到告警音讯

k8s-prod-th:集群

dict: 我的项目

dict: 命名空间

data-server:workload 名字

data-server-5b7d996f94-sfjwn:pod 名字

{}:接口返回内容, 即:response.content

http://dockermonitor.xxx.youdao.com/monitorLog?guid=61bbe71eadf849558344ad57d843409c&name=k8s-prod-th.dict.dict.data-server.data-server-5b7d996f94-sfjwn : 告警具体链接

4.2 主动生成 pod API 监控

主动生成上面三行监控工作:(第一行监控是按下面办法配置的容器 service ip 监控,后边三行是主动生成 pod 监控工作)

监控 service 级别是单 API,则主动生成的是单 API,service 级别是多 API,则主动生成的是多 API 监控。

主动生成的 pod 级别监控,除了最初两行标红处(ip: port)和 service 级别不一样,其余都一样。

实现 pod 主动生成的办法

1. 给 podmonitor(改框架是 java 语言编写的),减少一个 java 模块,用来同步 k8s 信息到 podmonitor 中。思考到批改 podmonitor 中数据这个行为,自身是能够独立于框架的,能够不批改框架任何一行代码就能实现数据动静更新。

2. 比照 podmonitor 数据库和 k8s 集群中的信息,不统一的数据,通过增删改查 db,减少 pod 的监控。因为数据之间存在关联性,有些工作增加完没有例行运行,故采纳了办法三。

3. 比照 podmonitor 数据库和 k8s 集群中的信息,不统一的数据,通过调用 podmonitor 外部接口增加 / 删除一项监控,而后调接口 enable /disable job 等。依照可操作性难易,咱们抉择了办法三

针对于 k8s 集群中查到的一条 pod 信息:总共有三种状况:

1. 对于表中存在要插入 pod 的监控信息记录,并且 enable 状态为 1。则认为该 pod 的监控不须要扭转

2. 对于表中存在要插入 pod 的监控信息记录(删除操作并不会删除源数据信息),并且 enable 状态为 0。则认为该 pod 的监控已被删除或者被进行。调用删除操作,清空 QRTZ(例行工作插件)表中的响应内容,调用 delete db 操作清出监控信息相干表中的内容(使得监控记录不至于始终在增长)

3. 对于表中不存在 pod 相干信息记录,则须要新减少的一个 pod。调用 post 创立监控工作接口(依据 service 监控配置),并调用 get 申请设置接口为监控 enabled 状态。

另外对于曾经在物理机 podmonitor 中增加了监控的服务,提供了一个小脚本,用于导出物理机 podmonitor 域名级别监控到 docker monitor 监控中。

5. 难点和重点问题解决

5.1 误报消减

5.1.1 上线告警克制

因为服务重启期间,会有 removing 状态和未 ready 状态的 pod,在 dockermonitor 零碎中存在记录,会引起误报。
咱们的解决办法是提供一个通用脚本,依据 k8s 服务的存活查看工夫,计算容器服务的公布更新工夫,确定再主动开启服务监控的机会。实现在服务重启时间段,进行该服务的接口性能告警;存活查看工夫过了之后,主动开启监控。
如下如所示,即 Health Check 中的 Liveness Check 查看工夫。

在咱们上线公布平台上连接了该告警克制性能。

5.1.2 弹性扩缩容告警克制

原来咱们通过查问 rancher 的 API 接口失去集群中全量信息,在咱们服务越来越多之后,查问一次全量信息须要的工夫越来越长,根本须要 5min 左右。在这个过程中,存在 docker-monitor 和 k8s 集群中的信息不统一的状况。一开始试图通过依照业务分组,并行调用 rancher 接口失去业务 k8s 集群信息。工夫从 5min 缩短到 1min 多钟。误报有肯定的缩小,但从高峰期到低谷期时间段,依然会有若干 pod 在 k8s 集群中缩掉了,但 docker-monitor 中仍有相应的告警。

在调研了一些计划之后,咱们通过 k8s 增量事件(如 pod 减少、删除)的机制,拿到集群中最新的信息,pod 的任何变更,3s 钟之内就能拿到。

通过 es 的查问接口,应用 filebeat-system 索引的日志,把 pod 带有关键字 Releasing address using workloadID(更及时),或 kube-system 索引的日志: Deleted pod: xx delete。

通过这个计划,曾经根本没有误报。

5.2 策略优化

为了适配一些 API 容许肯定的容错率,咱们在 apimonitor 框架中减少了重试策略(单 API 和多 API 形式均减少该性能)

为了适配各类不同业务,容许设置自定义超时工夫

5.3 易用性

减少复制等性能,关上一个已有的告警配置,批改后点击复制,则可创立一个新的告警项
应用场景: 在多套环境(预发、灰度和全量)监控,以及从一个类似 API 接口微调失去新 API 监控

5.4 业务适配

精品课对服务的容器化部署中应用了接口映射机制,应用自定义的监听端口来映射源端口,将 service 的监听端口作为服务的入口 port 供内部拜访,如下图所示。当 service 的监听端口收到申请时,会将申请报文散发到 pod 的源端口,因而对 pod 级别的监控,须要找到 pod 的源端口。

咱们剖析了 rancher 提供的服务 API 文件后发现,在端口的配置信息中,port.containerPort 为服务的监听端口,port.sourcePort 为 pod 的监听端口,port.name 蕴含 port.containerPo
-rt 和 port.sourcePort 的信息,由此找到了 pod 的源端口与 service 监听端口的要害分割,从而实现了对精品课服务接入本平台的反对。

6. 上线成果

1. 容器服务 API 监控对立,造成肯定的标准,帮忙疾速发现和定位问题。
通过该容器 API 监控零碎,拦挡的典型线上问题有:

· xx 上线误操作
· 依赖服务 xxxlib 版本库问题
· dns server 解析问题
· xxx 服务 OOM 问题
· xxx 服务堆内存调配有余问题
· xx 线上压测问题
· 多个业务服务日志写满磁盘问题
· 各类性能不可用问题
·

2. 同时减少了 API 延时趋势图标不便评估服务性能:

谬误统计表不便排查问题:

联合咱们 k8s 资源对象监控,和 grafana 的业务流量等指标监控,线上故障率显著缩小,几个业务的容器服务 0 故障。

7. 总结与瞻望

7.1 总结

本期文章中咱们介绍了基于动态 API 监控和 K8s 集群化治理计划,设计了实时的主动容器 API 监控零碎。

通过上述计划,咱们可能在业务迁徙容器后,很快地从物理机监控迁徙到容器监控。对立的监控零碎,使得咱们线上服务问题裸露更及时、故障率也显著缩小

7.2 瞻望

1. 主动同步 k8s 服务健康检查到 docker-monitor 零碎,保障每一个服务都有监控。

2. 集成到容器监控大盘中,能够利用大盘中 k8s 资源目录树,更快查找指定服务,以及关联服务的 grafana 指标等监控。

3. 主动复原服务,比方在上线指定工夫内,产生 API 监控告警,则主动回滚到上一版本,咱们心愿监控不仅能发现问题,还能解决问题。

监只是伎俩,控才是指标。

8. 结语

Docker 技术将部署过程代码化和继续集成,能放弃跨环境的一致性,在利用开发运维的世界中具备极大的吸引力。

而 k8s 做了 docker 的集群化治理技术,它从诞生时就自带的平台属性,以及良好的架构设计,使得基于 K8s 容器能够构建起一整套能够解决上述问题的“云原生”技术体系,也升高了咱们做继续集成测试、公布、监控、故障演练等统一规划和平台的难度。目前有道业务服务根本都上线到容器,后续咱们将陆续迁徙根底服务,实现整体的容器化。

咱们也会一直踊跃拥抱开源,借鉴业界胜利案例,寻找适宜咱们以后业务倒退须要的现实选型。

-END-

正文完
 0