news 2026/4/23 11:26:50

7.6 创建你的第一个Operator:从零开始的实战演练

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
7.6 创建你的第一个Operator:从零开始的实战演练

7.6 创建你的第一个Operator:从零开始的实战演练

在前面的课程中,我们学习了Operator的核心概念、架构设计和技术组件。现在,让我们通过实战演练,从零开始创建一个完整的Operator。通过这个实践过程,你将掌握Operator开发的完整流程,并能够独立开发自己的Operator。

环境准备

开发环境要求

在开始开发Operator之前,需要确保开发环境满足以下要求:

组件最低版本推荐版本说明
Go1.19+1.21+编译Operator代码
Kubernetes1.20+1.28+目标集群版本
kubectl1.20+1.28+集群管理工具
Docker20.10+24.0+构建镜像
Kubebuilder3.0+3.12+Operator开发框架
controller-gen0.13+0.14+代码生成工具

安装必要工具

# 安装Go语言环境(1.19+版本)wgethttps://go.dev/dl/go1.19.2.linux-amd64.tar.gzsudotar-C/usr/local-xzfgo1.19.2.linux-amd64.tar.gzexportPATH=$PATH:/usr/local/go/bin# 验证Go安装go version# 安装Kubebuilder(推荐方式)curl-L-okubebuilder https://go.kubebuilder.io/dl/latest/$(goenvGOOS)/$(goenvGOARCH)chmod+x kubebuildersudomvkubebuilder /usr/local/bin/# 或者安装Operator SDKcurl-LOhttps://github.com/operator-framework/operator-sdk/releases/download/v1.27.0/operator-sdk_linux_amd64chmod+x operator-sdk_linux_amd64sudomvoperator-sdk_linux_amd64 /usr/local/bin/operator-sdk# 安装kubectlcurl-LO"https://dl.k8s.io/release/$(curl-L-shttps://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"chmod+x kubectlsudomvkubectl /usr/local/bin/# 安装Dockersudoapt-getupdatesudoapt-getinstalldocker.io

准备Kubernetes集群

# 使用kind创建本地集群(用于开发测试)curl-Lo./kind https://kind.sigs.k8s.io/dl/v0.17.0/kind-linux-amd64chmod+x ./kindsudomv./kind /usr/local/bin/kind# 创建集群kind create cluster# 验证集群kubectl cluster-info kubectl get nodes

项目初始化

使用Kubebuilder初始化项目

# 创建项目目录mkdirvisitor-operatorcdvisitor-operator# 初始化项目kubebuilder init--domainexample.com--repogithub.com/example/visitor-operator# 创建APIkubebuilder create api--groupvisitor--versionv1--kindVisitorApp--resource--controller# 生成CRD和RBAC清单makemanifests

项目结构分析

生成的项目结构如下:

visitor-operator/ ├── api/ │ └── v1/ │ ├── groupversion_info.go │ ├── visitorapp_types.go │ └── zz_generated.deepcopy.go ├── config/ │ ├── crd/ │ │ ├── kustomization.yaml │ │ ├── bases/ │ │ └── patches/ │ ├── default/ │ ├── manager/ │ ├── rbac/ │ └── samples/ ├── controllers/ │ ├── suite_test.go │ └── visitorapp_controller.go ├── hack/ │ └── boilerplate.go.txt ├── Dockerfile ├── Makefile ├── PROJECT └── main.go

定义自定义资源

修改CRD定义

// api/v1/visitorapp_types.gopackagev1import(metav1"k8s.io/apimachinery/pkg/apis/meta/v1")// VisitorAppSpec defines the desired state of VisitorApptypeVisitorAppSpecstruct{// Replicas is the desired number of replicasReplicasint32`json:"replicas,omitempty"`// Image is the container image to useImagestring`json:"image,omitempty"`// Port is the container port to exposePortint32`json:"port,omitempty"`// VisitorMessage is the message to display to visitorsVisitorMessagestring`json:"visitorMessage,omitempty"`// Resources defines the resource requirementsResources Resources`json:"resources,omitempty"`}// Resources defines the resource requirements for the applicationtypeResourcesstruct{Requests ResourceList`json:"requests,omitempty"`Limits ResourceList`json:"limits,omitempty"`}// ResourceList defines a list of resourcestypeResourceListstruct{CPUstring`json:"cpu,omitempty"`Memorystring`json:"memory,omitempty"`}// VisitorAppStatus defines the observed state of VisitorApptypeVisitorAppStatusstruct{// Replicas is the number of actual replicasReplicasint32`json:"replicas"`// ReadyReplicas is the number of ready replicasReadyReplicasint32`json:"readyReplicas"`// Phase is the current phase of the applicationPhase VisitorAppPhase`json:"phase,omitempty"`// Conditions represent the latest available observations of an object's stateConditions[]metav1.Condition`json:"conditions,omitempty"`}// VisitorAppPhase is a label for the condition of a VisitorApp at the current timetypeVisitorAppPhasestringconst(// VisitorAppPhasePending means the VisitorApp is being createdVisitorAppPhasePending VisitorAppPhase="Pending"// VisitorAppPhaseRunning means the VisitorApp is runningVisitorAppPhaseRunning VisitorAppPhase="Running"// VisitorAppPhaseFailed means the VisitorApp has failedVisitorAppPhaseFailed VisitorAppPhase="Failed")//+kubebuilder:object:root=true//+kubebuilder:subresource:status//+kubebuilder:printcolumn:name="Replicas",type="integer",JSONPath=".spec.replicas"//+kubebuilder:printcolumn:name="Ready",type="integer",JSONPath=".status.readyReplicas"//+kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase"//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"// VisitorApp is the Schema for the visitorapps APItypeVisitorAppstruct{metav1.TypeMeta`json:",inline"`metav1.ObjectMeta`json:"metadata,omitempty"`Spec VisitorAppSpec`json:"spec,omitempty"`Status VisitorAppStatus`json:"status,omitempty"`}//+kubebuilder:object:root=true// VisitorAppList contains a list of VisitorApptypeVisitorAppListstruct{metav1.TypeMeta`json:",inline"`metav1.ListMeta`json:"metadata,omitempty"`Items[]VisitorApp`json:"items"`}funcinit(){SchemeBuilder.Register(&VisitorApp{},&VisitorAppList{})}

生成代码和清单

# 生成DeepCopy方法makegenerate# 生成CRD和RBAC清单makemanifests# 查看生成的CRDcatconfig/crd/bases/visitor.example.com_visitorapps.yaml

实现Controller逻辑

修改Controller实现

// controllers/visitorapp_controller.gopackagecontrollersimport("context""fmt""time"appsv1"k8s.io/api/apps/v1"corev1"k8s.io/api/core/v1""k8s.io/apimachinery/pkg/api/errors""k8s.io/apimachinery/pkg/api/resource"metav1"k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/apimachinery/pkg/runtime""k8s.io/apimachinery/pkg/types""k8s.io/apimachinery/pkg/util/intstr"ctrl"sigs.k8s.io/controller-runtime""sigs.k8s.io/controller-runtime/pkg/client""sigs.k8s.io/controller-runtime/pkg/controller/controllerutil""sigs.k8s.io/controller-runtime/pkg/log"visitorv1"github.com/example/visitor-operator/api/v1")// VisitorAppReconciler reconciles a VisitorApp objecttypeVisitorAppReconcilerstruct{client.Client Scheme*runtime.Scheme}//+kubebuilder:rbac:groups=visitor.example.com,resources=visitorapps,verbs=get;list;watch;create;update;patch;delete//+kubebuilder:rbac:groups=visitor.example.com,resources=visitorapps/status,verbs=get;update;patch//+kubebuilder:rbac:groups=visitor.example.com,resources=visitorapps/finalizers,verbs=update//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete//+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete//+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete//+kubebuilder:rbac:groups=core,resources=events,verbs=create;patch// Reconcile is part of the main kubernetes reconciliation loop which aims to// move the current state of the cluster closer to the desired state.func(r*VisitorAppReconciler)Reconcile(ctx context.Context,req ctrl.Request)(ctrl.Result,error){log:=log.FromContext(ctx)log.Info("Reconciling VisitorApp","VisitorApp",req.NamespacedName)// 获取VisitorApp实例visitorApp:=&visitorv1.VisitorApp{}iferr:=r.Get(ctx,req.NamespacedName,visitorApp);err!=nil{// 如果资源不存在,可能是被删除了returnctrl.Result{},client.IgnoreNotFound(err)}// 执行协调逻辑result,err:=r.reconcileVisitorApp(ctx,visitorApp)iferr!=nil{log.Error(err,"Failed to reconcile VisitorApp")returnresult,err}returnresult,nil}func(r*VisitorAppReconciler)reconcileVisitorApp(ctx context.Context,visitorApp*visitorv1.VisitorApp)(ctrl.Result,error){log:=log.FromContext(ctx)// 1. 确保ConfigMap存在iferr:=r.ensureConfigMap(ctx,visitorApp);err!=nil{returnctrl
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 11:28:46

空洞骑士模组管理器Scarab:让模组安装变得如此简单

空洞骑士模组管理器Scarab:让模组安装变得如此简单 【免费下载链接】Scarab An installer for Hollow Knight mods written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 还在为《空洞骑士》模组安装的复杂流程而烦恼吗?Sca…

作者头像 李华
网站建设 2026/4/23 14:45:19

RS-485通信接口设计:USB转485驱动电路全面讲解

从USB到工业总线:深入拆解USB转RS-485驱动电路设计在工厂车间的PLC控制柜里,在楼宇自控系统的传感器网络中,你总会看到一对红黑双绞线连接着多个设备——那是RS-485总线正在默默传输数据。而工程师手中的笔记本电脑没有串口,只能通…

作者头像 李华
网站建设 2026/4/20 0:23:11

Unity游戏全球化:智能自动翻译插件的创新解决方案

Unity游戏全球化:智能自动翻译插件的创新解决方案 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 在当今全球化的游戏市场中,Unity本地化已成为开发者必须面对的重要课题。传统的手…

作者头像 李华