ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

使用 Operator SDK 构建 Kubernetes Operator:核心概念、三种类型与从零实战

使用 Operator SDK 构建 Kubernetes Operator:核心概念、三种类型与从零实战 使用 Operator SDK 构建 Kubernetes Operator核心概念、三种类型与从零实战【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine本指南围绕 Kubernetes Operator 展开先讲清其本质——建立在控制器模式与自定义资源CRD之上的应用智能助手再梳理核心、社区、自定义三种类型及选型思路最后以 Operator SDK 为例从环境准备、项目初始化、API 类型与控制器编写到 CRD/RBAC 生成、集群内测试部署完整走通一个自定义 Operator 的开发闭环。读完你将掌握 Operator 的声明式调谐Reconcile原理并能独立创建一个可管理自定义资源的 Operator同时结合 refine 仓库中文档站的 Helm Chart 实例看到声明式期望状态在真实 Kubernetes 部署中的落地形态。理解 Kubernetes Operator什么是 Kubernetes Operator在云环境中管理复杂应用时我们常常面对大量需要持续升级、变更和监控的服务。人工维护这些永远处于期望状态的应用几乎不可能而 Kubernetes Operator 正是为此而生它像一个熟悉应用内部需求的智能管家把组件的安装、升级、修复、扩缩容等操作自动化是应用部署、伸缩与运维自动化的关键一环。从技术实现上讲Operator 是控制器Controller 自定义资源CRD的组合CRD 定义了一类新的资源及其期望状态控制器则持续观察集群中该资源的实际状态并不断把它调谐回期望状态。Reconcile调谐循环是控制器的核心入口每次资源发生变化控制器都会触发一次调谐逻辑。为什么要使用 OperatorOperator 提供的核心价值可以归纳为三点自动化生命周期管理自动管理应用与服务的部署、升级、回滚等完整生命周期自动化扩缩容与监控监控应用性能按实际负载自动调整实例数量匹配业务需求自动化维护执行备份、升级、故障修复持续保障集群内应用的高可用与性能。这些职责全部建立在使用声明式 Kubernetes API 的基础上——用户只描述想要什么状态Operator 负责把现实变成期望状态并将集群维持在用户指定的目标状态。下面是一段简化的 Operator 定义 YAML示意用于建立直觉apiVersion: operators.coreos.com/v1beta1 kind: Operator metadata: name: my-custom-operator spec: serviceName: my-app-service size: 3 version: 1.0.0这段配置定义了一个名为my-custom-operator的 Operator它管理目标服务my-app-service期望 3 个副本、版本为1.0.0。Operator 会在 Kubernetes 集群中持续监控并管理该服务的实际状态使其始终与这里的声明保持一致。需要说明的是这只是帮助理解的示意写法在实际开发中我们通过 Operator SDK 先定义CustomResourceDefinitionCRD再编写针对该 CRD 的控制器并通过kubectl apply提交 CRCustom Resource自定义资源实例来请求 Operator 执行任务下文实战部分会完整演示这一流程。Kubernetes Operator 的三种类型核心 OperatorCore Operators核心 Operator 内置于 Kubernetes 系统本身随集群默认提供负责最基础的资源编排能力。典型代表包括Deployment声明式管理无状态应用的副本数与滚动更新ReplicaSet保证指定数量的 Pod 副本始终运行DaemonSet确保每个或部分节点上都运行一个指定 Pod。它们适合承载日常的基础运维操作例如用 Deployment 滚动发布应用的新版本。社区 OperatorCommunity Operators社区 Operator 由 Kubernetes 社区创建和维护不属于核心组件但被广泛使用通常覆盖 Kubernetes 默认不提供的常用中间件与工具。典型代表包括Prometheus Operator用于监控 Kubernetes 集群与工作负载etcd Operator管理 etcd 集群的生命周期。当你的需求属于通用、常见范畴时优先在社区 Operator 中寻找现成方案。自定义 OperatorCustom Operators自定义 Operator 由用户按自身业务需求开发能够执行任何你配置给它的逻辑。典型场景是管理某种特殊数据库或复杂应用这些应用在升级、备份等操作时需要执行组织特有的处理流程。当核心 Operator 与社区 Operator 都无法覆盖你的独特需求时自定义 Operator 就是最佳选择——这也是本指南后续实战部分将要完成的事情。值得注意的是Kubernetes Operator 通常借助 Operator Framework 开发但并不强制你可以使用该框架提供的工具与工作流尤其是 Operator SDK显著简化开发过程也可以完全手工编写控制器。本指南采用 Operator Framework Operator SDK 的官方路径。声明式编排在 refine 仓库中的落地文档站 Helm Chart 剖析在深入动手之前先看一个仓库内真实存在的 Kubernetes 声明式管理实例帮助我们把期望状态从抽象概念映射到具体文件上。refine 文档站点本身就以 Helm Chart 形式声明式地部署在 Kubernetes 集群中相关文件位于 documentation/k8s/refine-documentation/其中 Chart.yaml 定义了图表元信息当前 chart 版本0.1.0、appVersion: 1.16.0。Deployment声明副本数的期望状态deployment.yaml 是 chart 中最能体现期望状态的模板当autoscaling.enabled为false时副本数直接取自 values.yaml 中的replicaCount: 1容器镜像来自ghcr.io/refinedev/refine/refine-documentation并通过imagePullSecrets指定拉取凭据name: github。模板还同时声明了存活探针livenessProbe与就绪探针readinessProbe均以 HTTP GET 方式探测根路径——这些探针正是控制器自动维护应用健康这一 Operator 理念在基础层级的体现探针失败时kubelet 与 Deployment 控制器会自动重启或重建 Pod。HPA按指标自动扩缩容hpa.yaml 展示了自动扩缩容的声明式配置HorizontalPodAutoscalerautoscaling/v2beta1当 values.yaml 中autoscaling.enabled为true时HPA 以 Deployment 为scaleTargetRef依据minReplicas默认 1、maxReplicas默认 100以及 CPU 目标利用率默认 80%自动调节副本数若配置了targetMemoryUtilizationPercentage内存指标也会被纳入。这正是前文所说监控性能、自动调整实例数量以匹配需求在真实清单中的具体实现。Service 与 Ingress暴露与路由service.yaml 声明了一个ClusterIP类型的 Service将流量路由到带有对应 selector 标签的 Pod 上values.yaml 中ingress.enabled: true并注入了一段 nginx 注解为/robots.txt返回禁止抓取的响应。此外 _helpers.tpl 中的命名模板把资源名截断到 63 个字符遵循 DNS 命名规范——这些细节说明一份声明式清单背后是由多个控制器Deployment、Service、HPA 控制器等协作维护的。这个例子可以清晰地印证Kubernetes 上一切资源都是声明期望状态控制器负责持续调谐实际状态。接下来我们就用 Operator SDK 亲手创建一个属于自己的控制器。实战使用 Operator SDK 构建第一个 Operator本实战的目标是创建一个名为AppService的自定义资源及其控制器CR 中声明期望的实例数量size控制器负责在集群中维护这些实例。开发流程为本地开发 → 生成清单 → 部署到集群本地 Minikube 或云集群。环境准备开始之前需要准备以下环境Go 语言1.13Operator SDK 生成的控制器基于 Go 编写请前往 Go 官方文档按平台安装对应版本Kubernetes 集群可使用 Minikube 本地集群或任意云厂商托管集群kubectl 命令行工具用于与集群交互必须已正确配置并指向目标集群kubectl config current-context可验证。说明以上环境要求与本文撰写时的 Operator SDK v1.17.0 对应使用更新版本时请以官方对应文档的版本要求为准。安装 Operator SDKOperator SDK 官方支持 Linux 与 macOSWindows 上官方二进制不支持需要先安装 WSL如 WSL Ubuntu再在 Linux 子系统中完成 SDK 与上述全部依赖的安装。原作者即是在 Windows 上通过 WSL/Ubuntu 完成本流程的。具体步骤如下1. 安装编译依赖在 WSL/Ubuntu 终端中执行sudo apt-get install make gcc g git2. 下载对应平台/架构的 Operator SDK 二进制Linux amd64 示例v1.17.0wget https://github.com/operator-framework/operator-sdk/releases/download/v1.17.0/operator-sdk_linux_amd643. 赋予可执行权限chmod x operator-sdk_linux_amd644. 移动到 PATH 目录常见位置/usr/local/bin/以便全局使用sudo mv operator-sdk_linux_amd64 /usr/local/bin/operator-sdk5. 验证安装operator-sdk version若输出 SDK 版本信息则安装成功。初始化 Operator 项目在本地工作目录中创建 Operator 项目operator-sdk init --domainmydomain.com --repogithub.com/myuser/my-operator两个关键参数的说明参数作用说明--domain为自定义资源定义CRD提供唯一组名不必是你真实拥有的域名只需遵循域名命名规范用于保证 CRD 全局唯一、避免与其他 CRD 冲突--repoGo 模块命名若代码不打算推送到远程仓库可填任意合法 URL 格式无需指向真实存在的仓库operator-sdk init会生成项目骨架包括go.mod、Makefile、PROJECT等文件Makefile中预置了generate、manifests、install、run等常用目标供后续步骤使用。创建 API 与控制器骨架在同一目录下执行operator-sdk create api --groupwebapp --versionv1 --kindAppService --resourcetrue --controllertrue--groupwebappCRD 的 API 组名最终与--domain组合成webapp.mydomain.com--versionv1API 版本--kindAppService资源类型名--resourcetrue --controllertrue同时生成资源类型定义与控制器骨架。执行后项目会自动生成api/与controllers/两个目录api/v1/存放AppService的类型定义与 schemacontrollers/存放调谐逻辑。开发你的 Operator第一步定义 API 类型编辑api/v1/目录下的类型文件如api/v1/appservice_types.go定义AppService的 spec 与 status 结构。完整示例package v1 import ( metav1 k8s.io/apimachinery/pkg/apis/meta/v1 ) // AppServiceSpec specifies the desired state of AppService type AppServiceSpec struct { //You can mention any instructions here related to your app Size int32 json:size } // Here AppServiceStatus specifies the observed state of AppService type AppServiceStatus struct { // Notet that the Nodes are actually the names of the AppService pods Nodes []string json:nodes } // The schema type AppService struct { metav1.TypeMeta json:,inline metav1.ObjectMeta json:metadata,omitempty Spec AppServiceSpec json:spec,omitempty Status AppServiceStatus json:status,omitempty } // AppServiceList is merely a list of AppService type AppServiceList struct { metav1.TypeMeta json:,inline metav1.ListMeta json:metadata,omitempty Items []AppService json:items } func init() { SchemeBuilder.Register(AppService{}, AppServiceList{}) }代码要点AppServiceSpec.Sizeint32JSON 字段size期望的实例数量即用户声明的目标状态AppServiceStatus.Nodes[]stringJSON 字段nodes观测到的实际状态存放当前运行实例Pod的名称列表AppService内嵌TypeMeta与ObjectMeta持有资源的类型元数据与名称、命名空间等对象元数据AppServiceList用于承载资源列表init()将类型注册进SchemeBuilder使控制器能识别并处理这类资源。Spec期望与 Status实际的分离正是声明式调谐的落点控制器读取 Spec 中的目标值对比 Status 中的当前值再执行动作拉近两者差距。第二步实现控制器逻辑编辑controllers/目录下生成的控制器文件如appservice_controller.go编写针对AppService的 CRUD 处理逻辑。核心实现package controllers import ( context appsv1 github.com/myuser/custom-operator/api/v1//your-api-path ctrl sigs.k8s.io/controller-runtime sigs.k8s.io/controller-runtime/pkg/log ) // Below AppServiceReconciler reconciles an AppService object type AppServiceReconciler struct { client.Client Scheme *runtime.Scheme } func (r *AppServiceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { _ context.Background() log : log.FromContext(ctx) // Get the AppService instance appService : appsv1.AppService{} err : r.Get(ctx, req.NamespacedName, appService) if err ! nil { log.Error(err, Failed to fetch AppService) return ctrl.Result{}, err } log.Info(Reconciling AppService, namespace, req.Namespace, name, req.Name) // Here you can put Business logic to handle AppService return ctrl.Result{}, nil } func (r *AppServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). For(appsv1.AppService{}). Complete(r) }代码要点AppServiceReconciler内嵌client.Client用于对集群资源执行 Get/List/Create/Update 等操作Reconcile是调谐循环的入口通过req.NamespacedName定位到具体AppService实例并读取读取失败时记录错误并返回控制器会据此决定是否重试成功则打印一条Reconciling AppService日志含 namespace 与 name。当前示例的业务逻辑为空你可以在这里实现创建 Deployment、更新副本数、写入 Status 等真实管理动作SetupWithManager将控制器注册进 ManagerFor(appsv1.AppService{})声明它监听AppService类型的变化任何 CR 的增删改都会触发Reconcile。提示真实 SDK 脚手架会自动补全Reconcile需要的全部导入如k8s.io/apimachinery/pkg/runtime等。若手写时遇到未定义的runtime.Scheme请在 import 中补充对应包这是保证代码可编译的关键细节。第三步生成 CRD 与 RBAC 清单在项目目录下依次执行make generate make manifestsmake generate根据 Go 源码中的注释标记markers生成/更新 DeepCopy 等代码make manifests基于源码中的 RBAC 与 CRD 标记生成/更新config/crd/下的 CRD 清单与config/rbac/下的 RBAC 规则。运行后config/目录会包含 CRD、RBAC、Manager 部署等完整清单供下一步部署使用。测试并部署你的 Operator开始前请确认kubectl已正确连接到目标集群。整个验证分四步1. 安装 CRD 到集群make install该命令会把上一步生成的 CRD 及必要依赖、配置与清单安装到集群中注册AppService这一新资源类型。2. 本地运行控制器make runmake run会在当前终端启动 Operator使其进入监听模式随时响应集群中AppService资源的变化。此命令会持续占用终端请保留该窗口用于观察日志。3. 提交自定义资源CR实例准备一个 CR 清单文件例如config/samples/webapp_v1_appservice.yamlapiVersion: webapp.mydomain.com/v1 kind: AppService metadata: name: example-appservice spec: size: 3 # Example size通过kubectl apply -f提交kubectl apply -f config/samples/webapp_v1_appservice.yaml这一步是告诉 Kubernetes 创建一种由你的 Operator 管理的资源apiVersion必须与create api时的--group/--domain组合一致webapp.mydomain.com/v1spec.size即声明的期望副本数。4. 验证调谐结果回到执行make run的终端窗口查看日志可看到控制器打印的调谐成功日志含 Reconciling AppService 及资源 namespace/name再用以下命令查看自定义资源的状态kubectl get appservices输出中应能看到example-appservice实例。至此你已经创建并部署了第一个 Kubernetes Operator。三大核心组件回顾Custom ResourceCR以简单配置描述资源的期望状态是用户与 Operator 之间的请求单Controller控制器实现基于 CR 期望状态管理资源的核心业务逻辑驱动调谐循环API类型定义定义自定义资源的结构与 schemaCRD保证提交的资源合法、符合约定。三者协同CR 描述要什么API 定义长什么样、控制器负责把它变成现实。结语Kubernetes Operator 代表了 Kubernetes 应用自动化管理的一次显著跃迁它不仅简化了服务与应用的生命周期管理还通过自动化调整与持续维护保障了高性能与可靠性。通过本文我们从概念、类型到 Operator SDK 实战完整走通了创建项目 → 定义 API → 编写控制器 → 生成清单 → 集群部署与验证的全流程同时借助 refine 仓库中 documentation/k8s/refine-documentation/ 的 Helm Chart 实例直观看到了 Deployment、HPA 等核心控制器如何以声明式方式维护一个真实应用的期望状态。沿用同样的方法你完全可以为自身业务开发生产可用的 Operator——无论是核心、社区还是自定义类型每一个都在 Kubernetes 生态中扮演着不可替代的角色是云原生技术栈中不可或缺的利器。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表