标签:容器云
k8s 是当前主流的容器编排服务,它主要解决「集群环境」下「容器化应用」的「管理问题」,主要包括如下几方面:
?
? 容器集群管理
- 编排?
- 调度?
- 访问?
? 基础设施管理
- 计算资源?
- 网络资源?
- 存储资源?
?
k8s 的强大依赖于它良好的设计理念和抽象,吸引了越来越多的开发者投入到 k8s 社区,把 k8s 作为基础设施运行服务的公司也逐步增多。
?
在设计理念方面,k8s 只有 APIServer 与 etcd (存储) 通信,其他组件在内存中维护状态,通过 APIServer 持久化数据。管理组件动作的触发是 level-based 而非 edge-based,并根据资源「当前状态」和「期望状态」进行相应动作。k8s 采用分层设计,基于各类抽象接口、由不同的插件满足不同的需求。
?
在抽象方面,不同的 workload 服务于不同的应用,如针对无状态应用的 Deployment、针对有状态应用的 StatefulSet 等。在访问管理方面,Service 解耦了集群内部服务访问方和提供者,Ingress 提供了集群外部到集群内部的访问管理。
?
k8s 虽然有良好的设计理念和抽象,但陡峭的学习曲线和不完善的开发资料极大增加了应用开发的难度。
?
本次分享将基于笔者的开发实践,以 MySQL on k8s 为例,描述如何基于 k8s 开发高可靠应用,尽可能抽象出最佳实践,降低基于 k8s 开发高可靠应用的成本。
?
?
应用的设计和开发不能脱离业务需求,对 MySQL 应用的需求如下:
1.数据高可靠
数据的高可靠一般依赖于这几方面:
全局控制管理主要负责「创建/删除集群」「管理所有 MySQL 集群状态」等,基于 Operator 的理念来实现。每个 MySQL 集群有一个控制器,负责该集群的「任务调度」「健康检测」「故障自动处理」等。
?
这种拆解将每个集群的管理工作下放到每个集群中,降低了集群间控制链路的相互干扰,同时又减轻了全局控制器的压力。
如下图:
?
??这里简单介绍下 Operator 的理念和实现。
?
Operator 是 CoreOS 公司提出的一个概念,用来创建、配置、管理复杂应用,由两部分构成:
?
Resource
- 自定义资源?
- 为用户提供一种简单的方式描述对服务的期望?
?Controller- 创建 Resource?
- 监听 Resource 的变更,用来实现用户对服务的期望?
?
工作流程如下图所示:?
?
?
??即:
Green
? 可以对外服务?
?运行节点数量符合预期?
Yellow
?可以对外服务?
?运行节点数量不符合预期?
Red
?不能对外服务?
?
同时针对每个 mysqld 节点,定义了如下状态:
?
Green
? 节点在运行?
? 节点在 MySQL 集群中?
Yellow?
? 节点在运行?
? 节点不在 MySQL 集群中?
Red-clean?
? 节点优雅退出?
Red-unclean?
? 节点非优雅退出?
Unknown?
? 节点状态不可知?
?
Controller 收集到所有 MySQL 节点状态后,会根据这些节点的状态推算 MySQL 集群的状态。当检测到 MySQL 集群状态不是 Green 时,会触发「故障处理」逻辑,该逻辑会根据已知的故障处理方案进行处理。若该故障类型未知,人工介入处理。整个流程如下图:
?
?
??由于每种应用的故障场景和处理方案不同,这里不再叙述具体的处理方法。
?
3.易使用
?
我们基于 Operator 的理念实现了高可靠的 MySQL 服务,为用户定义了两类资源,即 QiniuMySQL 和 QiniuMySQLData。前者描述用户对 MySQL 集群的配置,后者描述手动备份/恢复数据的任务,这里以 QiniuMySQL 为例。
?
用户可通过如下简单的 yaml 文件触发创建 MySQL 集群的操作:
??
?
?
在集群创建好后,用户可通过该 CR object 的 status 字段获取集群状态:
??
?
这里再引入一个概念:Helm。?
?
Helm 是为 k8s 提供的包管理工具,通过将应用打包为 Chart,标准化了 k8s 应用的交付、部署和使用流程。
?
Chart 本质上是 k8s yaml 文件和参数文件的集合,这样可以通过一个 Chart 文件进行应用的交付。Helm 通过操作 Chart,可一键部署、升级应用。
?
由于篇幅原因及 Helm 操作的通用性,这里不再描述具体的使用过程。
?
4.易运维
?
除了上述实现的「健康检测」「故障自动处理」以及通过 Helm 管理应用的交付、部署,在运维过程中还有如下问题需要考虑:
? 监控/告警?
? 日志管理?
?
我们通过 prometheus + grafana 做监控/告警服务,服务将 metric 数据以 HTTP API 暴露给 prometheus,由 prometheus server 定时拉取。开发人员在 grafana 上将 prometheus 中的监控数据可视化,根据对监控图表和应用的把握,在监控图中设置告警线,由 grafana 实现告警。
?
这种先可视化监控后告警的方式,极大程度上增强了我们对应用运行特征的把握,明确需要关注的指标和告警线,降低无效告警的产生量。
?
在开发中,我们通过 gRPC 实现服务间的通信。在 gRPC 生态系统中,有个名为 go-grpc-prometheus 的开源项目,通过在服务中插入几行简单的代码,就可以实现对 gRPC server 所有 rpc 请求的监控打点。
?
对于容器化服务,日志管理包括「日志收集」和「日志滚动」两方面维度。
?
我们将服务日志打到 syslog 中,再通过某种手段将 syslog 日志转入到容器的 stdout/stderr 中,方便外部采用常规的方式进行日志收集。同时,在 syslog 中配置了 logrotate 功能,自动进行日志的滚动操作,避免日志占满容器磁盘空间引发服务异常。
?
为了提升开发效率,我们使用?https://github.com/phusion/baseimage-docker?作为基础镜像,其中内置了 syslog 和 lograte 服务,应用只关心把日志打入 syslog 即可,不用关心日志的收集和日志滚动问题。
?
?
通过上述描述,完整的 MySQL 应用架构如下:
?
?
??在开发基于 k8s 的高可靠 MySQL 应用过程中,随着对 k8s 和 MySQL 理解的深入,我们不断进行抽象,逐步将如下通用的逻辑和最佳实践以模块的方式实现:
?
牛人说专栏致力于技术人思想的发现,其中包括技术实践、技术干货、技术见解、成长心得,还有一切值得被发现的技术内容。我们希望集合最优秀的技术人,挖掘独到、犀利、具有时代感的声音。
?
?
标签:容器云
原文地址:http://blog.51cto.com/7741292/2097414