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

🧰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

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

1cdd7d815f216c0223308038cebbd62d.png这里以 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-config
  namespace: my-namespace
  labels:
    prometheus: system-monitoring-prometheus
spec:
  staticConfigs:
    - labels:
        job: prometheus
      targets:
        - 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: 2
  vmstorage:
    replicaCount: 2
    storageDataPath: "/vm-data"
    storage:
      volumeClaimTemplate:
        spec:
          resources:
            requests:
              storage: "10Gi"
    resources:
      limits:
        cpu: "1"
        memory: "1Gi"
  vmselect:
    replicaCount: 2
    cacheMountPath: "/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 原理

78ddb8ade8e195145eb54915aef8ddc0.pngOperator 通常是运行在 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-order
  namespace: test  
spec:  
  env:  
    - name: OTEL_SERVICE_NAME  
      value: order
  selector:  
    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 才能正常的回调。

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

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

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

参考链接:

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

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

    往期推荐

    如何找到并快速上手一个开源项目

    OpenTelemetry 深度定制:跨服务追踪的实战技巧

    从 Prometheus 到 OpenTelemetry: 指标监控的演进与实践

    从 Dapper 到 OpenTelemetry:分布式追踪的演进之旅

    实操 OpenTelemetry:通过 Demo 掌握微服务监控的艺术

    ab8c94efd5579def0dba183d4ba2f9c4.gif

    点分享

    9b785d96af38ff71a2611c38331dd390.gif

    点收藏

    fb8ca8057dc45a8bdd311d75971abaae.gif

    点点赞

    5147ebc5cc405c49bb6638c7c0d7a4c8.gif

    点在看

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【系统架构设计】计算机组成与体系结构(二)

计算机组成与体系结构 计算机系统组成存储器系统前言主存储器存储器存储数量(计算) 辅助存储器(以磁盘为例)Cache存储器 流水线 计算机系统组成 存储器系统 前言 存储器用来存放程序和数据的部件,是一个记忆装置&am…

【网络安全的神秘世界】XSS基本概念和原理介绍

🌝博客主页:泥菩萨 💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 一、基本概念 恶意攻击者往web页面插入恶意代码脚本(JS代码),当用户浏览该页面时&#xf…

泛微开发修炼之旅--36通过js控制明细表中同一列中多个浏览框的显示控制逻辑(明细表列中多字段显示逻辑控制)

文章链接:36通过js控制明细表中同一列中多个浏览框的显示控制逻辑(明细表列中多字段显示逻辑控制)

0基础学会在亚马逊云科技AWS上搭建生成式AI云原生Serverless问答QA机器人(含代码和步骤)

小李哥今天带大家继续学习在国际主流云计算平台亚马逊云科技AWS上开发生成式AI软件应用方案。上一篇文章我们为大家介绍了,如何在亚马逊云科技上利用Amazon SageMaker搭建、部署和测试开源模型Llama 7B。下面我将会带大家探索如何搭建高扩展性、高可用的完全托管云原…

安防综合管理/视频汇聚平台EasyCVR视频监控存储技术:高效稳定的视频数据保障方案

随着科技的飞速发展,视频监控已成为现代社会不可或缺的一部分。无论是城市治安、交通管理,还是商业安保、家庭监控,视频监控都发挥着至关重要的作用。而在这背后,视频监控存储技术则是确保监控数据得以长期保存、高效检索和可靠利…

技术速递|VS Code Java 6月更新 - 项目设置功能增强!大量 Spring 新特性

作者:Nick Zhu 排版:Alan Wang 大家好,欢迎阅读 Visual Studio Code for Java 的六月更新!在这篇博客中,我们将分享项目设置项目的重要更新以及一系列 Spring 的功能改进,让我们开始吧! 项目设…

分布式锁(仅供自己参考)

分布式锁:满足分布式系统或集群式下多进程可见并且互斥的锁(使用外部的锁,因为如果是集群部署,每台服务器都有一个对应的tomcat,则每个tomcat的jvm就不同,锁对象就不同(加锁的机制,每…

(自用)共享单车服务器(二) 项目日志

stdin、stdout、stderr 注意&#xff1a;stderr是不缓存的&#xff0c;stdout则进行行间缓存。接下来我们看下行间缓存的效果&#xff0c;请参考以下代码&#xff1a; #include "stdio.h" #include <unistd.h>int main(int argc, char** argv) {for (int i 0…

万字长文MySQL Binlog 详细指南

目录 第一阶段 MySQL Binlog 基础用法1. Binlog基本概念1.1 什么是Binlog1.2 Binlog的作用1.3 Binlog格式 2. 配置和管理Binlog2.1 开启Binlog2.2 设置Binlog文件大小和保留时间2.3 查看Binlog状态 3. Binlog的实际应用3.1 数据恢复3.2 主从复制3.3 审计 4. Binlog工具使用4.1 …

吴恩达机器学习笔记2.1 - 什么是机器学习

吴恩达机器学习笔记2.1 - 什么是机器学习 最早的机器学习 1959年&#xff0c;亚瑟塞缪尔(Arthur Samuel)将机器学习定义为“Field of study that gives computers the ability to learn without being explicitly programmed”&#xff08;无需编程即可学习的研究领域&#xf…

谷粒商城 - 编写一个自定义校验注解

目录 开始 未来实现效果 第一步&#xff1a;编写自定义校验注解 第二步&#xff1a;编写自定义校验器 第三步&#xff1a;编写配置文件 效果演示 开始 未来实现效果 编写一个 ListValue 注解&#xff0c;可以实现功能有&#xff1a; 限定字段的值&#xff0c;例如指定只…

解读BASE理论:高可用性与性能的完美平衡

Base概念 BASE 理论是一种处理大规模分布式系统中的数据一致性问题的思路。相比于传统的严格一致性&#xff0c;它更灵活&#xff0c;适用于那些需要高可用性和性能的系统。BASE 理论由三个部分组成&#xff1a; 基本可用&#xff08;Basically Available&#xff09; 基本可用…

Unity通过NDK实现C#与C++之间的相互调用

由于一些历史遗留问题&#xff0c;我们项目还在使用一套C实现的Box2D定点数的库&#xff0c;由于最近修改了视野算法所以需要重新打包安卓的【.so】文件&#xff0c;特此记录 1、关于NDK 在Android平台&#xff0c;C/C需通过NDK编译成动态链接库.so文件&#xff0c;然后C#中通过…

天士力“数智本草”大模型如何赋能中药药品研发工作?

天士力“数智本草”大模型如何赋能中药药品研发工作&#xff1f; 目前&#xff0c;“数智本草”大模型如何配合天士力研发工作&#xff1f;对新药研发、中药二次开发等产生了什么价值&#xff1f;能否介绍一些具体的成果案例&#xff1f; “数智本草”大模型目前已经形成智能问…

免费下载工具 -- Free Download Manager(FDM) v6.24.0.5818

软件简介 Free Download Manager (FDM) 是一款免费的功能强大的下载管理软件&#xff0c;适用于多种操作系统&#xff0c;包括 Windows、macOS、Android 和 Linux。这款软件的特色在于它快速、安全且高效的下载能力。它可以下载各种热门网站的影片&#xff0c;支持 HTTP/HTTP…

【内网渗透】MSF渗透阶段的常用指令笔记

目录 渗透阶段划分 msfvenom 常用参数 各平台生成payload命令 Meterpreter Meterpreter的常用命令 基本命令 常用命令 针对安卓手机的一些命令 针对Windows的一些命令 文件系统命令 生成木马反弹shell(以linux靶机为例) 木马生成 配置监控 攻击利用 渗透阶段划分…

人工智能算法工程师(中级)课程2-Opencv视觉处理之高级操作

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程2-Opencv视觉处理之高级操作。在上一节课中的OpenCV基础操作我们了解到OpenCV是一个开源的计算机视觉软件库。它提供了各种视觉处理函数&#xff0c;并支持多种编程语言&#xff0c;如…

2-29 基于matlab的CEEMD

基于matlab的CEEMD&#xff08;Complementary Ensemble Empirical Mode Decomposition&#xff0c;互补集合经验模态分解&#xff09;&#xff0c;先将数据精心ceemd分解&#xff0c;得到imf分量&#xff0c;然后通过相关系数帅选分量&#xff0c;在求出他们的样本熵的特征。用…

HTML语言常见标签

语法 HEAD部分的HTML标签 1 标题标签 <title>标题内容</title> 2 段落标签 <meta charset"utf-8"/> BODY部分的HTML标签 1标题标签&#xff08;独占一行&#xff09;<h1>标题内容</h1> 2段落标签&#xff08;独占一行&#xff09;…

FUSE(用户空间文件系统)命令参数

GPT-4 (OpenAI) FUSE (Filesystem in Userspace)是一个允许创建用户空间文件系统的接口。它提供了一个API&#xff0c;让开发者在未修改内核代码的情况下&#xff0c;通过自己的程序实现文件系统。FUSE 文件系统通常通过 mount 命令来挂载&#xff0c;而且这个命令可以接受各…