Operator 開發入門系列(一):Hello World

背景

我們公司最近計劃將產品遷移到 Kubernetes 環境。 為了更好地管理和自動化我們的應用程序,我們決定使用 Kubernetes Operator。 本系列博客將記錄我們學習和開發 Operator 的過程,希望能幫助更多的人入門 Operator 開發。

目標讀者

  • 對 Kubernetes 有一定了解的開發人員和運維人員
  • 希望使用 Operator 自動化管理應用程序的人員
  • 對 Go 語言有基本了解的人員

準備工作

在開始之前,你需要準備以下環境:

  • Go 語言環境 (>= 1.23): Operator 通常使用 Go 語言開發,你需要安裝 Go 語言環境。 建議使用 Go 1.21 或更高版本。 可以從 https://go.dev/dl/ 下載安裝包。 安裝完成后,請配置好 GOPATHPATH 環境變量。

  • Kubernetes 集群: 你需要一個可用的 Kubernetes 集群來部署和測試 Operator。 可以使用 Minikube、Kind 或其他的 Kubernetes 發行版。

  • kubectl 命令行工具: kubectl 是 Kubernetes 的命令行工具,用于與 Kubernetes 集群交互。 請確保你已經安裝并配置了 kubectl, 并且能夠連接到你的 Kubernetes 集群。

  • Kubebuilder (>= 3.0): Kubebuilder 是一個用于快速構建 Kubernetes Operator 的框架。 使用 Kubebuilder 可以簡化 Operator 的開發流程,并生成一些必要的代碼框架。 可以使用以下命令安裝 Kubebuilder:

cd $HOME/go/bin
curl -L -o kubebuilder "https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH)"
chmod +x kubebuilder

請確保 $HOME/go/bin 目錄在你的 PATH 環境變量中。 可以運行 kubebuilder version 命令來驗證 Kubebuilder 是否安裝成功。

  • Docker (可選): 如果你需要構建 Operator 的 Docker 鏡像,你需要安裝 Docker。

我的環境是 MacOS(arm64) + Orbstack

什么是 Operator?

簡單來說,Operator 是 Kubernetes 的擴展,它利用自定義資源(Custom Resources, CRs)來自動化管理應用程序。Operator 允許我們像管理 Kubernetes 內置資源一樣管理復雜的應用程序,例如數據庫、消息隊列等。

為什么選擇 Operator?

Operator 提供了一種聲明式的方式來管理應用程序的生命周期,包括部署、升級、備份、恢復等。它可以簡化運維流程,提高自動化程度,并確保應用程序的狀態符合預期。

我們的第一個 Operator:Hello World

這個 Operator 將監聽一個名為 HelloWorld 的自定義資源,并在 Kubernetes 中創建一個 Pod,該 Pod 運行一個簡單的 “Hello World” 應用程序。

1. 初始化 Kubebuilder 項目

首先,我們需要使用 Kubebuilder 創建一個新的項目。 在你的 GOPATH 目錄下創建一個新的目錄,例如 hello-world-operator,然后進入該目錄,運行以下命令

kubebuilder init --domain infini.cloud --repo github.com/infinilabs/hello-world-operator

這個命令會創建一個新的 Kubebuilder 項目,并生成一些必要的文件和目錄。

2. 創建自定義資源(Custom Resource Definition, CRD)

接下來,我們需要定義 HelloWorld 資源的結構。 運行以下命令

kubebuilder create api --group example --version v1alpha1 --kind HelloWorld

這個命令會創建一個新的 API 定義,包括 api/v1alpha1/helloworld_types.gocontrollers/helloworld_controller.go 兩個文件。

編輯 api/v1alpha1/helloworld_types.go 文件,修改 HelloWorldSpec 的定義,添加 namemessage 字段:

// HelloWorldSpec defines the desired state of HelloWorld
type HelloWorldSpec struct {// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster// Important: Run "make" to regenerate code after modifying this file// Name is the name of the HelloWorld resourceName string `json:"name,omitempty"`// Message is the message to be printed by the podMessage string `json:"message,omitempty"`
}

3. 實現 Reconcile 邏輯

編輯 controllers/helloworld_controller.go 文件,實現 Reconcile 函數, 創建一個 Pod,該 Pod 運行一個 busybox 鏡像,并輸出 HelloWorld 資源中定義的 message

package controllersimport ("context""fmt"corev1 "k8s.io/api/core/v1"apierrors "k8s.io/apimachinery/pkg/api/errors"metav1 "k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/apimachinery/pkg/runtime"ctrl "sigs.k8s.io/controller-runtime""sigs.k8s.io/controller-runtime/pkg/client""sigs.k8s.io/controller-runtime/pkg/log"examplev1alpha1 "github.com/infinilabs/hello-world-operator/api/v1alpha1"
)// HelloWorldReconciler reconciles a HelloWorld object
type HelloWorldReconciler struct {client.ClientScheme *runtime.Scheme
}//+kubebuilder:rbac:groups=example.com,resources=helloworlds,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=example.com,resources=helloworlds/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=example.com,resources=helloworlds/finalizers,verbs=update
//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.13.0/pkg/reconcile
func (r *HelloWorldReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {log := log.FromContext(ctx)// 1. Fetch the HelloWorld instancehelloWorld := &examplev1alpha1.HelloWorld{}err := r.Get(ctx, req.NamespacedName, helloWorld)if err != nil {if apierrors.IsNotFound(err) {// Object not found, return.  Created objects are automatically garbage collected.// For additional cleanup logic use finalizers.log.Info("HelloWorld resource not found. Ignoring since object must be deleted")return ctrl.Result{}, nil}// Error reading the object - requeue the request.log.Error(err, "Failed to get HelloWorld")return ctrl.Result{}, err}// 2. Define the desired Podpod := &corev1.Pod{ObjectMeta: metav1.ObjectMeta{Name:      helloWorld.Name + "-pod",Namespace: helloWorld.Namespace,Labels: map[string]string{"app": helloWorld.Name,},},Spec: corev1.PodSpec{Containers: []corev1.Container{{Name:  "hello-world",Image: "busybox",Command: []string{"sh", "-c", fmt.Sprintf("echo '%s' && sleep 3600", helloWorld.Spec.Message)},},},},}// 3. Set HelloWorld instance as the owner and controllerif err := ctrl.SetControllerReference(helloWorld, pod, r.Scheme); err != nil {log.Error(err, "Failed to set controller reference")return ctrl.Result{}, err}// 4. Check if the Pod already existsfound := &corev1.Pod{}err = r.Get(ctx, client.ObjectKey{Name: pod.Name, Namespace: pod.Namespace}, found)if err != nil && apierrors.IsNotFound(err) {log.Info("Creating a new Pod", "Pod.Namespace", pod.Namespace, "Pod.Name", pod.Name)err = r.Create(ctx, pod)if err != nil {log.Error(err, "Failed to create new Pod", "Pod.Namespace", pod.Namespace, "Pod.Name", pod.Name)return ctrl.Result{}, err}// Pod created successfully - return and requeuereturn ctrl.Result{Requeue: true}, nil} else if err != nil {log.Error(err, "Failed to get Pod")return ctrl.Result{}, err}// 5. Pod already exists - don't requeuelog.Info("Skip reconcile: Pod already exists", "Pod.Namespace", found.Namespace, "Pod.Name", found.Name)return ctrl.Result{}, nil
}// SetupWithManager sets up the controller with the Manager.
func (r *HelloWorldReconciler) SetupWithManager(mgr ctrl.Manager) error {return ctrl.NewControllerManagedBy(mgr).For(&examplev1alpha1.HelloWorld{}).Owns(&corev1.Pod{}).Complete(r)
}

4. 安裝 CRD 到 Kubernetes 集群

運行以下命令安裝 CRD 到 Kubernetes 集群:

make install

5. 運行 Operator

運行以下命令在本地運行 Operator:

make run

6. 創建 HelloWorld 資源

創建一個名為 my-hello-world.yaml 的文件,內容如下:

apiVersion: example.com/v1alpha1
kind: HelloWorld
metadata:name: my-hello-world
spec:name: my-hello-worldmessage: "Hello World from Operator!"

使用 kubectl apply -f my-hello-world.yaml 創建資源。

7. 驗證

使用 kubectl get pods 命令查看是否創建了名為 my-hello-world-pod 的 Pod。 使用 kubectl logs my-hello-world-pod 查看 Pod 的日志,確認是否輸出了 “Hello World from Operator!”。

總結

恭喜你完成了第一個 Operator! 雖然這個 Operator 非常簡單,但它展示了 Operator 的基本原理:監聽自定義資源,并根據資源的狀態來管理 Kubernetes 資源。 在接下來的系列中,我們將深入探討 Operator 的更多高級特性。

敬請期待下一篇博客!

作者:羅厚付,極限科技(INFINI Labs)云上產品設計與研發負責人,擁有多年安全風控及大數據系統架構經驗,主導過多個核心產品的設計與落地,日常負責運維超大規模 ES 集群(800+節點/1PB+數據)。
原文:https://infinilabs.cn/blog/2025/kubernetes-operator-develop-part-1/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/77244.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/77244.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/77244.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java基礎知識面試題(已整理Java面試寶典pdf版)

什么是Java Java是一門面向對象編程語言,不僅吸收了C語言的各種優點,還摒棄了C里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特征。Java語言作為靜態面向對象編程語言的代表,極好地實現了面向對象理論…

科學視角下的打坐:身心獲益的實證探究

在快節奏的現代生活中,人們在追求物質豐富的同時,也愈發關注身心的健康與平衡。古老的打坐修行方式,正逐漸走進科學研究的視野,并以大量實證數據展現出對人體多方面的積極影響。? 什么是打坐: 打坐是一種養生健身法…

javaSE————網絡編程套接字

網絡編程套接字~~~~~ 好久沒更新啦,藍橋杯爆掉了,從今天開始爆更嗷; 1,網絡編程基礎 為啥要有網絡編程呢,我們進行網絡通信就是為了獲取豐富的網絡資源,說實話真的很神奇,想想我們躺在床上&a…

MySQL性能調優(三):MySQL中的系統庫(mysql系統庫)

文章目錄 MySQL性能調優數據庫設計優化查詢優化配置參數調整硬件優化 MySQL中的系統庫1.5.Mysql中mysql系統庫1.5.1.權限系統表1.5.2.統計信息表1.5.2.1.innodb_table_stats1.5.2.2.innodb_index_stats 1.5.3.日志記錄表1.5.3.1. general_log1.5.3.2. slow_log 1.5.4.InnoDB中的…

多個路由器互通(靜態路由)無單臂路由(簡單版)

多個路由器互通(靜態路由)無單臂路由(簡單版) 開啟端口并配ip地址 維護1 Router>en Router#conf t Router(config)#int g0/0 Router(config-if)#no shutdown Router(config-if)#ip address 192.168.10.254 255.255.255.0 Ro…

關于 AI驅動的智慧家居、智慧城市、智慧交通、智慧醫療和智慧生活 的詳細解析,涵蓋其定義、核心技術、應用場景、典型案例及未來趨勢

以下是關于 AI驅動的智慧家居、智慧城市、智慧交通、智慧醫療和智慧生活 的詳細解析,涵蓋其定義、核心技術、應用場景、典型案例及未來趨勢: 一、AI智慧家居 1. 定義與核心功能 定義:通過AI與物聯網(IoT)技術&#…

【ESP32|音頻】一文讀懂WAV音頻文件格式【詳解】

簡介 最近在學習I2S音頻相關內容,無可避免會涉及到關于音頻格式的內容,所以剛開始接觸的時候有點一頭霧水,后面了解了下WAV相關內容,大致能夠看懂wav音頻格式是怎么樣的了。本文主要為后面ESP32 I2S音頻系列文章做鋪墊&#xff0…

端側大模型綜述On-Device Language Models: A Comprehensive Review

此為機器翻譯,僅做個人學習使用 設備端語言模型:全面回顧 DOI:10.48550/arXiv.2409.00088 1 摘要 大型語言模型 (LLM) 的出現徹底改變了自然語言處理應用程序,由于減少延遲、數據本地化和個性化用戶體驗…

推流265視頻,網頁如何支持顯示265的webrtc

科技發展真快,以前在網頁上(一般指谷歌瀏覽器),要顯示265的視頻流,都是很雞肋的辦法,要么轉碼,要么用很慢的hls,體驗非常不好,而今谷歌官方最新的瀏覽器已經支持265的web…

redis的sorted set的應用場景

Redis 的 Sorted Set(有序集合,簡稱 ZSet) 結合了 Set 的去重特性 和 按分數(score)排序 的特性,非常適合需要 高效排序 或 范圍查詢 的場景。以下是它的典型應用場景及示例: 實時排行榜 場景&…

18-21源碼剖析——Mybatis整體架構設計、核心組件調用關系、源碼環境搭建

學習視頻資料來源:https://www.bilibili.com/video/BV1R14y1W7yS 文章目錄 1. 架構設計2. 核心組件及調用關系3. 源碼環境搭建3.1 測試類3.2 實體類3.3 核心配置文件3.4 映射配置文件3.5 遇到的問題 1. 架構設計 Mybatis整體架構分為4層: 接口層&#…

未啟用CUDA支持的PyTorch環境** 中使用GPU加速解決方案

1. 錯誤原因分析 根本問題:當前安裝的PyTorch是CPU版本,無法調用GPU硬件加速。當運行以下代碼時會報錯:model YOLO("yolov8n.pt").to("cuda") # 或 .cuda()2. 解決方案步驟 步驟1:驗證CUDA可用性 在Pyth…

JVM-基于Hotspot

前言 Java虛擬機(Java Virtual Machine簡稱JVM)是運行所有Java程序的抽象計算機,是Java語言的運行環境,其主要任務為將字節碼裝載到內部,解釋/編譯為對應平臺上的機器指令執行。 Java虛擬機規范定義了一個抽象的——…

智能合約安全審計平臺——可視化智能合約漏洞掃描

目錄 可視化智能合約漏洞掃描 —— 理論、實踐與安全保障1. 引言2. 理論背景與漏洞原理2.1 智能合約簡介2.2 常見漏洞類型2.3 漏洞掃描與安全評估原理3. 系統架構與工作流程3.1 系統總體架構3.2 模塊說明4. 漏洞掃描流程詳解4.1 代碼上傳與靜態解析4.2 漏洞模式檢測4.3 風險評估…

【MySQL數據庫】數據類型詳解

目錄 數據類型tinyint類型(整形)bit類型小數浮點數 float、doubledecimal 字符串類型charvarcharchar與varchar的比較 日期時間類型enum和set總結 數據類型 tinyint類型(整形) 例: mysql> create table tt1(num tinyint);mysql> insert into tt1 values(1)…

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包

咪咕MG101_晨星MSO9380芯片_安卓5.1.1_免拆卡刷固件包(內有教程) 刷機教程簡單說明: 1、把下載好的刷機包,U盤里建立一個upgrade文件夾,固件放入此文件夾里,放入U盤中,注意升級包為壓縮包不要對…

CS61A:STRING REPRESENTATION

Python 規定所有對象都應該產生兩種不同的字符串表示形式:一種是人類可解釋的文本,另一種是 Python 可解釋的表達式。字符串的構造函數 str 返回一個人類可讀的字符串。在可能的情況下,repr 函數會返回一個計算結果相等的 Python 表達式。rep…

LangChain緩存嵌入技術完全指南:CacheBackedEmbedding原理與實踐(附代碼示例)

一、嵌入緩存技術背景與應用場景 1.1 為什么需要嵌入緩存? 算力消耗問題:現代嵌入模型(如text-embedding-3-small)單次推理需要約0.5-1秒/文本 資源浪費現狀:實際業務中約30%-60%的文本存在重復計算 成本壓力&#…

精益數據分析(3/126):用數據驅動企業發展的深度解析

精益數據分析(3/126):用數據驅動企業發展的深度解析 大家好!一直以來,我都堅信在當今競爭激烈的商業環境中,數據是企業獲得競爭優勢的關鍵。最近深入研究《精益數據分析》這本書,收獲頗豐&…

wpf ScaleTransform

在WPF中,ScaleTransform是用于實現元素縮放的核心類,屬于System.Windows.Media命名空間下的變換類型。以下是其主要特性與使用方式的總結: ?核心屬性? ?縮放比例? ScaleX:水平方向縮放比例(默認1.0,即…