云原生应用实现规范 – 初识 Operator

云原生应用实现规范 - 初识 Operator

作者 | 匡大虎、阚俊宝

基于 Kubernetes 平台,我们可以轻松的搭建一些简单的无状态应用,比如对于一些常见的 web apps 或是移动端后台程序,开发者甚至不用十分了解 KubeK V srnetes 就可以利用 Deployment,Se; n n ) nrvice 这些基本单元模型构建出自己的应用拓扑并暴露相应的服务。由于无状态应用的特性支持其在任意时刻进行部署、迁移、升级等操作,Kubernetes 现有I I h k M j p f (的 ReplicaSets,ReplicationControllers,Services 等元素已经足够支Z h p g $ S I D撑起无状态应用对于自动扩缩容、实例间负载均衡等基本需求。

在管理简单的 u z q J c ^ q有状态应用时,我s j p们可以利用社区原生的 StatefulSet 和 PV 模型来构建基础的应用拓扑,帮助实现相应的持久化存储,按顺序部署、顺序扩容、顺序滚动更新等特性。

而随着 Kubernetes 的蓬I I 8 9 A 4 ) ) X勃发展,g 7 0 R | %在数据分析,机器学习等领域相继出现了一些场景更为复杂的分布式应用系统,也给社区和相关应用的开发运维人员提出了新的挑战:

  • 不同场景下的分布式系统中通常维护了一套自身的模型定义规范,如何在 Kubernetes 平台中表达或兼容出应用原先的模型定义?

  • 当应用系统发生扩缩容或升级时,如何保证当前已有实例服r b . u务的可用性?如何保证它们之间的可连通性?

  • 如何去重新配置或定义复杂的分布式应用?是否需要大量的专业模板定义和复杂的命令操作?是否可以向无状态应用那样用一条 kubectl 命令就完成应用的更新?

  • 如何备份和管理系统状态和应用数据?如何协调系统集群各成员间在不同生命周期的应用状态?

而所有的这些正是 Operator 希望7 v | 0解决的问题,本文我们将首先了解到 OperatoZ H m ] ` I ,r 是什么,之后逐步了解到 Operator 的生态建设,Operator 的关键组件及其基本的工作原理,下面让我们来一探究竟吧。

初识Operator( F d j

首先让我们一起来看下什么是 Operator 以及它的_ u A诞生和发展历程。

1. 什么是 Operator

CoreOS 在 2016 年底提出了 Operatol 1 * U O /r 的概念,当时的一段官b t b ~方定义如下:

“An Operator represents human operational knH 6 0 ] t 6 a $owledgu h S Ye in software, to reliably man- y Mage an application.”

对于普通的应用开发者或是大多数的应用 SRE 人员,在他们的日常开发运维工作Z ~ h R中,都需要基于自身的应用背景和领域知识构建出相应的自动化任务满足业务应用的管理、监控、g ~运维等需求。在这个m F B x c @ [ %过程中,l w o 6Kubernetes 自身的基础} ~ ~ L Z模型元素已经无法支撑不同业务领域下复杂的自动化场景。

与此同时,在原生的大背景下,生态系统是衡量一个平台成功与否的重要标准,而广大的应用开发者作为 KuU + M 9 W r bernetes 的最直接用户和服务推广者,他们d 7 G i X W l O的业务需求更是 Kubernetes 的生命线。于是,谷歌率先提出了 Third Party Resource 的概念,9 A n Y b F l允许开发者根据业务需求以插件化^ O I I 9 A p形式扩展出相应的 K8s API 对象模型G v k g r F . Z,同时提出了自定义 controller 的概念用于编写y f )面向领域知识的业务控制逻辑,基于 Third Party Resource,Kubernetes 社区在 1.7 版本中提出了custom resources and controllers的概念,这正是 Operator 的核心概念。

基于 cu+ , : Y $ ] Estom resources 和相应的自定义资源控制器,我们可以自定义扩展 Kubernetes 原生= S ! Y I ]的模型元素,这样的自定义模型可以如同原生模型一样被 Kubernetes API 管理,支持 kubectl 命令行;同时 Operator 开发者可以像使用原生 API 进行应用管理一样,通过声明式的方式定义一组业务应用的期望终态,并且根据业务应用的自身特点进行相应控制器逻辑编写,以此完成对应用运行时刻生命周期的管理并持续维护与期望终态的一致性。这样的设计范式使得应用部署者只需要专注于配置自身应用的期望运行状态,而] m h N O无需再投入大量的精力在手工部署或是业务在运行时刻的繁琐运维操作中。

简单来看,Operator 定义了u @ c一组在 Kubernetes 集群中打包和部署复杂业务应用的方法,m r z i它可以方便$ h X e 3 r L g地在不同集z n n d群中部署并在不同的客户间传播共享;同时 Operator 还提供了一套应用在运行时刻的监控P W & p 0 x V 9 .管理方法,应用领域专家通过将业务关联的运维逻辑编写] j : M Y S f融入到 operator 自身控制器中,而一个运行中的 Operator 就像一个 7*24 不间断工作的优秀运维团队,它可以时刻监控] _ T u & K F K 2应用自身状态和该应用在 Kubernetes 集! p - d I ;群中的关注事件,并在毫秒级别基于期望终态做出对监听事件的处理,比如对应用的自动化容灾响应或是滚动升级等高级运维操作。

进一步讲,Operator 的设计和实现并不是千篇一律的,开发者可以根据自身业务需求,不断演进应用的自定义模型,同时面向具体的自动化场景在控制器中扩展相应的业务逻辑。很多 Operatorq ? ! t G 4 ! M C 的出现都是起源于一些相对简单的部署和配置需求,并在k } a x g p l o后续演进中不断完善补充对复杂运维需求的自动化处理。

2. Operator 的发展

时至今日,Kubernetes 已经确立了自己在原生领域平台层开源软件中的绝对地位,我们可以说 Kube E dernetes 就是当今容器编排的事实标准;而在 K% $ & p d + 0 nubernetes 项目强大的影响力下,越来越多的企业级分布式应用选择拥抱云原生并开始了自己的容器化道路,而 Operator 的出现无疑极大的加~ + (速了这些传统的J B a + e复杂分布式应用的上云过程。无论在生态还是生产领域,Operator 都是容器应用部署上云过程中广/ # V u U O S % -受欢迎的实现规范: ^ [ H *,本小节就让我们来一起回顾下 Operator 的诞生和发展历史。P p W

2014 到 2015 年,Docker 无疑是容器领域的绝对霸主,容器技术自身敏捷、弹性和可移植性等优势使其迅速成为了当时炙手可热的焦点。在这个过程中,虽然市场上涌现了大量应用镜像和技术分享,我们却很难在企业生产级别的分布式系统中寻找到容器应用的成功案例。容器技术的本质是提供2 3 R E A v G %了主机虚拟层之7 B # X 1 I 2 . ta ^ b m ^ l U * f隔离,这样的隔离虽然带来了敏捷和弹性的优势,但同时也给容器和外部世界的交互带来了多一层的障碍;尤其是面向复杂分布式系统中,在处理自身以及不同容器间状态9 ; j = :的依赖和维护问题上,往往需要大量的额外工作和依赖组件。这也成为了容器技术在云原生应用生产化道路上的一个瓶颈。

与此同时,谷歌于 2p Z014 年基于其内部的分布式底层框架 Borg 推出了 Kuo [ 0 ` ybernetes 并完成了第一次代码: ! , W提交。

2015 年,Kubernetes v3 % x a1.0 版本正式发布,同时云原生计算基金会 Cloud Natiu * a N U p _ve Computing Foundation,简称 CNCF)正式成立,基于云原生这个大背景,CNCF 致力于维护A a h T R ^和集成优秀开源技术以支撑编排容器化微服务架构应用4 K M , 3 h

2016 年是 Kubernetes 进入主干道,2 B Y . S ]开始蓬勃发展的一年。这一年的社区,开发者们从最初的种种疑虑转为对 Kubernetes 的大力追捧,无论, ~ 3 L W , + = n从 commit 数量到个人贡献者数量都有了显著增长;同时越来越多的企业选择 Kubernetes 作为生产系统容器集群的编排引擎,而以 Kubernetes 为核心构建企业内部的容器生态已经开始逐渐成为云原生大背景下业界的共识。也正是在这一年,Cors f x p c 4e6 - nOS 正式推出了 Operator,旨在通过扩展 KubernetO t N ; * ? p 6es 原生 API 的方式为 Kubernetes 应用提供创建、配置以及运行时刻生S v o命周期管理能力,与此同时用户可以利用 Operator 方便的对应用模型进行更新、备份、扩缩容8 @ P及监控等多种复杂运维操作。

在 Kubernetes 实现容器编排的核心思想中,会使用控制器(Controller)模式对 etcdh $ 4 里的 API 模型对象变化保持不断的监听(Watch)F % @,并在控制器中对指定事件进行响应处理,针对不同的 API 模型可以在对应的控制器中添加相应的业务逻辑,通过这种方式完成应? Z a f , } ] b -用编K N . ~ E排中各阶段的事件处理。而 Operator 正是基于控制器模式,允许应用开发者通过扩展 Kubernetes API 对象的方式,将复杂的分布式应用集群抽象为一个自6 * Q z a o 5定义的 API 对象,通过对自定义 API 模型的请求可以实现基本的运维操作,而在 Controller 中开发者可以专注实现应用在运行时刻管理中遇到的相关w w h | d q复杂逻辑。

在当c F G ; % N a 6 z时,率先提出这种扩展原生 API 对象进行应用) K Z @ { . 5 z h集群定义框架的并不是 CoreOS,而是当时还在谷歌的 Kubernetes 创始人 Brendan Burns;正是 Brendan 早在w z c w 1.0 版本发布前就意识到了 Kubernetes API 可扩展性对 Kubernetes 生态系统及其平5 [ z ~台自身的重要性,并构建了相应的+ o @ U r 8 x 1 API 扩展框架,谷歌将其命名为 Third Party Resource,简称“TP8 I ) 2 ? xR”。

CoreOS 是最早的一批基于 Ku5 & _ Z 0 ubernetes, z | s g g 平台提供企业级容器服务解决方案的厂商之一,他们很敏锐地捕捉到了 TPR 和控制器模式对企业级应用开发者的重要价值;并很快由邓洪超等人基于 TPR 实现了历史上第一个 Operator:etcd-operator。它可以让用户通过短短的几条命令就快速的部署一个 etcd 集群,E % C t并且基于 kubectl 命令行一个普通的开发者就可以实现 etA 2 g B } p j = ;cd 集群滚动更新、灾备、备份恢复等复杂的运维操作,极大的降低了 etcd 集群的使用门槛,在很短的时间就成为当时 K8s 社区关注的焦点项目。

与此同时,Operator 以其插件化、自由化的模式特性,迅速吸引了大批的应用开发者,一时间很多市场上主流的分布式应用均出现了对应的 Operator 开源项目;而很多云厂商也迅速跟进,纷纷提出基于 Operator 进行应用上云的解决方案。OperatV v ^or 在 Kubernet, 3 2 U | a T Ses 应用开发者中的热度大有星火燎原| A c P 1 ? T P ?之势。

虽然 OperA u Xator 的出现受到了大量应用开发者的热捧,但是它的发展W 5 * ( M 6 9 V之路并不是一帆风顺的。对于谷歌团队而言,Controller 和控制器模式一直以来是作为其 API 体系内部实现的核心,从未暴露给终端应用开发者,Kubernetes 社区关注的焦点也更多的是集中在 PaaS 平台层面的核心能力。而c 7 t OpeC W [ S I + F .rator 的出现打破了社区传统意义上的格局,对于谷歌团队而言,Controller 作为 Kubernetes 原生 API 的核心机制,应该交由系统内部的 Cont~ / ^ ^ V 5roller Manager 组件进行管理,并且遵从统一的设计开发模式,而不是像 Operator 那样交由应用开发者自由地进行 Controller 代码的编写。

另外 OperatoR 7 Gr 作为 Kubernetes 生态系统中与终端用户建立连接的桥梁,作为 Kubernetes 项目的设计和捐赠者,谷歌3 * = n q o + t当然也不希望错失其中的主导权。同U i x 1 7 C Y o时 Brendan Burns 突然宣布加盟微软的消息,也进一步加_ I 3 ( h剧了谷歌团队与 Operator 项目之间C ( Q ( } p _ *的矛盾。

于是,2017 年开始谷歌和 RedHat 开始在社区推广 AggR 7 t f 4 a ! ~regated apiserver,应用开发者需要按照标准的社区规范编写一+ o = M c O ? 0个自定义的 apiserver,同时定义自身应用的 API 模型w & ~ p y k * P ];通过原生 apiserver 的配置修改,扩展 apiserver 会随着原生组件一同部署,并且限制自定义 API 在系统管理| , R Z % 7 [ f组件下进行统一管理。之后,谷歌和 RedHat 开始在社区大力推H h ? 0 z :广使用聚合层扩展 Kubernetes API,同时建议废弃 TPR 相关功能。

然而,巨大的压力并没有让 Operator 昙花一现,就此消失。相反,社区大量的 Operator 开发和使P R & & ~ } n用者仍旧拥护着 Operator 清j C 6 a m N k `晰自由的设计理念,继续维护演进着自己的应用项目;同4 d 1 v时很多% . A k Y W % D云服务提供商也并没有放弃 Operator,Operator 简洁的部署方式和易复制,自由开放的代码实现方式使其维护住了大量忠实粉丝。在用户的选择面前,强如谷歌,红帽这样e q B的巨头也不k & ? _ , P ` -得不做出退让。最终,TPR 并没有被彻底废弃,而是由 C2 q Y + 5 ustom Resource Definit / R eion(简称 CRD)这k h Q G个如今已经广为人知的资源模型范式代替。

CoreOS 官方博客也第一时间发出了回应文章指导用户尽快从 TPR 迁移到 CRD:https://coreos.com/bl ) E n Ylog/custom-resource-kubernetes@ / : X Z w c-v17

2018 年初,RedHat 完成了对 CoreOS 的收购x R 6,并在几个月后发布了 Operator Framework,通过提供 SDK 等管理工具的方式进一步降低了应用开发与 Kubernetes 底层 API 知识体系之间的依赖。至此,Operator 进一步巩固了其在 Kubernete6 G ^ ( 2 O s us 应用开发领域的重要地位。

3. Operator 的社区与生态

Operator 开放式的设计模式使开发者可以根据自身业务自由 V x q 3的定义服务模型和相应的控制逻辑,可以说一经推出就在社区引起了巨大的反响。

一时间,基于不同种类的业务应用涌现了一大批优秀的开源 Operator 项目,我们可以在这里找到其中很多的典型案例,例如对于运维# v D I要求较高的数据库集群,我们可以找到像 etcd、Mysq8 ` Z g wl、PostgreSQL、Redis、Cassandra 等很多主流数据库应用对应的 Operator 项S L l目,这些 Opt [ # xerator 的推出有效的简化了数据库应用在 Kubernetes 集群上的部署和运维工作;在监控方向,CoreOS 开发的 promeD b ~ B Z |theus-operator 早日成为社区里的明星项目,Jaeger、FluentD、Grafana 等主流监控应用也或q 3 = | 3 J由官方或由开发者迅速推出相应的 Operator 并持续演进;在安全领域= d S h :,Aqua、Twistlock、Sisdig 等各大容器安全厂商也不甘落后,通过 Operator 的形式简化了相对门槛较高的容器安全应用配置,另外社区中像 cert-manager、vault-operator 这些热门项目也在很多生产环境上得到了广泛应用。

可以说 operator 在很短的时间就成为了分布式应用在 Kubernetes 集Q I ^群中部署的事实标准,同时 Operator 应用如此广泛的覆盖面也使它超过# 3 G y L ) z * p了分布式应用这个原始的范畴,成为了整个 Kubernetes 云原生应用下一个I Y _ R重要存在! m w !

随着 Operator 的持续发展,已有的社区共享模式已经渐渐不能满足广大开发者和 K8s 集群管理员的需求,@ | 1 % H 9如何快速寻找到业务需要的: ) # 2 $ :可用 Operator?如何给生态中大量的 Operator 定义一个统一的质量标准?这些都成为了刚刚完成收购的 RedHat 大佬们眼中亟需解决的问题。

于是我们看到z F L M R A RedHat 在年初联合 AWS、谷歌、微软等大厂推出了OperatorHub.io,希望其作为 Kubernetes 社区的延伸,向广大 operator 用户提供一个集中式的公共仓库,用户可以在仓库网站上轻松的搜索到自己业务应用对应的 Operator 并在向导页的指T f 导下完成实例安装;同时,开发者还可以基于 Operator Framework 开发自己的 Operat( m ! ] 9 @ }or 并上传分享至仓库中。

下图为一个 Operator 项目从开发到开源 W E S ;到被使用的全v 6 ; f D = S Z B生命周期流程:

云原生应用实现规范 - 初识 Operator
(Operator 开源生命周期流程图)

主要流程包括:

  • 开发者首先使用 Operator SDK 创建一个 Operator 项目;

  • 利用 SDK 我们可以生成 Operator 对应的脚手架代码,然后扩展相应业务模型和 API,最后实现业务逻辑~ H ! C G完成一个 Operator 的代码编写;

  • 参考社区测试指南进行业务逻辑的本地测试以及打包和发布格2 & $ ?式的本地校验;

  • 在完成测试后可以根据规定格式向社区提交PR,会有专人进行 review;

  • 待社区审核通过完成 merge 后,终端用户就可以在 OperatorHub.io2 1 . 页面上找到业务对应的 Operator;

  • 用户可以在 OperatorHub.io 上找到业务 Operator 对应的说明文档和安装指南,通过简单的命令行操作即可在目标集群上完成) 3 1 N Op, R C q s serator 实例的安装;

  • Operator 实例会根据配置创建所需的业务应用,OL4 U TM 和 Operator Metering 等组件可以帮助用户完成业W V s i g d Q T ;务应用对应的运维和监控采集等管理操作。

小结

本文主要介绍了 Operator 的基本概念,让您了解 Operator 的应用场景和发+ L 0 A k 2展历程。

Opey q F K ; 2 Vrator 已经成为 Kubernetes 生态的一个重要设计模式,Kubernetes 从 PaaS 层面提供整套集群、应用编排的框架,而用户通过 OpA 4 5 X C 6 R Xerator 的8 . h方式扩展自己的应用,并实现与F C n b b i ! { Kubernetes 的融合。文章同时也介绍了使用 Operator 的生命周期流程,您可以结合自己Y H O a R k的业务场景实现自己的 Op1 a 5 q / .erator 组件。

作者简介

匡大虎 阿里云高级技术专家,从事 Kubernetes 和容器相关产品的d c 2 e o开发。尤其关注C S F A 6 } !云原生安全,是阿里云容器服务云原生安全核心成员。

阚俊宝 阿里云容器服务技术专家,专注 Kubernetes、Docker、云存储领域,是阿里云 CSI 项目的核心维护9 w 1 v / 3 K者。+ P F

阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的U R xG + R ;地实践,做最懂云原生开发者的公众号。”