草庐IT

operator简介

yl555 2023-03-28 原文

原理

operator 是一种 kubernetes 的扩展形式,利用自定义资源对象(Custom Resource)来管理应用和组件,允许用户以 Kubernetes 的声明式 API 风格来管理应用及服务。

  • CRD (Custom Resource Definition): 允许用户自定义 Kubernetes 资源,是一个类型;
  • CR (Custom Resourse): CRD 的一个具体实例;
  • webhook: 它本质上是一种 HTTP 回调,会注册到 apiserver 上。在 apiserver 特定事件发生时,会查询已注册的 webhook,并把相应的消息转发过去。按照处理类型的不同,一般可以将其分为两类:一类可能会修改传入对象,称为 mutating webhook;一类则会只读传入对象,称为 validating webhook。
  • 工作队列: controller 的核心组件。它会监控集群内的资源变化,并把相关的对象,包括它的动作与 key,例如 Pod 的一个 Create 动作,作为一个事件存储于该队列中;
  • controller :它会循环地处理上述工作队列,按照各自的逻辑把集群状态向预期状态推动。不同的 controller 处理的类型不同,比如 replicaset controller 关注的是副本数,会处理一些 Pod 相关的事件;
  • operator:operator 是描述、部署和管理 kubernetes 应用的一套机制,从实现上来说,可以将其理解为 CRD 配合可选的 webhook 与 controller 来实现用户业务逻辑,即 operator = CRD + webhook + controller。

工作流程

  1. 用户创建一个自定义资源 (CRD);
  2. apiserver 根据自己注册的一个 pass 列表,把该 CRD 的请求转发给 webhook;
  3. webhook 一般会完成该 CRD 的缺省值设定和参数检验。webhook 处理完之后,相应的 CR 会被写入数据库,返回给用户;
  4. 与此同时,controller 会在后台监测该自定义资源,按照业务逻辑,处理与该自定义资源相关联的特殊操作;
  5. 上述处理一般会引起集群内的状态变化,controller 会监测这些关联的变化,把这些变化记录到 CRD 的状态中。

构建工具

两者实际上并没有本质的区别,它们的核心都是使用官方的 controller-tools 和 controller-runtime。

operator SDK

operator framework,是 CoreOS 公司开发和维护的用于快速创建 operator 的工具,可以帮助我们快速构建 operator 应用。

安装

#下载operator sdk
wget https://github.com/operator-framework/operator-sdk/releases

创建项目

mkdir -p /root/go/src/github.com/memcached-operator
cd /root/go/src/github.com/memcached-operator
operator-sdk init --domain example.com --repo github.com/memcached-operator

创建API

operator-sdk create api --group cache --version v1alpha1 --kind Memcached --resource --controller

项目结构

# tree
.
├── api
│   └── v1alpha1
│       ├── groupversion_info.go
│       ├── memcached_types.go
│       └── zz_generated.deepcopy.go
├── bin
│   └── controller-gen
├── config
│   ├── crd
│   │   ├── kustomization.yaml
│   │   ├── kustomizeconfig.yaml
│   │   └── patches
│   │       ├── cainjection_in_memcacheds.yaml
│   │       └── webhook_in_memcacheds.yaml
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   └── manager_config_patch.yaml
│   ├── manager
│   │   ├── controller_manager_config.yaml
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── manifests
│   │   └── kustomization.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   ├── rbac
│   │   ├── auth_proxy_client_clusterrole.yaml
│   │   ├── auth_proxy_role_binding.yaml
│   │   ├── auth_proxy_role.yaml
│   │   ├── auth_proxy_service.yaml
│   │   ├── kustomization.yaml
│   │   ├── leader_election_role_binding.yaml
│   │   ├── leader_election_role.yaml
│   │   ├── memcached_editor_role.yaml
│   │   ├── memcached_viewer_role.yaml
│   │   ├── role_binding.yaml
│   │   └── service_account.yaml
│   ├── samples
│   │   ├── cache_v1alpha1_memcached.yaml
│   │   └── kustomization.yaml
│   └── scorecard
│       ├── bases
│       │   └── config.yaml
│       ├── kustomization.yaml
│       └── patches
│           ├── basic.config.yaml
│           └── olm.config.yaml
├── controllers
│   ├── memcached_controller.go
│   └── suite_test.go
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
├── main.go
├── Makefile
└── PROJECT

17 directories, 43 files

测试

将 CRD 安装到k8s集群中
make install
部署operator
make deploy
安装CR实例
kubectl apply -f config/samples/cache_v1alpha1_memcached.yaml

卸载operator

make undeploy
卸载CRD
make uninstall

kubebuilder

安装

# 下载 kubebuilder
wget https://github.com/kubernetes-sigs/kubebuilder/releases/download/v2.3.1/kubebuilder_2.3.1_linux_amd64.tar.gz

创建项目

mkdir -p /root/go/src/github.com/testcrd-controller
cd /root/go/src/github.com/testcrd-controller

#--domain 指定了后续注册 CRD 对象的 Group 域名
kubebuilder init --domain edas.io

创建API

kubebuilder create api --group apps --version v1alpha1 --kind Application 

参数说明:

  • group 加上之前的 domian 即此 CRD 的 Group: apps.edas.io;
  • version 一般分三种,按社区标准:
    • v1alpha1: 此 api 不稳定,CRD 可能废弃、字段可能随时调整,不要依赖;
    • v1beta1: api 已稳定,会保证向后兼容,特性可能会调整;
    • v1: api 和特性都已稳定;
  • kind: 此 CRD 的类型,类似于 Service 的概念;

项目结构

# ls
api  bin  config  controllers  Dockerfile  go.mod  go.sum  hack  main.go  Makefile  PROJECT
# tree
.
├── api
│   └── v1alpha1
│       ├── application_types.go
│       ├── groupversion_info.go
│       └── zz_generated.deepcopy.go
├── bin
│   └── manager
├── config
│   ├── certmanager
│   │   ├── certificate.yaml
│   │   ├── kustomization.yaml
│   │   └── kustomizeconfig.yaml
│   ├── crd
│   │   ├── bases
│   │   │   └── apps.edas.io_applications.yaml
│   │   ├── kustomization.yaml
│   │   ├── kustomizeconfig.yaml
│   │   └── patches
│   │       ├── cainjection_in_applications.yaml
│   │       └── webhook_in_applications.yaml
│   ├── default
│   │   ├── kustomization.yaml
│   │   ├── manager_auth_proxy_patch.yaml
│   │   ├── manager_webhook_patch.yaml
│   │   └── webhookcainjection_patch.yaml
│   ├── manager
│   │   ├── kustomization.yaml
│   │   └── manager.yaml
│   ├── prometheus
│   │   ├── kustomization.yaml
│   │   └── monitor.yaml
│   ├── rbac
│   │   ├── application_editor_role.yaml
│   │   ├── application_viewer_role.yaml
│   │   ├── auth_proxy_client_clusterrole.yaml
│   │   ├── auth_proxy_role_binding.yaml
│   │   ├── auth_proxy_role.yaml
│   │   ├── auth_proxy_service.yaml
│   │   ├── kustomization.yaml
│   │   ├── leader_election_role_binding.yaml
│   │   ├── leader_election_role.yaml
│   │   ├── role_binding.yaml
│   │   └── role.yaml
│   ├── samples
│   │   └── apps_v1alpha1_application.yaml
│   └── webhook
│       ├── kustomization.yaml
│       ├── kustomizeconfig.yaml
│       └── service.yaml
├── controllers
│   ├── application_controller.go
│   └── suite_test.go
├── Dockerfile
├── go.mod
├── go.sum
├── hack
│   └── boilerplate.go.txt
├── main.go
├── Makefile
└── PROJECT

测试

将 CRD 安装到k8s集群中
make install
本地运行controller
make run
安装CR实例
kubectl apply -f config/samples/
卸载CRD
make uninstall

创建webhook

kubebuilder create webhook --group apps --version v1alpha1 --kind Application --defaulting --programmatic-validation

案例

Mongodb

安装mongodb operator

安装mongodb实例

---
apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: example-mongodb
spec:
  members: 1
  type: ReplicaSet
  version: "4.2.6"
  security:
    authentication:
      modes: ["SCRAM"]
  users:
    - name: my-user
      db: admin
      passwordSecretRef: # a reference to the secret that will be used to generate the user's password
        name: my-user-password
      roles:
        - name: clusterAdmin
          db: admin
        - name: userAdminAnyDatabase
          db: admin
      scramCredentialsSecretName: my-scram
  additionalMongodConfig:
    storage.wiredTiger.engineConfig.journalCompressor: zlib

# the user credentials will be generated from this secret
# once the credentials are generated, this secret is no longer required
---
apiVersion: v1
kind: Secret
metadata:
  name: my-user-password
type: Opaque
stringData:
  password: "123456"

使用mongodb

# kubectl exec -it example-mongodb-0 -n mongodb bash    
I have no name!@example-mongodb-0:/$ mongo
MongoDB shell version v4.2.6
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("51607c54-bc7d-4006-8ef6-a9ff0a2e767a") }
MongoDB server version: 4.2.6
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
	http://docs.mongodb.org/
Questions? Try the support group
	http://groups.google.com/group/mongodb-user
2021-08-23T03:21:29.304+0000 I  STORAGE  [main] In File::open(), ::open for '//.mongorc.js' failed with Permission denied
example-mongodb:PRIMARY> use admin
switched to db admin
example-mongodb:PRIMARY> db.auth('my-user', '123456')
1
example-mongodb:PRIMARY> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB
example-mongodb:PRIMARY> exit

ECK

Elastic Cloud on Kubernetes(ECK)是一个 Elasticsearch Operator。 ECK 使用 Kubernetes Operator 模式构建而成,需要安装在您的 Kubernetes 集群内,其功能绝不仅限于简化 Kubernetes 上 Elasticsearch 和 Kibana 的部署工作这一项任务。ECK 专注于简化所有后期运行工作,例如:

  • 管理和监测多个集群
  • 轻松升级至新的版本
  • 扩大或缩小集群容量
  • 更改集群配置
  • 动态调整本地存储的规模(包括 Elastic Local Volume(一款本地存储驱动器))
  • 备份

安装 ECK 对应的 Operator 资源对象

#kubectl apply -f https://download.elastic.co/downloads/eck/1.6.0/all-in-one.yaml

Elasticsearch

创建单节点Elasticsearch 集群
cat <<EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 7.13.2
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
EOF
创建三节点Elasticsearch的集群

宿主机设置一下sysctl -w vm.max_map_count=262144

---
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 7.13.2
  http:
    service:
      spec:
        type: NodePort
  nodeSets:
  - name: default
    count: 3
    podTemplate:
      spec:
        volumes:
        - name: elasticsearch-data
          emptyDir: {}
查看es集群状态
# kubectl get elastic 
NAME                                                    HEALTH   NODES   VERSION   PHASE   AGE
elasticsearch.elasticsearch.k8s.elastic.co/quickstart   green    3       7.13.2    Ready   2m4s
# kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
quickstart-es-default-0   1/1     Running   0          2m13s
quickstart-es-default-1   1/1     Running   0          2m13s
quickstart-es-default-2   1/1     Running   0          2m13s
# kubectl get svc
NAME                      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes                ClusterIP   10.43.0.1    <none>        443/TCP    22d
quickstart-es-default     ClusterIP   None         <none>        9200/TCP   2m23s
quickstart-es-http        ClusterIP   10.43.0.51   <none>        9200/TCP   2m24s
quickstart-es-transport   ClusterIP   None         <none>        9300/TCP   2m24s
访问es集群
# PASSWORD=$(kubectl get secret quickstart-es-elastic-user -o go-template='{{.data.elastic | base64decode}}')
# curl -u "elastic:$PASSWORD" -k "https://xx.xx.xx.xx:port"
{
  "name" : "quickstart-es-default-2",
  "cluster_name" : "quickstart",
  "cluster_uuid" : "_33mFEetTrCjkjKKJlbCCQ",
  "version" : {
    "number" : "7.13.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "4d960a0733be83dd2543ca018aa4ddc42e956800",
    "build_date" : "2021-06-10T21:01:55.251515791Z",
    "build_snapshot" : false,
    "lucene_version" : "8.8.2",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

#### kibana

##### 创建kibana

```yaml
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: testkibana
spec:
  version: 7.13.2
  count: 1
  elasticsearchRef:
    name: quickstart
查看kibna状态
# kubectl get kibanas.kibana.k8s.elastic.co 
NAME         HEALTH   NODES   VERSION   AGE
testkibana   green    1       7.13.2    68s
# kubectl get svc|grep kibana
testkibana-kb-http                    ClusterIP   10.43.50.88     <none>        5601/TCP                                87s
访问kibana服务

配置kibana svc代理,将5601端口映射

# echo $(kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode)
r0V8YQ1L51UavQOh8St8L913

#访问kibana页面:
https://xx.xx.xx.xx:5601/

用户名:elastic
密码:r0V8YQ1L51UavQOh8St8L913

有关operator简介的更多相关文章

  1. HBase Region 简介和建议数量&大小 - 2

    Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile

  2. ruby-on-rails - ruby 范围 : operators in case statement - 2

    我想检查my_number是否在某个范围内,包括较高的值。在IF语句中我会简单地使用“x>100&&x但是我应该在Ruby案例中做什么(开关)?使用:casemy_numberwhenmy_number不起作用。备注:标准范围不包括my_number恰好为500的情况,并且我不想添加第二个“when”,因为我必须编写双重内容casemy_number#between100and500when100..500puts"Correct,dosomething"when500puts"Correct,dosomethingagain"end 最佳答案

  3. ruby-on-rails - 活跃商家 : How to authorise cards when using gateways that do not support the void operation? - 2

    我正在使用ActiveMerchant开发RubyonRails应用程序的计费组件。我们选择的支付网关是PaymentExpress.我看到的代码示例如下所示,使用authorize()和void()来测试卡的有效性:deftest_card!auth_response=gateway.authorize(100,card)gateway.void(auth_response.authorization)ifauth_response.success?raiseAuthorizationFailed.new(auth_response)unlessauth_response.succe

  4. IDEA 2023.1 正式发布,新特性简介 - 2

     昨晚看到IDEA官推宣布IntelliJIDEA2023.1正式发布了。简单看了一下,发现这次的新版本包含了许多改进,进一步优化了用户体验,提高了便捷性。至于是否升级最新版本完全是个人意愿,如果觉得新版本没有让自己感兴趣的改进,完全就不用升级,影响不大。软件的版本迭代非常正常,正确看待即可,不持续改进就会慢慢被淘汰!根据官方介绍:IntelliJIDEA2023.1针对新的用户界面进行了大量重构,这些改进都是基于收到的宝贵反馈而实现的。官方还实施了性能增强措施,使得Maven导入更快,并且在打开项目时IDE功能更早地可用。由于后台提交检查,新版本提供了简化的提交流程。IntelliJIDEA

  5. 已解决socket.timeout : The read operation timed out - 2

    已解决(pip安装模块超时,利用四种国内镜像源完美解决)WARENTING:Retrying(Retry(total=4,connect=None,read=None,redirect=None,status=None))afterconnectionbrokenby‘ConnectTimeoutError(pip._vendor.urllib3.connection.HTTPSConnectionobjectatOx00001D6OE4F4A940>,‘Connectiontopypi.orgtimedout.(connecttimeout=15)’)’':/simple/pip/socke

  6. pytest简介 - 2

    介绍pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点:简单灵活,容易上手支持参数化能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试(pytest+requests)pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-selenium(集成selenium)、pytest-html(完美html测试报告生成)、pytest-rerunfailures(失败case重复执行)、pytest-xdist(多CPU分发)等测试用例的skip和xfail处理可以很好的和jenkins集成

  7. ruby 习语 : predicates and the conditional operator - 2

    我喜欢明智地使用三元条件运算符。在我看来,它非常简洁。但是,在ruby​​中,我发现我经常测试谓词方法,它们已经有了自己的问号:some_method(x.predicate??foo:bar)这两个问号靠得太近让我感到震惊。是否有同等紧凑和可读的替代方案? 最佳答案 C中需要条件运算符的原因是,条件语句是一个语句,即它不(也不能)返回值。所以,如果你想从条件代码中返回一个值,那你就不走运了。这就是必须添加条件运算符的原因:它是一个表达式,即它返回一个值。然而,在Ruby中,条件运算符是完全多余的,因为无论如何Ruby都没有语句。一

  8. ruby-on-rails - Ruby 2.3 safe navigation operator '&. and the ' 之间有什么区别试试!来自 ActiveSupport 的方法? - 2

    Ruby2.3的安全运算符&.和ActiveSupport的try!方法可以互换吗?如果不是,它们之间有什么区别? 最佳答案 一个关键的区别是try!是一个额外的方法调用,而&.不是。我能想到这造成的一个(公认的人为的)差异"1234"&.gsub(/\d/,"a")$&#=>"1234"这并不奇怪-我进行了正则表达式匹配,因此设置了正则表达式全局变量($&是匹配的字符串)。但是如果(在新的irbsession中——这很重要)我这样做"1234".try!(:gsub,/\d+/,"a")$&#=>nil然后正则表达式相关的全局变量

  9. SpringCloud入门实战(七)-Hystrix入门简介 - 2

    📝学技术、更要掌握学习的方法,一起学习,让进步发生👩🏻作者:一只IT攻城狮。💐学习建议:1、养成习惯,学习java的任何一个技术,都可以先去官网先看看,更准确、更专业。💐学习建议:2、然后记住每个技术最关键的特性(通常一句话或者几个字),从主线入手,由浅入深学习。❤️《SpringCloud入门实战系列》解锁SpringCloud主流组件入门应用及关键特性。带你了解SpringCloud主流组件,是如何一战解决微服务诸多难题的。项目demo:源码地址👉🏻SpringCloud入门实战系列不迷路👈🏻:SpringCloud入门实战(一)什么是SpringCloud?SpringCloud入门实战

  10. sql - ActionView::Template::Error (PG::UndefinedFunction: ERROR: operator does not exist: integer ~~ 未知 - 2

    为了在Heroku中使用,我从MySQL切换到了PostgreSQL。现在我的搜索不起作用。无法弄清楚运营商出了什么问题。ActionView::Template::Error(PG::UndefinedFunction:ERROR:operatordoesnotexist:integer~~unknown.2014-11-11T19:59:58.082607+00:00app[web.1]:ProcessingbyAllListingsController#search_listingsasJS2014-11-11T19:59:58.105074+00:00app[web.1]:4:

随机推荐