揭秘Kubernetes Operator(一)

您或许已经听说了自定义Kubernetes Operator,甚至已经阅读了 CoreOS operator-sdk ,并试着动手设置过。Operator的概念很酷,它可以扩展Kubernetes功能,以更好的管理有状态应用。在 Kenzan ,我们有幸使用Operator操作那些有状态的基础设施服务,包括:组件升级、节点恢复、调整集群规模。一个理想化的运维平台必须是Operator自己维护有状态应用,并将人工干预降低到最低限度。在读过一些资料后,你可能依然对什么是Operator及其各组件如何协作感到困惑。我们也认为Operator和Operator-sdk的概念有点令人困惑。

在这篇文章中,我们将揭秘什么是Operator,以及如何用CoreOS operator-sdk将输入文件转换为控制Operator运行的代码。在这个循序渐进的教程中,我们将创建一个Operator样例,包括 operator-sdk user guide 演示的功能和一些高级特性。之后,您将具备为真实应用构建Operator的坚实基础。

什么是Operator?

为了理解什么是Operator,让我们先复习一下Kubernetes。Kubernetes实际是期望状态管理器。先在Kubernetes中指定应用程序期望状态(实例数,磁盘空间,镜像等),然后它会尝试把应用维持在这种状态。Kubernetes的控制平面运行在Master节点上,它包含数个controller以调和应用达到期望状态:

  • 检查当前的实际状态(Pods、Deployment等)
  • 将实际状态与spec期望状态进行比较
  • 如果实际状态与期望状态不一致,controller将会尝试协调实际状态以达到一致

比如,通过RS定义Pod拥有3个副本。当其中一个Pod down掉时,K8s controller通过wacth API发现期望运行3个副本,而实际只有2个副本在运行。于是它新创建出一个pod实例。

如图所示,controller在Kubernetes中发挥的作用。

  • 通过Kubectl命令发送对象spec定义(Pod,Deployment等)到K8s Master节点的API服务
  • Master节点调度对象运行
  • 一旦对象运行,controller会持续检查对象并根据spec协调实际情况

通过这种方式,Kubernetes非常适合维护无状态应用。但它本身的资源类型(Pod,Deployments,Namespaces,Services,DaemonSets等)比较有限。虽然每种资源类型都预定了行为及协调方式,但它们的处理方式没有多大差别。

现在,如果您的应用更复杂并需要执行自定义操作以达到期望的运行状态,应该怎么办?

举一个有状态应用的例子。假如一个数据库应用运行在多个节点上。如果超过半数的节点出现故障,则需要按照特定步骤从特定快照中加载数据。使用原生Kubernetes对象类型和controller则难以实现。或者为有状态应用程序扩展节点,升级到新版本或灾难恢复。这些类型的操作通常需要非常具体的步骤,并且通常需要手动干预。

揭晓Operator

Operator通过扩展Kubernetes定义Custom Controller,观察应用并根据实际状态执行自定义任务。应用被定义为Kubernetes对象: Custom Resource (CR),它包含yaml spec和被API服务接受对象类型(K8s kind)。这样,您可以在自定义规范中定义要观察的任何特定条件,并在实例与规范不匹配时协调实例。虽然Operator controller主要使用自定义组件,但它与原生Kubernetes controller协调方式非常类似。

请注意,两张示意图的主要区别在于,Operator通过Custom Controller协调应用spec。虽然API服务知道Custom Controller,但Operator可以独立运行在集群内部或外部。

由于Operator是管理有状态应用的强大工具,我们可以找到一些预制Operator来自 <a href="http://dockone.io/” rel=”nofollow,noindex” target=”_blank”>CoreOS 以及其他贡献者,比如etcd、Vault和Prometheus。这些都是不错的起点,但Operator真正价值来自于你对应用失败状态处理的最佳实践,以及Operator如何协同人工干预。

构建Operator

为了创建自定义Operator,我们需要如下资源:

  1. Custom Resource (CR) spec,定义我们要观测的应用对象,以及为CR定义的API
  2. Custom Controller,用来观测CR
  3. Custom code,决定Custom Controller如何协调CR
  4. Operator,管理Custom Controller
  5. Deployment,定义Operator和自定义资源

所有上述内容都可以通过手工编写go代码和spec,或通过 kubebuilder 等工具生成Kubernetes API。但最简单的方式(也是我们在这里使用的方法)是使用 CoreOS operator-sdk 为这些组件生成模版。它允许您通过CLI命令生成spec、controller以及Operator框架。一旦生成后,您可以在spec中定义自定义字段并编写协调的自定义代码。我们将在本教程的下一部分中展开介绍。