CRD - 自定义资源

https://segmentfault.com/a/1190000014836253
CustomResourceDefinition(CRD)是 v1.7 + 新增的无需改变代码就可以扩展 Kubernetes API 的机制,用来管理自定义对象。它实际上是 ThirdPartyResources(TPR) 的升级版本,而 TPR 已经在 v1.8 中删除。

一些使用场景:

  • 提供/管理外部数据存储/数据库(例如 CloudSQL/RDS 实例)
  • 对k8s基础资源进行更高层次的抽象(比如定义一个etcd集群)

其实crd在很多k8s周边开源项目中有使用,比如ingress-controller和众多的 operator

https://juejin.im/post/5c108bb8e51d450c5a47c67f#heading-20
Operator=CRD+Controller。
CRD仅仅是资源的定义,而Controller可以去监听CRD的CRUD事件来添加自定义业务逻辑。

https://sq.163yun.com/blog/article/174980128954048512
Snipaste_2019-05-02_21-46-34.png

https://www.jianshu.com/p/cc7eea6dd1fb

2.2、Prometheus Operator 架构:

Prometheus Operator 的目标是尽可能简化在 Kubernetes 中部署和维护 Prometheus 的工作。其架构如下图所示:
11025663-bd31fc6df95e9d0c.png

1)、Operator:
Operator 即 Prometheus Operator,在 Kubernetes 中以 Deployment 运行。其职责是部署和管理 Prometheus Server,根据 ServiceMonitor 动态更新 Prometheus Server 的监控对象,这里的ServiceMonitor资源对象就是指一个需要监控的目标对象在Prometheus中的配置信息。operator会根据Kubernetes标签查询自动生成监控目标配置;不需要学习普罗米修斯特有的配置语言。(operator就是一个将应用的操作性知识以软件的形式表现出来,通过基于K8s的Resources 和 Controllers来创建、配置、管理有状态的pod,使有状态的应用在k8s中得到简化的运用)
尘泥:一个产品或者应用可以以 Operator 形式入驻 K8S,与其相关的运维的领域知识可以落到 Operator 中,不须要 K8S 管理员感知

Operator

https://jimmysong.io/kubernetes-handbook/develop/operator.html
Operator是由CoreOS开发的,用来扩展Kubernetes API,特定的应用程序控制器,它用来创建、配置和管理复杂的有状态应用,如数据库、缓存和监控系统。Operator基于Kubernetes的资源和控制器概念之上构建,但同时又包含了应用程序特定的领域知识。创建Operator的关键是CRD(自定义资源)的设计。

https://www.redhat.com/en/blog/introducing-operator-framework-building-apps-kubernetes
image.png

To help make it easier to build Kubernetes applications, Red Hat and the Kubernetes open source community today share the Operator Framework — an open source toolkit designed to manage Kubernetes native applications, called Operators, in a more effective, automated, and scalable way.

🌟Operators are Kubernetes applications

You may be familiar with Operators from the concept’s introduction in 2016. An Operator is a method of packaging, deploying and managing a Kubernetes application. A Kubernetes application is an application that is both deployed on Kubernetes and managed using the Kubernetes APIs and kubectl tooling. To be able to make the most of Kubernetes, you need a set of cohesive APIs to extend in order to service and manage your applications that run on Kubernetes. You can think of Operators as the runtime that manages this type of application on Kubernetes.

Conceptually, an Operator takes human operational knowledge and encodes it into software that is more easily packaged and shared with consumers. Think of an Operator as an extension of the software vendor’s engineering team that watches over your Kubernetes environment and uses its current state to make decisions in milliseconds. Operators follow a [maturity model] from basic to having specific logic for an application. Advanced Operators are designed to handle upgrades seamlessly, react to failures automatically, and not take shortcuts, like skipping a software backup process to save time.
The pieces that are now being launched as the Operator Framework are the culmination of the years of work and experience of our team in building Operators. We’ve seen that Operators’ capabilities differ in sophistication depending on how much intelligence has been added into the implementation logic of the Operator itself. We’ve also learned that the creation of an Operator typically starts by automating an application’s installation and self-service provisioning capabilities, and then evolves to take on more complex automation.

OperatorHub

https://operatorhub.io
我们都知道在 Kubernetes 上安装应用可以使用 Helm 直接安装各种打包成 Chart 形式的 Kubernetes 应用,但随着 Kubernetes Operator 的流行,Kubernetes 社区又推出了 OperatorHub,你可以在这里分享或安装 Operator:https://www.operatorhub.io
另外,awesome-operators 中罗列了目前已知的 Operator。

Jaeger

image.png

示例:

  1. apiVersion: io.jaegertracing/v1alpha1
  2. kind: Jaeger
  3. metadata:
  4. name: my-jaeger
  5. spec:
  6. strategy: allInOne
  7. allInOne:
  8. image: jaegertracing/all-in-one:latest
  9. options:
  10. log-level: debug
  11. storage:
  12. type: memory
  13. options:
  14. memory:
  15. max-traces: 100000
  16. ingress:
  17. enabled: false
  18. agent:
  19. strategy: DaemonSet
  20. annotations:
  21. scheduler.alpha.kubernetes.io/critical-pod: ""

源码:
https://github.com/jaegertracing/jaeger-operator

🌟Istio

https://github.com/banzaicloud/istio-operator
K8S 系统学习(Step 2 几个关键概念) - 图5

🌟🌟🌟面向 Kubernetes 编程:Kubernetes 是下一代操作系统

https://zhuanlan.zhihu.com/p/57279700
作者:陈俊(心贵),蚂蚁金服 此文章适合没有任何 Kubernetes/容器/Docker 经验的同学 — 在不久的将来,你不懂如何操作 Kubernetes 接口,就等于现在的你不懂最普通的 Linux 命令。此文章阅读耗时大概 15 分钟。

面向 Kubernetes 编程:使用 Operator 交付软件

上面提到的使用“交付大厨”的方式去交付软件看起来很美好。那么,如何实现呢?也就是我们要怎么培养出属于我们自己的“厨师”。

其实我们在 “小试牛刀” 的章节已经介绍了一位 “厨师” 了: 负责 “Deployment” 的厨师。只是,他的工作比较通用化、没有什么业务含义。它只是负责守护用户在 “菜单” 里面描述的 “进程”(Pod) 数量,至于怎么起 “进程” 都是用户传入的。

那么,我们是不是可以根据这个 “厨师” 的模仿出有业务含义的 “厨师”?比如,业界有一位比较出名的一个 “厨师”,是负责 etcd 集群的。如果我需要一个副本数是3的 etcd 集群,只要向 Kubernetes 提交如下的一个 “菜单”:

  1. apiVersion: "etcd.database.coreos.com/v1beta2"
  2. kind: "EtcdCluster"
  3. metadata:
  4. name: "example-etcd-cluster"
  5. spec:
  6. size: 3

“etcd厨师长” 就会根据这个 “菜单” 做出一个副本数是3(Spec.Size=3)的 etcd 集群给你。用户不需要知道 3 副本的 etcd 集群里每个副本参数是什么样的。

“etcd厨师长” 真实的名字叫 etcd-operator。顾名思义,operator 就是“厨师长”,“xxx-operator”就是 “xxx应用-厨师长”。在不久的将来,我觉得我们也会有 “xx-db-operator”,“xx-web-operator”,我们也用这种简洁明了的声明方式,快速得到一个 db 实例, 或者一个 “xx-web” 应用。

回到怎么培养厨师长的话题,首先我们来介绍一下名词:

  1. CRD (CustomResourceDefinitions):定义“满汉全席”这样的全家桶。Deployment 是 Kubernetes 官方的资源定义,Kubernetes 同时向开发者提供了 “自定义资源定义”。开发者可以向 Kubernetes 集群提交有 “满汉全席” 的定义,那么当用户提交一桌 “满汉全席” 时,Kubernetes 就明白用户的请求了,也就是说 Kubernetes 知道用户所说的 “满汉全席” 是什么了。
  2. CR (Custom Resources):一个 CRD 实例,即一桌 “满汉全席”,也就是类似上文一样的 YAML 声明。
  3. Custom Controller: 我们的“厨师长”。当 Controller 发现用户提交了 一桌 “满汉全席”,那么他就开始做菜了。当然它并不是完全亲自做每道菜,正如我上文所说。我们的 “厨师长” 可以依赖另一位 “厨师长”,比如 “db 厨师长” 可以依赖 “Deployment 厨师长”,当用户需要一个 db 实例的时候,“db 厨师长” 只需要负责再向 Kubernetes 提交一个 Deployment 声明即可。注意:“厨师长” 之间的交互也是靠 “CR” 或者 Kubernetes 官方定义的资源(如 Deployment、Pod)。“厨师长” 一般也是通过 Deployment 的方式部署在 Kubernetes 集群内(保证了 “厨师长” 自身的稳定性),除非像 “Deployment 厨师长” 这种 Kubernetes 核心 “厨师长”的稳定性 由 Kubernetes 服务提供商保证。
  4. Operator: Kubernetes 里的 Operator,即 CRD + Custom Controller。

一个简单的图将它们串起来:

K8S 系统学习(Step 2 几个关键概念) - 图6

上图展示了我们的 My-App-Operator 的 “厨师长” 的关系图。当我们需要一个 “my-app” 应用实例时,我们只要告诉我们的 “厨师长” 是需要多少副本数的实例。我们的 “厨师长” 自动将需求转化成 Deployment,其它的功能就完全依靠了 “Deployment 厨师长”。

如何面向 Kubernetes 写一个 Operator

首先我们来看一下 “厨师长” (Operator) 需要关注一些什么事情,以及它做了什么事情:

  1. 多久要开始做菜(Observe):即 “厨师长” (Operator/Controller) 需要知道多久他要开始工作了。当用户提交了 “菜单”(CR),“厨师长” 要开始做菜。或者,因为 “桌子” 上少了一个预期中的 “菜”(Pod 因为故障少了一个),“厨师长” 也要开始做菜了。
  2. 做什么菜(Analyze): “厨师长” 首先要看看桌子上的菜,再对比一下用户的 “菜单”,得出还缺少什么菜,那么就做什么菜。
  3. 开始做菜(Action):得出做什么菜之后,那么后面的事情就简单了。通知其他 “厨师长” 做菜(提交一个其他的CR),或者自己亲手做个菜(提交一个 Pod)。

这3件事情,其实就是 Controller 模式的核心三件事:

K8S 系统学习(Step 2 几个关键概念) - 图7
那么用 Kubernetes 写一个 Operator 需要多久?
可能从 “0” 到可以把 Operator 运行起来只需要 10分钟吧。因为 Kubernetes 的 Kube-Apiserver 提供天然的 watch 接口,我们可以去关注我们在意的资源(我们的 CR,我们的 Pod 等),这样我们的 “厨师” 就能很自然的得到通知该干活了。然后 “厨师” 就开始做出分析,到最后再向 Kube-Apiserver 提交我们想要的资源(Deployment,或者其它的 CR)。我们都面向 Kube-Apiserver 做编程, 所有的“厨师”都 向 Kube-Apiserver 提交、修改、Watch资源作为统一的交互协议,一切都会变得简单许多。

最后,再加上 Operator 的脚手架帮我们生成基础代码(初始化 Kubernetes 客户端,建立 Watch 等),我们开发者只需要关心的怎么 Analyze 和 Action 即可。 Operator 的脚手架社区常见的有 kube-builder 和 coreos 提供的 operator-framework 等。

我们用伪代码来写一下上文画的 My-App-Operator 核心逻辑 (其它都脚手架做好了,甚至如何 build,Operator 本身它自己如何部署的“菜单” YAML 都是脚手架生成好了):

  1. // Reconcile 即我们 Operator 核心代码逻辑
  2. // Reconcile 何时触发,也是 Operator 生成好了
  3. func Reconcile(crName string) error {
  4. // 获取 CR (用户提交的“菜单”)
  5. cr := client.getCR(crName)
  6. // 计算出这个 CR 期望的 Deployment (用户提交的“菜单”应该在桌子上有什么菜)
  7. desireDeployment := getDesireDeployment(client, cr)
  8. // 目前集群里面实际的 Deployment (实际上桌子上有什么菜)
  9. deployment := client.GetDeployment(crName)
  10. // 如果期望和实际的不太一样,把实际的更新一下就行了。
  11. if diff(desireDeployment, deployment) {
  12. return client.UpdateDeployment(desireDeployment);
  13. }
  14. // 如果期望和实际都一样,什么事情都不做了。
  15. return nil
  16. }

面向 Kubernetes 编程和 Operator 的优势总结

  1. 统一的信息获取源和统一的接口: Kube-Apiserver 就像是一个大的信息流转中心。所有的组件(“厨师长”)都通过这个中心上传他负责的资源(CR,Deployment,Pod都是 Kubernetes 的资源)的信息,同时,他也通过这个接口,去感知其它资源状态的变化,如果这些变化是他感兴趣的,那么他就开始工作(“厨师长” 开始工作)。
  2. 构建在 Kubernetes 核心组件以及 社区通用的 Operator 之上:站在巨人的肩膀上能让我们的工作更加的减负同时达到更加理想的效果。上文中,我们的 Operator 可能在依赖 Deployment 之后,他负责的 “菜”(Pod)就自带副本保持功能。同时,假如我们的应用(DB,Web)要依赖社区的 MySQL 数据库,那么我们的应用 Operator(Web + DB) 可以通过社区的 MySQL-Operator 提供的 CR 快速建出 MySQL 实例,然后再使用 Deployment 建出 Web。

FaaS

用 Operator 交付软件,目前看起来是最酷的一种交付软件方式。

但是在当今云原生技术快速发展的时代,可能在不久的将来,Operator 模式可能也会被淘汰。因为 Operator 也需要开发者关注一些部署的细节,让开发者真正只关注在自己的业务逻辑,“业务代码” 变成 “服务” 完全对开发者透明,可能需要比 Kubernetes 更上层的框架 - FaaS框架。

FaaS 全称是 Function as a service 。用户只要写自己的业务函数,向 Kubernetes 提交业务函数,FaaS 框架将业务函数变成 Deployment,变成 Pod,变成 Service。但是 FaaS 目前还在发展阶段,并不像 Kubernetes 已经变成事实标准,这里不再详细讨论。

TODO:

  • 阅读一个 Operator 源码