ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

基于operator-sdk的kubernetes-operator实现

2021-12-31 16:02:44  阅读:156  来源: 互联网

标签:控制器 kubernetes ctrl -- make operator sdk


目录

简介

本文基于operator-sdk,实现一个简单的operator,一方面学习和了解operator,另一方面通过该operator实现一个简单的功能:对于符合名称前缀的一系列命名空间,约束某些命名空间的deployment replica为0,仅允许白名单里的namespace有pod运行。

实现该自动化的动机是:在工作中由于集群资源有限,且开发中的项目版本众多,每个版本都在各自的命名空间运行,大量的pod可能未在使用。在交付发布前,需要优先保证待发布版本的命名空间能够有足够的资源运行pod,避免因为各种resource不足导致的调度失败。在没有该operator时,需要每次发布前挑选版本,然后逐个运行kubectl scale命令将命名空间内的deploy全部缩为0。

本文仓库地址:lwabish/namespace-scaler-operator: 按照参数配置,把在管理范围内且不在白名单内的namespace下的deployment全部scale为0 (github.com)

准备工作

  1. 安装operator-sdk:Installation | Operator SDK (operatorframework.io)

  2. 初始化项目:operator-sdk init --domain wubw.fun --repo github.com/lwabish/namespace-scaler-operator

  3. 创建指定GVK(Group Version Kind)的crd和控制器,本文的cr kind为NSScaler:operator-sdk create api --group operators --version v1alpha1 --kind NSScaler --resource --controller --namespaced=false

  4. 修改cr的spec结构体api/v1alpha1/nsscaler_types.go,按需增加字段,然后make generate用代码生成器生成深拷贝之类的代码。

  5. 生成crd yaml:make manifests

控制器实现

controllers/nsscaler_controller.go为控制器,需要我们实现协调循环函数Reconcile

触发

  1. 首先,我们的cr在创建、更新、删除时,控制器显然是需要调用Reconcile函数进行状态协调的。
  2. 其次,如果operator会创建附属于operator的子资源,那么这些子资源的状态发生变更时也应该调用Reconcile函数进行协调。如果是这种情况需要参考文档增加子资源类型。

父子关系

如果operator会创建子资源,那么需要在创建后标记出父子关系:controllerutil.SetControllerReference()

增删改查

控制器结构体组合了一个专门为控制器准备的k8s client,可以用该client从cache中高效地增删改查集群对象,作为完成逻辑的基础。

// 基本逻辑先创建实例,然后把指针传给r.Get/List/Update等方法,最后获取结果
func (r *NSScalerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
  ...
  // 查
  instance := &operatorsv1alpha1.NSScaler{}
	err := r.Get(ctx, req.NamespacedName, instance)
  
  // 批量查
  nsList := &coreV1.NamespaceList{}
	err = r.List(ctx, nsList, &client.ListOptions{})
  
  // 改
  err = r.Update(ctx, &deployment, &client.UpdateOptions{})
}

状态维护

instance.Status.Done = noPodObserved
err = r.Status().Update(context.TODO(), instance)

幂等性

幂等性十分关键。确保每次调用协调循环完成的任务都是独立的,不依赖于其他操作的状态。

协调结果

// 有错
return ctrl.Result{}, err

// 没错,需要再次协调
return ctrl.Result{Requeue: true}, nil

// 正常结束
return ctrl.Result{}, nil

// 延时再次协调
return ctrl.Result{RequeueAfter: nextRun.Sub(r.Now())}, nil

本地调试

  1. make install/make uninstall 安装卸载crd到kubeconfig中的集群。

  2. make run启动控制器或使用idea/goland等debug main.go 启动控制器。

  3. kubectl apply -f config/samples/xxx.yaml 部署cr,观察控制器被触发后的效果。

集群部署

  1. 修改makefile中的IMAGE_TAG_BASEIMG ?= $(IMAGE_TAG_BASE):$(VERSION), 并设置合适的版本号version
  2. 国内网络即使宿主机可以连接k8s.io,在多阶段构建时容器里也无法直连k8s.io下载依赖。因此需要设置go proxy。Dockerfile中增加ENV GOPROXY="https://goproxy.cn,direct"
  3. build、push镜像:make docker-build docker-push
  4. 准备rbac相关的权限yaml。偷懒可直接在config/rbac/role_binding.yaml中把sa关联cluster-admin。
  5. make deploy

集群卸载

make undeploy

参考

Go Operator Tutorial | Operator SDK (operatorframework.io)

标签:控制器,kubernetes,ctrl,--,make,operator,sdk
来源: https://www.cnblogs.com/lwabish/p/an-operator-based-on-operator-sdk.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有