Operator Framework简介

什么是Operator

引用官网的话,“An Operator is a method of packaging, deploying and managing a Kubernetes application.” Operator是一种打包、部署、管理K8S应用的方式。

很明显,Operator天生就是面向交付及运维的。在常见的环境中,对于无状态的K8S应用,借助于容器的健康检查机制通过自启可以解决绝大部分问题(虽然一定程度上也掩盖了自身确实存在的问题),对这些应用,使用Operator的必要性不足,所以通常的Operator,都是针对于有状态应用/中间件来做具体实现的。可以参考当前一些成熟的或正在孵化中的Operator项目:https://github.com/operator-framework/awesome-operators

Operator应用场景

在传统运维环境中,中间件都是基于非容器部署,我们往往会面对各种部署及运维需求:
1. 备份&数据恢复。备份分为冷备和热备。冷备通常可以通过定时任务执行,对于即时的备份需求,大公司内部往往有成熟的平台支撑,但中小企业往往是运维人员手动执行操作,数据恢复也是如此
2. 扩容。又分scaleup、scaleout。对于数据库,如果只是scaleout,增加从节点,相对较容易;但是如果是scaleup,升级主节点cpu、内存呢?往往涉及比较复杂的一系列运维操作,且风险极大
3. 故障恢复。对于特定中间件,通常都有比较成熟的高可用集群部署方案,但对于运维而言,依然存在诸多问题。对于异常节点,如何恢复?对于不同中间件之间的依赖,如何处理?(比如断电重启中,hadoop对zk的依赖,hbase对hadoop的依赖等)
4. 声明式部署。对于POC环境,单节点即可;对于生产环境,使用集群方式,节点数多少等等,都使用声明式地配置,通过helm/ansible方式一键安装
5. 安全。网络访问限制、加密协议及秘钥管理等
6. 版本升级。如何平滑升级,一直是部署运维人员面对有状态系统头疼的问题,所以通常这些系统比较稳定,一方面是自身问题,另一方面是升级困难风险高,不得不压住升级需求。

以上场景都是可以通过Operator解决,使用方式上,只需要创建指定格式的K8S CRD即可,至于Operator内部如何执行具体的部署/运维逻辑,交付人员无需关心。

Operator作用域

Operator比运维人员的人工判断要敏捷的多,它可以观测集群/应用的当前状态并在若干毫秒之内作出合理的运维决定。

Operator遵循如下成熟度模型:

scope

Helm通常用于Charts的部署于升级,Ansible则可以触及到应用的生命周期管理,而高级的Operator可以实现无缝升级、自动处理故障,真正达到Auto-pilot,自运维、自巡航。

Operator与K8S Controller的关系

几个tips:

  • 所有的Operator都是用了Controller模式,但并不是所有Controller都是Operator。只有当它满足: controller模式 + API扩展 + 专注于某个App/中间件时,才是一个Operator。
  • Operator就是使用CRD实现的定制化的Controller. 它与内置K8S Controller遵循同样的运行模式(比如 watch, diff, action)
  • Operator是特定领域的Controller实现

所以要了解Operator的工作原理,首先要先了解K8S controller的原理。控制器是一个永不终止的控制循环,它持续管理着集群的状态,通过apiserver获取系统的状态,并且不断尝试以达到预期状态,比如副本控制器,namespace控制器,service-accounts控制器,Ingress也是一个典型的Controller实现


controller模型

Informer和workqueue是两个核心组件。Controller可以有一个或多个informer来跟踪某一个resource。Informter跟API server保持通讯获取资源的最新状态并更新到本地的cache中,一旦跟踪的资源有变化,informer就会调用callback。把关心的变更的Object放到workqueue里面。然后woker执行真正的业务逻辑,计算和比较workerqueue里items的当前状态和期望状态的差别,然后通过client-go向API server发送请求,直到驱动这个集群向用户要求的状态演化。

Operator具体应用举例

1)mysql-operator 如何进行定时数据备份:

image

2)etcd-operator如何rolling-upgrade

image

如何开发一个Operator

Operator Framework

通常对运维人员越友好,隐藏的逻辑就越多,这些逻辑不会凭空消失,而是下沉给开发者实现,这也符合Devops的核心理念,开发者自运维。但是从0开发一个Operator有很高的门槛,因此coreos提供了一个Operator Framework加速开发,包含以下几个组件:

Operator SDK。集成controller-runtime,提供了:编写运维逻辑的高阶API,快速构建Operator项目及代码生成的脚手架工具,覆盖常见Operator用例的扩展。Operator SDK是Operator Framework中最核心的工程。

Operator Lifecycle Manager:K8S集群内所有Operator(及其关联服务)的生命周期管理( installation, updates, and management )

Getting Started

借用官网Helm例子,实现一个nginx-operator

1. 安装 Operator SDK CLI

Operator SDK CLI 可以帮助开发快速创建、构建、部署一个新的Operator工程

mkdir -p $GOPATH/src/github.com/operator-framework
cd $GOPATH/src/github.com/operator-framework
git clone https://github.com/operator-framework/operator-sdk
cd operator-sdk
git checkout master
make dep
make install

operator-sdk工具会安装在 $GOPATH/bin路径下
可以将此工具cp到bin目录,方便使用:cp operator-sdk /usr/local/bin/

2. 创建一个新项目

使用CLI创建一个基于Helm的Operator项目:

operator-sdk new nginx-operator --api-version=example.com/v1alpha1 --kind=Nginx --type=helm
cd nginx-operator

这样就创建出了一个监听Nginx资源(即K8S中的CRD)的nginx-operator项目

目录结构如下:

$ tree -F nginx-operator/
nginx-operator/
├── build/ #Contains scripts that the operator-sdk uses for build and initialization.
│   └── Dockerfile
├── deploy/  #ontains a generic set of Kubernetes manifests for deploying this operator on a Kubernetes cluster.
│   ├── crds/
│   │   ├── example_v1alpha1_nginx_cr.yaml
│   │   └── example_v1alpha1_nginx_crd.yaml
│   ├── operator.yaml
│   ├── role.yaml
│   ├── role_binding.yaml
│   └── service_account.yaml
├── helm-charts/ # 标准charts格式
│   └── nginx/
│       ├── Chart.yaml
│       ├── charts/
│       ├── templates/
│       │   ├── NOTES.txt
│       │   ├── _helpers.tpl
│       │   ├── deployment.yaml
│       │   ├── ingress.yaml
│       │   ├── service.yaml
│       │   └── tests/
│       │       └── test-connection.yaml
│       └── values.yaml
└── watches.yaml #Contains Group, Version, Kind, and Helm chart location.

3. 定制Operator逻辑

Nginx CR

生成的watches.yaml内容如下:

$ cat watches.yaml
---
- version: v1alpha1
  group: example.com
  kind: Nginx
  chart: /opt/helm/helm-charts/nginx

它表示我们的Operator会watch Nginx这个资源的事件(create,update,delete等),部署时使用 /opt/helm/helm-charts/nginx这个chart进行部署。
在生成的nginx-operator中,helm-charts/nginx是一个标准的Helm Chart模板,Helm格式的具体参考见:Helm Chart developer documentation.

Nginx Helm Chart

Helm使用 values 提供自定义默认值配置的能力, 见 helm-charts/nginx/values.yaml
覆盖这些默认值就像在CR规范中设置所需的值一样简单。我们以副本数量为例。

首先,检查helm-charts/nginx/values.yaml,我们看到Chart有一个名为replicaCount的值,默认设置为1。如果我们想要在部署中使用2个nginx实例,我们需要确保我们的CR规范包含replicaCount:2

更新deploy/crds/example_v1alpha1_nginx_cr.yaml如下:

apiVersion: example.com/v1alpha1
kind: Nginx
metadata:
  name: example-nginx
spec:
  replicaCount: 2

同样,我们看到默认服务端口设置为80,但我们想使用8080,因此我们将通过添加服务端口覆盖来再次更新deploy/crds/example_v1alpha1_nginx_cr.yaml:

apiVersion: example.com/v1alpha1
kind: Nginx
metadata:
  name: example-nginx
spec:
  replicaCount: 2
  service:
    port: 8080

该CR文件其实就是Helm Chart的标准values.yaml文件,使用kubectl create创建该CR后,operator内部逻辑就像使用helm install -f ./overrides.yaml一样,所有需要修改的变量都要在这个文件中配置。

Build and run the operator

在run operator之前,Kubernetes需要知道要watch的CRD资源是什么。
部署CRD(如果创建operator前没有创建CRD,operator会启动失败):
kubectl create -f deploy/crds/example_v1alpha1_nginx_crd.yaml

在k8s集群中运行operator,首先要构建operator镜像并将镜像push到我们的集群仓库中:

operator-sdk build quay.io/example/nginx-operator:v0.0.1
docker push quay.io/example/nginx-operator:v0.0.1

然后把deploy/operator.yaml中的REPLACE_IMAGE替换为我们刚才push的镜像:
sed -i 's|REPLACE_IMAGE|quay.io/example/nginx-operator:v0.0.1|g' deploy/operator.yaml

部署nginx-operator:

kubectl create -f deploy/service_account.yaml
kubectl create -f deploy/role.yaml
kubectl create -f deploy/role_binding.yaml
kubectl create -f deploy/operator.yaml

至此,一个nginx-operator就成功创建出来了:


image.png

到这一步只是将operator创建成功,需要创建我们上面提到的CR文件,才能将我们最终需要的nginx pod创建出来,当然可以编写多个CR文件,这样就能创建多个nginx deployment
kubectl apply -f deploy/crds/example_v1alpha1_nginx_cr.yaml

$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
example-nginx-b9phnoz9spckcrua7ihrbkrt1 2 2 2 2 1m

环境铲除:

kubectl delete -f deploy/crds/example_v1alpha1_nginx_cr.yaml
kubectl delete -f deploy/operator.yaml
kubectl delete -f deploy/role_binding.yaml
kubectl delete -f deploy/role.yaml
kubectl delete -f deploy/service_account.yaml
kubectl delete -f deploy/crds/example_v1alpha1_nginx_crd.yaml

operator helm化

什么意思?
我们已经用operator部署了一个helm chart,什么叫operator helm化?
其实很好理解,观察下我们上述的部署操作,如果我们把CRD、role_binding、service_account等等这些放到一个Chart里面,则通过helm install的方式可以直接安装operator,再通过create特定的cr,创建对应的资源。
可以参考jaeger-operator

注:遇到一个坑,删除不掉CR和CRD

运行kubectl delete -f deploy/crds/example_v1alpha1_nginx_cr.yaml之后,nginx pod没有按预期被删除掉。发现资源仍然存在,所以operator监听不到资源的销毁

# kubectl get Nginx
NAME                 AGE
example-nginx        1m

解决:

# kubectl patch nginx/example-nginx -p '{"metadata":{"finalizers":[]}}' --type=merge
nginx "example-nginx" patched

另外CRD删不掉的情况:

kubectl patch crd/nginxes.example.com -p '{"metadata":{"finalizers":[]}}' --type=merge
kubectl create -f deploy/crds/example_v1alpha1_nginx_crd.yaml
kubectl patch nginx/emas-default-nginx -p '{"metadata":{"finalizers":[]}}' --type=merge

https://github.com/kubernetes/kubernetes/issues/60538

helm方式目前仅适用于创建、更新,对于备份、恢复之类的操作,没有显式的扩展支持。

Ref

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,841评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,415评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,904评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,051评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,055评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,255评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,729评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,377评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,517评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,420评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,467评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,144评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,735评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,812评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,029评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,528评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,126评论 2 341