Kubernetes Operator 技术下沉,体验上浮

讲在前面

今天谈谈Kubernetes生态中目前非常活跃的一个概念“Operator”。是的,我认为它是一个概念,一个设计模式。它并不是一个开发框架,一种资源或者说一个项目,这个概念由CoreOS提出。Operator的概念是从Kubernetes的CRD(Custom Resource Definition)自定义资源衍生而来。Kubernetes 的API设计是跨时代的,这种面向资源模型的声明式API体系,使得其能够在分布式体系管理各种资源。CRD的提出更是为开发者打开了创新的大门,从最开始的分布式应用部署,到更广阔的应用开发/发布场景,再到各类云服务场景。各类型资源都接入到Kubernetes API中有效协同管理。Operator的概念在这个过程中推波助澜,我们可以从 awesome-operators 这里看到,各种Operator实现种类齐全。

Operator模式与实践

Operator是一个设计模式,那它到底是一种什么样的模式。要分析这个问题我们可以先理解理解在Kubernetes中Deployment这个资源是如何设计和工作的。Deployment作为我们在Kubernetes中部署无状态应用的标准化方式,其实它的完整工作方式也是Operator设计模式的一种官方实践。在通过其他的标准Operator设计实践来进行理解。我们从以下两个方面来说明Operator模式。

资源定义

Deployment是一种资源,它有完整的定义和Kubernetes API原生的支持。资源的定义中大致分为三个部分:

  • Metadata
  • Specification
  • Status

我们先给它名一个名,资源三剑客,事实上不管是Statefulset等官方资源和CRD都是按照这样的三剑客模式定义。Metadata部分定义这个资源最基础的信息,版本、类型、名称、标签等等。这些信息会告诉所有人这个资源是什么,可以通过什么方式查询获取到它;Specification部分,简称Spec,该资源的规范性定义。这部分通俗的讲就是告知所有人这个资源要做的事和做事需要的条件。比如Deployment这部分的定义基本上就是需要创建Pod,至于创建多少,怎么创建,创建需要的信息都在Spec里定义了;Status部分就是体现当前资源的工作状态或者结果了。比如Deployment这里就体现Pod创建好没有,创建了多少,分别运行状态是什么一类的状态信息。

我们再从另外一个维度来理解资源定义,Metadata和Specification部分一般是由资源创建者来提供数据,或者由资源完善控制器来做部分数据完善。Status部分由资源控制器来响应和赋值。这里出现了两类角色,资源创建者,资源控制器。

Operator实践时,我们通过CRD来定义我们需要的资源类型,举个例子,Rainbond-Operator 项目目的是为了在Kubernetes集群中实现Rainbond 所有的组件安装和运维。那么我们定义了一个资源来描述Rainbond 的组件。

type RbdComponent struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   RbdComponentSpec    `json:"spec,omitempty"`
    Status *RbdComponentStatus `json:"status,omitempty"`
}

使用Golang 语言对这个资源进行定义的化它大概是这样的。满足上诉讲的三剑客原则。资源定义完成后使用operator sdk相关代码生成工具即可生成CRD资源定义。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: rbdcomponents.rainbond.io
spec:
  group: rainbond.io
  names:
    ...
  scope: Namespaced
  subresources:
    status: {}
  validation:
    ...
  version: v1alpha1
  versions:
  - name: v1alpha1
    served: true
    storage: true

它大概是这样的,注意这里是局部代码。

控制器与状态维护

控制器负责完成对资源实例的生命周期维护,资源实例的生命周期一般包括:创建、更新、删除。上面讲了资源定义,资源定义在Kubernetes中的概念可以对应为CRD,资源实例那就是对应的CR。CRD的作用域是Kubernetes API,CR的主要作用域就是控制器。每一个CR的控制器实现基本上都是遵循1对多原则,及一个控制器支持管理多个CR。比如etcd-operator-controller 可以支持多个CR,创建出多个etcd集群。每一个CR在由控制器管理的过程类似于流水线一样。由CR的每一次状态变更或定时时钟驱动控制器完成相关的控制动作。基于这种类似的场景operator-sdk当然就给出了通用性开发框架来实现这个过程。

还是举两个例子,Deployment 的控制器在Kube-controller-manage中内置实现,Deployment的每次数据变更或特殊操作(更新)驱动控制器来判断此资源需要的下级资源(包括ReplicaSet )是否符合资源需求。如果需要创建、删除、更新相应的二级资源,由控制器驱动完成,然后更新状态到Deployment的status中。同样的上文讲到的rainbond-operator中的RbdComponent对应的控制器也一样。根据不同的组件定义创建出不同的二级资源,再形成资源的相关状态。

借用一下网络中的一张图来展示一下资源、控制器的工作流程。

Kubernetes Operator 技术下沉,体验上浮

Operator协同

Operator这种模式目前应用中我们各类高级运维场景中,实现各种自动化运维特征。以Mysql数据库运维为例,或许会存在Mysql集群部署Operator,Mysql数据库数据备份Operator,Mysql数据库监控、日志分析Operator等等。我们是否可以想到这样一个问题,在同一个集群中各种各样的Operator同时存在时,会不会产生冲突、重复等等问题。比如一个Operator实现负责扩容,一个Operator实现负责缩容,他们共同作用于一类资源类型,如何协同将成为首要问题。

Operator模式的实现定义是不受约束的。其实在整个体系中,CRD定义、Operator模式实现,helm打包工具等等都是没有规范可循的,没有规范的资源和功能定义越来越多的时候我们想要让其能够协同工作将越来越困难。

我们想要的状态肯定是可以像搭积木一样选择各类Operator协同工作,因此我们需要上升一个维度,去探索Operator能否一定层面的标准规范化。

Operator标准化、规范化

标准化三个字在Kubernetes体系中针对物理资源管理层面来说效果显著。针对网络接入提出并实现了CNI规范,针对存储系统接入提出CSI规范,针对运行时接入提出CRI规范等等。这些规范提出都是为了解决异构的资源提供方以一种统一的、标准的方式接入Kubernetes体系的问题。

回到Operator上来,在Operator的实现上实现方式、使用方式越来越多。那么我们是否可以有一种较为规范的方式对Operator的实现进行准入。我们举一个例子,helm工具作为目前kubernetes app最常用的部署管理工具,但我认为其有一个最大的问题点在于不能体现app的实际状态。我们使用helm list 类的命令查询app列表时只能获取到它的部署状态,无法获取其真实状态,这就是由于资源状态定义没有规范导致(当然,不是说这种设计有问题,有缺陷,相反我们上文说了这种设计是大家各种各样创建的基础)。当Operator越来越多时我们需要一种管理工具可以有效管理和协同使用各种Operator实现。

我认为Operator的规范化将体现在下述几个方面:

  1. 资源状态体现规范化。
  2. 功能、能力边界规范化。
  3. 协同方式规范化。

愿景:Operator技术下沉,体验上浮

所有的技术都是为业务服务的,我们都有一个追求目标,把复杂的技术实现往下沉,让用户可以最简单的方式体验到Operator模式的能力。我们希望可以逐步打造一种工具或是形成一种规范,让广大的开发者能够发挥创新能力创造各种Operator,让后将其共享出来。对于大多数的用户可以便捷的选择需要的功能,像搭积木一样注入到自己的集群环境,应用于业务应用运维中。或许体验是这样的:
从一种平台中,我们可以一目了然的知道当前集群中有哪些应用运维能力,比如可以部署etcd集群,可以进行mysql数据备份,可以创建阿里云RDS,可以进行大数据计算等待。有了这些能力我们在部署和运维应用的同时可以方便的选择需要的运维功能,而不需要去关注它是如何实现。甚至这样的应用发布到其他环境去部署时依然可以找到对应的运维功能实现。

相关项目:

Rainbond 是以企业云原生应用开发、架构、运维、共享、交付为核心的Kubernetes多云赋能平台, 向下结合Kubernetes云原生资源管理模式,对接管理各类基础设施,通过多维度的软件定义屏蔽了底层资源的差异,甚至包括CPU架构差异和操作系统差异,从而对上层提供以应用为中心的基础设施; 向上定义了标准应用模型(RAM,OAM),内置ServiceMesh微服务架构框架, 提供用户基于源码/已有镜像构建服务组件的能力,编排服务组件的能力,发布共享完整应用模型的能力,交付运维业务应用的能力。

上一篇:使用git遇到的问题汇总


下一篇:开源社区Discourse在Rainbond上的云原生部署