从 Helm 到 Operator:Kubernetes应用管理的进化

news/2024/11/20 20:43:19/文章来源:https://www.cnblogs.com/crossoverJie/p/18289299

🧰Helm 的作用

在开始前需要先对 kubernetes Operator 有个简单的认识。

以为我们在编写部署一些简单 Deployment 的时候只需要自己编写一个 yaml 文件然后 kubectl apply 即可。

apiVersion: apps/v1  
kind: Deployment  
metadata:  labels:  app: k8s-combat  name: k8s-combat  
spec:  replicas: 1  selector:  matchLabels:  app: k8s-combat  template:  metadata:  labels:  app: k8s-combat  spec:  containers:  - name: k8s-combat  image: crossoverjie/k8s-combat:v1  imagePullPolicy: Always  resources:  limits:  cpu: "1"  memory: 300Mi  requests:  cpu: "0.1"  memory: 30Mi
kubectl apply -f deployment.yaml

这对于一些并不复杂的项目来说完全够用了,但组件一多就比较麻烦了。


这里以 Apache Pulsar 为例:它的核心组件有:

  • Broker
  • Proxy
  • Zookeeper
  • Bookkeeper
  • Prometheus(可选)
  • Grafana(可选)
    等组件,每个组件的启动还有这依赖关系。

必须需要等 Zookeeper 和 Bookkeeper 启动之后才能将流量放进来。

此时如何还继续使用 yaml 文件一个个部署就会非常繁琐,好在社区有提供 Helm 一键安装程序,使用它我们只需要在一个同意的 yaml 里简单的配置一些组件,配置就可以由 helm 来部署整个复杂的 Pulsar 系统。

components:  # zookeeper  zookeeper: true  # bookkeeper  bookkeeper: true  # bookkeeper - autorecovery  autorecovery: true  # broker  broker: true  # functions  functions: false  # proxy  proxy: true  # toolset  toolset: true  # pulsar manager  pulsar_manager: false  
monitoring:  # monitoring - prometheus  prometheus: true  # monitoring - grafana  grafana: true  # monitoring - node_exporter  node_exporter: true  # alerting - alert-manager  alert_manager: false

比如在 helm 的 yaml 中我们可以选择使用哪些 components,以及是否启用监控组件。

最后直接使用这个文件进行安装:

helm install pulsar apache/pulsar \--values charts/pulsar/values.yaml \--set namespace=pulsar \--set initialize=true

它就会自动生成各个组件的 yaml 文件,然后统一执行。

所以 helm 的本质上和 kubectl apply yaml 一样的,只是我们在定义 value.yaml 时帮我们处理了许多不需要用户低频修改的参数。

我们可以使用 helm 将要执行的 yaml 输出后人工审核

helm install pulsar apache/pulsar --dry-run --debug > debug.yaml

🤔Operator 是什么

💔Helm 的痛点

Helm 虽然可以帮我们部署或者升级一个大型应用,但他却没法帮我们运维这个应用。

举个例子:比如我希望当 Pulsar Broker 的流量或者内存达到某个阈值后就指定扩容 Broker,闲时再自动回收。

或者某个 Bookkeeper 的磁盘使用率达到阈值后可以自动扩容磁盘,这些仅仅使用 Helm 时都是无法实现的。

以上这些需求我们目前也是通过监控系统发出报警,然后再由人工处理。

其中最大的痛点就是进行升级:

  • 升级ZK
  • 关闭auto recovery
  • 升级Bookkeeper
  • 升级Broker
  • 升级Proxy
  • 开启auto recovery

因为每次升级是有先后顺序的,需要依次观察每个组件运行是否正常才能往后操作。

如果有 Operator 理性情况下下我们只需要更新一下镜像版本,它就可以自动执行以上的所有步骤最后将集群升级完毕。

所以相对于 Helm 来说 Operator 是可以站在一个更高的视角俯视整个应用系统,它能发现系统哪个地方需要它从而直接修复。

💎CRD(Custom Resource Definitions)

而提到 Operator 那就不得不提到 CRD(Custom Resource Definitions)翻译过来就是自定义资源。

这是 kubernetes 提供的一个 API 扩展机制,类似于内置的 Deployment/StatefulSet/Services 资源,CRD 是一种自定义的资源。

这里以我们常用的 prometheus-operatorVictoriaMetrics-operator 为例:

Prometheus:

  • Prometheus:用于定义 Prometheus 的 Deployment
  • Alertmanager:用于定义 Alertmanager
  • ScrapeConfig:用于定会抓取规则
apiVersion: monitoring.coreos.com/v1alpha1
kind: ScrapeConfig
metadata:name: static-confignamespace: my-namespacelabels:prometheus: system-monitoring-prometheus
spec:staticConfigs:- labels:job: prometheustargets:- prometheus.demo.do.prometheus.io:9090

使用时的一个很大区别就是资源的 kind: ScrapeConfig 为自定义的类型。

VictoriaMetrics 的 CRD:

  • VMPodScrape:Pod 的抓取规则
  • VMCluster:配置 VM 集群
  • VMAlert:配置 VM 的告警规则
  • 等等
# vmcluster.yaml
apiVersion: operator.victoriametrics.com/v1beta1
kind: VMCluster
metadata:name: demo
spec:retentionPeriod: "1"replicationFactor: 2vmstorage:replicaCount: 2storageDataPath: "/vm-data"storage:volumeClaimTemplate:spec:resources:requests:storage: "10Gi"resources:limits:cpu: "1"memory: "1Gi"vmselect:replicaCount: 2cacheMountPath: "/select-cache"storage:volumeClaimTemplate:spec:resources:requests:storage: "1Gi"resources:limits:cpu: "1"memory: "1Gi"requests:cpu: "0.5"memory: "500Mi"vminsert:replicaCount: 2

以上是用于创建一个 VM 集群的 CRD 资源,应用之后就会自动创建一个集群。

Operator 原理


Operator 通常是运行在 kubernetes API server 的 webhook 之上,简单来说就是在一些内置资源的关键节点 API-server 会调用我们注册的一个 webhook,在这个 webhook 中我们根据我们的 CRD 做一些自定义的操作。

理论上我们可以使用任何语言都可以写 Operator,只需要能处理 api-server 的回调即可。

只是 Go 语言有很多成熟的工具,比如常用的 kubebuilder 和 operator-sdk.

他们内置了许多命令行工具,可以帮我们节省需要工作量。

这里以 operator-sdk 为例:

$ operator-sdk create webhook --group cache --version v1alpha1 --kind Memcached --defaulting --programmatic-validation

会直接帮我们创建好一个标准的 operator 项目:

├── Dockerfile
├── Makefile
├── PROJECT
├── api
│   └── v1alpha1
│       ├── memcached_webhook.go
│       ├── webhook_suite_test.go
├── config
│   ├── certmanager
│   │   ├── certificate.yaml
│   │   ├── kustomization.yaml
│   │   └── kustomizeconfig.yaml
│   ├── default
│   │   ├── manager_webhook_patch.yaml
│   │   └── webhookcainjection_patch.yaml
│   └── webhook
│       ├── kustomization.yaml
│       ├── kustomizeconfig.yaml
│       └── service.yaml
├── go.mod
├── go.sum
└── main.go

其中 Makefile 中包含了开发过程中常用的工具链(包括根据声明的结构体自动生成 CRD 资源、部署k8s 环境测试等等)、Dockerfile 等等。

这样我们就只需要专注于开发业务逻辑即可。

因为我前段时间给 https://github.com/open-telemetry/opentelemetry-operator 贡献过两个 feature,所以就以这个 Operator 为例:

它有一个 CRD: kind: Instrumentation,在这个 CRD 中可以将 OpenTelemetry 的 agent 注入到应用中。

apiVersion: opentelemetry.io/v1alpha1  
kind: Instrumentation  
metadata:  name: instrumentation-test-ordernamespace: test  
spec:  env:  - name: OTEL_SERVICE_NAME  value: orderselector:  matchLabels:  app: order  java:  image: autoinstrumentation-java:2.4.0-release  extensions:  - image: autoinstrumentation-java:2.4.0-release  dir: /extensions  env:  - name: OTEL_RESOURCE_ATTRIBUTES  value: service.name=order  - name: OTEL_INSTRUMENTATION_MESSAGING_EXPERIMENTAL_RECEIVE_TELEMETRY_ENABLED  value: "true"  - name: OTEL_TRACES_EXPORTER  value: otlp  - name: OTEL_METRICS_EXPORTER  value: otlp  - name: OTEL_LOGS_EXPORTER  value: none  - name: OTEL_EXPORTER_OTLP_ENDPOINT  value: http://open-telemetry-opentelemetry-collector.otel.svc.cluster.local:4317  - name: OTEL_EXPORTER_OTLP_COMPRESSION  value: gzip  - name: OTEL_EXPERIMENTAL_EXPORTER_OTLP_RETRY_ENABLED  value: "true"

它的运行规则是当我们的 Pod 在启动过程中会判断 Pod 的注解中是否开启了注入 OpenTelemetry 的配置。

如果开启则会将我们在 CRD 中自定义的镜像里的 javaagent 复制到业务容器中,同时会将下面的那些环境变量也一起加入的业务容器中。

要达到这样的效果就需要我们注册一个回调 endpoint。

mgr.GetWebhookServer().Register("/mutate-v1-pod", &webhook.Admission{  Handler: podmutation.NewWebhookHandler(cfg, ctrl.Log.WithName("pod-webhook"), decoder, mgr.GetClient(),  []podmutation.PodMutator{  sidecar.NewMutator(logger, cfg, mgr.GetClient()),  instrumentation.NewMutator(logger, mgr.GetClient(), mgr.GetEventRecorderFor("opentelemetry-operator"), cfg),  }),})

当 Pod 创建或有新的变更请求时就会回调我们的接口。

func (pm *instPodMutator) Mutate(ctx context.Context, ns corev1.Namespace, pod corev1.Pod) (corev1.Pod, error) {  logger := pm.Logger.WithValues("namespace", pod.Namespace, "name", pod.Name)}

在这个接口中我们就可以拿到 Pod 的信息,然后再获取 CRD Instrumentation 做我们的业务逻辑。

var otelInsts v1alpha1.InstrumentationList  
if err := pm.Client.List(ctx, &otelInsts, client.InNamespace(ns.Name)); err != nil {  return nil, err  
}// 从 CRD 中将数据复制到业务容器中。
pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{Name:      javaInitContainerName,Image:     javaSpec.Image,Command:   []string{"cp", "/javaagent.jar", javaInstrMountPath + "/javaagent.jar"},Resources: javaSpec.Resources,VolumeMounts: []corev1.VolumeMount{{Name:      javaVolumeName,MountPath: javaInstrMountPath,}},
})for i, extension := range javaSpec.Extensions {pod.Spec.InitContainers = append(pod.Spec.InitContainers, corev1.Container{Name:      initContainerName + fmt.Sprintf("-extension-%d", i),Image:     extension.Image,Command:   []string{"cp", "-r", extension.Dir + "/.", javaInstrMountPath + "/extensions"},Resources: javaSpec.Resources,VolumeMounts: []corev1.VolumeMount{{Name:      javaVolumeName,MountPath: javaInstrMountPath,}},})
}

不过需要注意的是想要在测试环境中测试 operator 是需要安装一个 cert-manage,这样 webhook 才能正常的回调。


要使得 CRD 生效,我们还得先将 CRD 安装进 kubernetes 集群中,不过这些 operator-sdk 这类根据已经考虑周到了。

我们只需要定义好 CRD 的结构体:

然后使用 Makefile 中的工具 make bundle 就会自动将结构体转换为 CRD。

参考链接:

  • https://github.com/VictoriaMetrics/operator
  • https://github.com/prometheus-operator/prometheus-operator

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/740391.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RAG工程实践拦路虎之一:PDF格式解析杂谈

背景 PDF(Portable Document Format)是一种广泛用于文档交换的文件格式,由Adobe Systems开发。它具有跨平台性、固定布局和易于打印等特点,因此在商业、学术和个人领域广泛应用。然而,PDF文件的解析一直是一个具有挑战性的问题,因为其内部结构的复杂性和多样性,使得提取…

PHP转Go系列 | ThinkPHP与Gin框架之API接口签名设计实践

数据安全一直是个热门的话题,API 接口在数据的传输上扮演着至关重要的角色。大家好,我是码农先森。 回想起以前用模版渲染数据的岁月,那时都没有 API 接口开发的概念。PHP 服务端和前端 HTML、CSS、JS 代码混合式开发,也不分前端、后端程序员,大家都是全干工程师。随着前后…

【一位资深用户的可视化工具推荐】智慧社区平台里的停车位如何协调?快来看看这款免费可视化工具

在智慧社区的管理中,停车位的协调是一个重要的难题,而山海鲸可视化这款免费可视化工具为解决这一问题提供了完美的解决方案。山海鲸可视化通过其强大的二三维融合功能,能够将二维面板与三维场景无缝结合,使停车位的管理变得更加直观和高效。无论是实时查看停车位的使用情况…

**CodeForces CF1928B Equalize题解**

ok兄弟们,今天本蒟蒻来做一篇小小的题解 Equalize 题面翻译 有一个给定的长度为 $n$ 的数列 $a$,现在加上一个排列 $b$,即 $c_i=a_i+b_i$。 现在求对于所有可能的 $b$,$c$ 中出现最多的数的出现次数的最大值。 translate by @UniGravity. 题目描述 Vasya has two hobbies —…

QT学习遇到的问题 乱码

孔夫子上买了一本二手的《QT 5.9 C++开发指南》, 从网站上下载了书中的代码, 在运行样例6.1过程中, 发现弹出的对话框中字符为乱码, 经过搜索, 找到了如下解决方法: 在头文件中添加了一行代码: #pragmaexecution_character_set("UTF-8")

微信小程序自动识别收货地址

为提升用户体验,在用户新增收货地址时,加入自动识别收货地址功能。.wxml <view class="top"><input type="text" placeholder="复制收货信息(格式:姓名→电话→地址)" value="{{distinguish}}"bindinput="distinguis…

性价比很高的多域名SSL证书:Buypass

在当今数字化快速发展的时代,网络安全已成为公众和企业关注的焦点。为了保障网站数据的安全传输,许多网站都采用了SSL证书来加密用户与服务器之间的通信。申请Buypass六个月免费SSL证书步骤 1、输入域名,注意由于Buypass不支持泛域名,请不要勾选泛域名。 2、选择加密方式,…

01、基础介绍

Kubernetes介绍和各组件盘点 01、K8S总览 Kubernetes(K8s),用于自动部署、扩容、缩容和管理容器化应用程序的开源系统。 它将组成应用程序的容器组合成逻辑单元,以便于管理和服务发现。 Kubernetes源自Google 15年生产环境的运维经验,同时凝聚了社区最佳创意和实践。 简单…

RAG知识库之多表示索引

在朴素RAG中通常会对文档、文本进行分块后进行文档嵌入,对所有文件、文本都没有经过采用Chunk方法可能有时候效果不是和好,尽管有着各种分块策略有针对大文件的、针对小文件的策略,但都难免可能会造成上下文语义丢失。分块通常有两个非常重要的参数chunk_size、chunk_overla…

Halcon学习笔记(3):WPF 框架搭建,MaterialDesign+Prism

目录前言环境Nuget安装新建WPF 类库项目初始化PrismApp启动页初始化重写MainView 前言 其实我更喜欢CommunityToolkit.mvvm+HandyControl。但是因为找工作,你不能去抗拒新事物。这里就当体验一下完整的流程好了。 环境windows 11 .net core 8.0Nuget安装新建WPF 类库项目新建项…

Halcon 学习笔记(2):Halcon+WPF导入

目录前言.net core 8.0.net core 8.0新功能,打开文件夹和打开文件HSmartWindowControlWPFSystem.Drawing.Common重置拉伸关闭拖拽和缩放文件导出 前言 这里补充一下Halcon导入到WPF的要求 .net core 8.0 Halcon是支持.net core 8.0导入的 .net core 8.0新功能,打开文件夹和打…

数据血缘系列(1)—— 为什么需要数据血缘?

大家好,我是独孤风。在当今数据驱动的商业环境中,数据治理成为企业成功的关键因素之一。本文我们详细探讨下为什么需要数据血缘,并说明数据血缘如何帮助企业解决关键问题,特别是在不同行业中的实际应用。 本文为《数据血缘分析原理与实践 》一书读书笔记,部分观点参考自书…