15 分钟制作 Kubernetes Operator
原文:Make a Kubernetes Operator in 15 minutes with Helm
作者:Rob Szumski
之前我们介绍了如何使用 Ansible 实现 Helm Chart 的自动化。今天会继续这方面的话题,但是会转用 Operator。Operator 是一种打包、部署和管理 Kubernetes 应用的方法。这里说的 Kubernetes 应用,不仅是部署在 Kubernetes 集群中,还使用 Kubernetes API 以及 kubectl 工具进行管理。
本文会尝试根据已有的 Helm chart 来创建一个 Operator,以此展示 Operator 的价值。这一过程无需编写 Go 代码,仅需要使用 Operator 框架 中的 Helm Operator 工具包。最后还会对 Go 和 Helm 实现的 Operator 进行比较。
我们期待的用户体验
本文试图描述多数公司中都存在的一种场景:用稳定、可复用以及可审计的方式,在多个环境中发布应用或产品,首先做一下分析。
稳定的部署过程:在符合所有需求的情况下(例如所有测试均已通过,或者负责人审核通过),用全自动的方式进行部署。
可复用的部署过程:工件一旦完成构建,就应该有一个无法变更的版本号。对于单个组件来说,在容器中进行构建是很方便的,然而分布式系统通常都是多个组件构成的。Helm chart 可以将这些组件组织到一起,但是 Chart 本身也需要版本化。Helm Operator 可以把 Chart 和依赖捆绑到 Operator 容器镜像中,这样就有了一个覆盖完整分布式系统的单一的版本化呈现。借助版本化的 Operator 容器,工程师就能在多个环境中运行同一版本的应用了。
可审计的部署过程:应用的部署和运行都是在受控的环境中完成的,而不是工程师的笔记本电脑。Helm Operator 允许用户使用现存的 Helm Chart,无需手工运行 Helm 命令。这样就降低了一次性错误的发生机会,提供了用于审计的轨迹。
这一过程大致包含一下步骤,后续会进一步进行说明:
对 Chart 进行一些变更。例如给应用组件加入版本。
一个用于构建 Operator的持续构建流程,将新的 Chart 拷贝到容器之中。
能把 Operator 部署到测试集群上一个新的命名空间的测试管线。测试套件使用新的 Operator,运行对应配置的应用。假设一个应用同时提供了标准模式和高可用模式的配置,Operator 应该可以使用新的 Chart 来测试这两种模式。新的命名空间应该可以在测试完成后删除。
如果测试通过,发布管理员会进行确认,或者自动触发确认过程。接下来持续部署系统会使用这一 Operator 对应用进行在线的滚动更新,或蓝绿部署。这一过程应该能够在应用所在的其他环境、其他命名空间中重复运行。
接下来会手工完成整个过程,当然读者可以发挥想象力,例如将 Quay.io 加入进来构建镜像,或者用 Jenkins/CircleCI 等运行测试并和 Kubernetes 进行通信。
前提条件:Kubernetes 环境和镜像库
Helm Operator 套件需要 Kubernetes 1.9 以上的集群,集群需要有足够资源运行一到两套测试应用。本地需要有 Docker 来构建镜像,并且有 kubectl 用于控制集群。如果熟悉常 Helm 操作,对本文的理解会更有帮助。
Operator 如何运作
Helm Operator 是用来应对仅需少量部署逻辑的无状态应用的。如果这一描述不符合你的应用的实际情况,在本文最后会提供一些替代选项。
Operator 的主要功能就是在自定义对象和对应应用实例的状态之间进行同步。Helm Operator 套件生成的 Operator 对象中,spec 字段是一个配置列表,其内容一般是在 Helm 的 values.yaml 文件中指定的。我们会在自定义资源中指定选项值,而不是使用命令参数(helm install -f values.yaml),自定义资源对象是 Kubernetes 的原生对象,这样就能够享受到 RBAC 和审计方面的益处。例如这样一个简单的资源:
apiVersion: apache.org/v1alpha1
kind: Tomcat
metadata:
name: example-app
spec:
replicaCount: 2
replicaCount 的值是 2,会传播给 Chart 的模板:
{{ .Values.replicaCount }}
Operator 构建和部署之后,部署应用的新实例就很只需要简单的创建一个新的自定义资源了。比如说要列出所有环境中的实例,只需要使用 kubectl:
kubectl get Tomcats --all-namespaces
这样也就无需使用 Helm 命令行或者安装 Tiller 了;Operator 镜像是由 Helm Operator 套件从 Helm 项目中导入生成的。只要 Operator 实例在运行,并用 CRD 注册自定义资源即可,并且自定义资源需服从 RBAC 的管理,这样也可以更方面的管理产品的变更。
这就好像建立了一个应用上线的流程:首先创建自定义资源,然后实例就会上线和运行。
构建 Operator 镜像
我们认为最佳时间就是为每个 Chart 都创建一个新的 Operator。这样看起来更符合 Kubernetes API 的风格(例如 kubectl get Tomcats),如果需要更好的控制,还可把 Operator 从 Helm 迁移到 Go。第一步是把 Chart、Kubernetes API 组(例如 apache.org/v1alpha1)以及 Kind(例如 Tomcat)集成到 Operator 的容器镜像中。这一部分很简单,Dockerfile 把这些变量用构建参数的形式公开为变量。只要构建 Dockerfile 然后进行推送即可:
$ docker build \
--build-arg HELM_CHART=https://storage.googleapis.com/kubernetes-charts/tomcat-0.1.0.tgz \
--build-arg API_VERSION=apache.org/v1alpha1 \
--build-arg KIND=Tomcat \
-t quay.io/<namespace>/tomcat-operator:v0.0.1 .
$ docker push quay.io/<namespace>/tomcat-operator:v0.0.1
相关链接
使用 Ansible 实现 Helm Chart 的自动化:
https://blog.openshift.com/automating-helm-charts-with-ansible/Operator 框架:
https://github.com/operator-framework)Helm Operator 工具包:
https://github.com/operator-framework/helm-app-operator-kit
