日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用kuberbuilder创建工程示例

發(fā)布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用kuberbuilder创建工程示例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文連接:https://blog.csdn.net/u012986012/article/details/119710511

kubebuilder是一個官方提供快速實(shí)現(xiàn)Operator的工具包,可快速生成k8s的CRD、Controller、Webhook,用戶只需要實(shí)現(xiàn)業(yè)務(wù)邏輯。

類似工具還有operader-sdk,目前正在與Kubebuilder融合

kubebuilder封裝了controller-runtime與controller-tools,通過controller-gen來生產(chǎn)代碼,簡化了用戶創(chuàng)建Operator的步驟。

一般創(chuàng)建Operator流程如下:

  • 創(chuàng)建工作目錄,初始化項(xiàng)目
  • 創(chuàng)建API,填充字段
  • 創(chuàng)建Controller,編寫核心協(xié)調(diào)邏輯(Reconcile)
  • 創(chuàng)建Webhook,實(shí)現(xiàn)接口,可選
  • 驗(yàn)證測試
  • 發(fā)布到集群中
  • 示例

    我們準(zhǔn)備創(chuàng)建一個2048的游戲,對外可以提供服務(wù),也能方便地?cái)U(kuò)縮容。

    準(zhǔn)備環(huán)境

    首先你需要有Kubernetes、Docker、Golang相關(guān)環(huán)境。
    Linux下安裝kubebuilder

    curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/$(go env GOOS)/$(go env GOARCH) chmod +x kubebuilder && mv kubebuilder /usr/local/bin/

      Create Resource [y/n]
      y #生成CR
      Create Controller [y/n]
      y #生成Controller

      目錄結(jié)構(gòu)如下:

      ├── api │ └── v1 # CRD定義 ├── bin │ └── controller-gen ├── config │ ├── crd # crd配置 │ ├── default │ ├── manager # operator部署文件 │ ├── prometheus │ ├── rbac │ └── samples # cr示例 ├── controllers │ ├── game_controller.go # controller邏輯 │ └── suite_test.go ├── Dockerfile ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt # 頭文件模板 ├── main.go # 項(xiàng)目主函數(shù) ├── Makefile └── PROJECT #項(xiàng)目元數(shù)據(jù)

      編寫API

      在mygame/api/v1/game_types.go定義我們需要的字段

      Spec配置如下

      type GameSpec struct {// Number of desired pods. This is a pointer to distinguish between explicit// zero and not specified. Defaults to 1.// +optional//+kubebuilder:default:=1 //+kubebuilder:validation:Minimum:=1Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`// Docker image name// +optionalImage string `json:"image,omitempty"`// Ingress Host nameHost string `json:"host,omitempty"` }

      kubebuilder:default可以設(shè)置默認(rèn)值

      Status定義如下

      const (Running = "Running"Pending = "Pending"NotReady = "NotReady"Failed = "Failed" ) type GameStatus struct {// Phase is the phase of guestbookPhase string `json:"phase,omitempty"`// replicas is the number of Pods created by the StatefulSet controller.Replicas int32 `json:"replicas"`// readyReplicas is the number of Pods created by the StatefulSet controller that have a Ready Condition.ReadyReplicas int32 `json:"readyReplicas"`// LabelSelector is label selectors for query over pods that should match the replica count used by HPA.LabelSelector string `json:"labelSelector,omitempty"` }

      另外需要添加scale接口

      //+kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.replicas,selectorpath=.status.labelSelector

        編寫Controller邏輯

        Controller的核心邏輯在Reconcile中,我們只需要填充自己的業(yè)務(wù)邏輯

        func (r *GameReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {logger := log.FromContext(ctx)logger.Info("revice reconcile event", "name", req.String())// 獲取game對象game := &myappv1.Game{}if err := r.Get(ctx, req.NamespacedName, game); err != nil {return ctrl.Result{}, client.IgnoreNotFound(err)}// 如果處在刪除中直接跳過if game.DeletionTimestamp != nil {logger.Info("game in deleting", "name", req.String())return ctrl.Result{}, nil}// 同步資源,如果資源不存在創(chuàng)建deployment、ingress、service,并更新statusif err := r.syncGame(ctx, game); err != nil {logger.Error(err, "failed to sync game", "name", req.String())return ctrl.Result{}, nil}return ctrl.Result{}, nil }

        添加rbac配置

        //+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=apps,resources=deployments/status,verbs=get;update;patch //+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=networking,resources=ingresses,verbs=get;list;watch;create;update;patch;delete

        具體syncGame邏輯如下

        func (r *GameReconciler) syncGame(ctx context.Context, obj *myappv1.Game) error {logger := log.FromContext(ctx)game := obj.DeepCopy()name := types.NamespacedName{Namespace: game.Namespace,Name: game.Name,}// 構(gòu)造ownerowner := []metav1.OwnerReference{{APIVersion: game.APIVersion,Kind: game.Kind,Name: game.Name,Controller: pointer.BoolPtr(true),BlockOwnerDeletion: pointer.BoolPtr(true),UID: game.UID,},}labels := game.Labelslabels[gameLabelName] = game.Namemeta := metav1.ObjectMeta{Name: game.Name,Namespace: game.Namespace,Labels: labels,OwnerReferences: owner,}// 獲取對應(yīng)deployment, 如不存在則創(chuàng)建deploy := &appsv1.Deployment{}if err := r.Get(ctx, name, deploy); err != nil {if !errors.IsNotFound(err) {return err}deploy = &appsv1.Deployment{ObjectMeta: meta,Spec: getDeploymentSpec(game, labels),}if err := r.Create(ctx, deploy); err != nil {return err}logger.Info("create deployment success", "name", name.String())} else {// 如果存在對比和game生成的deployment是否一致,不一致則更新want := getDeploymentSpec(game, labels)get := getSpecFromDeployment(deploy)if !reflect.DeepEqual(want, get) {deploy = &appsv1.Deployment{ObjectMeta: meta,Spec: want,}if err := r.Update(ctx, deploy); err != nil {return err}logger.Info("update deployment success", "name", name.String())}}//service創(chuàng)建svc := &corev1.Service{}if err := r.Get(ctx, name, svc); err != nil {...}// ingress創(chuàng)建ing := &networkingv1.Ingress{}if err := r.Get(ctx, name, ing); err != nil {...}newStatus := myappv1.GameStatus{Replicas: *game.Spec.Replicas,ReadyReplicas: deploy.Status.ReadyReplicas,}if newStatus.Replicas == newStatus.ReadyReplicas {newStatus.Phase = myappv1.Running} else {newStatus.Phase = myappv1.NotReady}// 更新狀態(tài)if !reflect.DeepEqual(game.Status, newStatus) {game.Status = newStatuslogger.Info("update game status", "name", name.String())return r.Client.Status().Update(ctx, game)}return nil }

        默認(rèn)情況下生成的controller只監(jiān)聽自定義資源,在示例中我們也需要監(jiān)聽game的子資源,如監(jiān)聽deployment是否符合預(yù)期

        // SetupWithManager sets up the controller with the Manager. func (r *GameReconciler) SetupWithManager(mgr ctrl.Manager) error {// 創(chuàng)建controllerc, err := controller.New("game-controller", mgr, controller.Options{Reconciler: r,MaxConcurrentReconciles: 3, //controller運(yùn)行的worker數(shù)})if err != nil {return err}//監(jiān)聽自定義資源if err := c.Watch(&source.Kind{Type: &myappv1.Game{}}, &handler.EnqueueRequestForObject{}); err != nil {return err}//監(jiān)聽deployment,將owner信息即game namespace/name添加到隊(duì)列if err := c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{OwnerType: &myappv1.Game{},IsController: true,}); err != nil {return err}return nil }

        部署驗(yàn)證

        安裝CRD

        make install

          # 查看deploy
          kubectl get deploy game-sample
          NAME READY UP-TO-DATE AVAILABLE AGE
          game-sample 1/1 1 1 6m

          # 查看ingress
          kubectl get ing game-sample
          NAME CLASS HOSTS ADDRESS PORTS AGE
          game-sample <none> mygame.io 192.168.49.2 80 7m

          驗(yàn)證應(yīng)用,在/etc/host中添加<Ingress ADDRESS Ip> mygame.io,訪問瀏覽器如下圖所示

          驗(yàn)證擴(kuò)容

          kubectl scale games.myapp.qingwave.github.io game-sample --replicas 2 game.myapp.qingwave.github.io/game-sample scaled

          # 擴(kuò)容后
          kubectl get games.myapp.qingwave.github.io
          NAME PHASE HOST DESIRED CURRENT READY AGE
          game-sample Running mygame.io 2 2 2 7m

            同樣的通過ValidateCreate、ValidateUpdate可實(shí)現(xiàn)validating webhook

            func (r *Game) ValidateCreate() error {gamelog.Info("validate create", "name", r.Name)// Host不能包括通配符if strings.Contains(r.Spec.Host, "*") {return errors.New("host should not contain *")}return nil }

            本地驗(yàn)證webhook需要配置證書,在集群中測試更方便點(diǎn),可參考官方文檔。

            總結(jié)

            至此,我們已經(jīng)實(shí)現(xiàn)了一個功能完全的game-operator,可以管理game資源的生命周期,創(chuàng)建/更新game時會自動創(chuàng)建deployment、service、ingress等資源,當(dāng)deployment被誤刪或者誤修改時也可以自動回復(fù)到期望狀態(tài),也實(shí)現(xiàn)了scale接口。

            通過kubebuiler大大簡化了開發(fā)operator的成本,我們只需要關(guān)心業(yè)務(wù)邏輯即可,不需要再手動去創(chuàng)建client/controller等,但同時kubebuilder生成的代碼中屏蔽了很多細(xì)節(jié),比如controller的最大worker數(shù)、同步時間、隊(duì)列類型等參數(shù)設(shè)置,只有了解operator的原理才更好應(yīng)用于生產(chǎn)。

            引用

            [1] https://book.kubebuilder.io/

            總結(jié)

            以上是生活随笔為你收集整理的使用kuberbuilder创建工程示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

            如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

            主站蜘蛛池模板: 999xxxxx| 国产一区久久 | 成人公开视频 | 日本a视频在线观看 | 免费黄色a| 中国zzji女人高潮免费 | 国产永久av| 日韩一区二区三区在线观看视频 | 久草久热 | 少妇一级1淫片 | 玖玖免费 | 亚洲一区激情 | 四虎影成人精品a片 | 伊人超碰 | 亚洲精品一区二 | 波多野结衣99 | 91精品国产色综合久久不卡电影 | 五月婷婷视频在线观看 | 色婷婷综合视频 | 中文字幕一区二区三区免费 | 五月天激情社区 | 成人私密视频 | 欧美射射 | 日本不卡一区视频 | 久久影院国产 | 亚洲精品自拍偷拍 | 国产精品视频h | 污漫网站 | 极品久久 | 国产在线一卡二卡 | 亚洲高清二区 | 苏晴忘穿内裤坐公交车被揉到视频 | 欧美亚洲另类在线 | 熟女少妇一区二区三区 | 一本加勒比北条麻妃 | 成人性生交大片免费看vrv66 | 谁有毛片网站 | 久久97久久97精品免视看 | 怡红院男人的天堂 | 亚洲国产精品成人无久久精品 | 精品人妻二区中文字幕 | 葵司免费一区二区三区四区五区 | 蜜桃av网站 | 免费日本黄色片 | 成人福利影院 | 幸福宝在线观看 | 男女黄网站 | 99re在线观看视频 | 欧美高跟鞋交xxxxxhd | 日韩视频播放 | 影音先锋久久 | 欧美影院久久 | 亚洲自拍偷拍一区二区 | 干b视频在线观看 | 国产精品一二区在线观看 | 激情小说专区 | www黄色在线观看 | 伊人黄网| 私拍在线| 午夜免费高清视频 | 91老肥熟 | 国产天堂av在线 | 亚洲综合自拍 | 男女操操 | 999久久久精品视频 亚洲视频精品在线 | 国产精品二区三区 | 欧美成人a∨高清免费观看 国产精品999视频 | 黄色aa毛片| 五月天六月色 | 亚洲三级图片 | 蜜桃传媒一区二区亚洲 | 亚欧中文字幕 | 日日碰碰 | 黑人高潮一区二区三区在线看 | 香港三级网站 | 国产精品99久久久久久久久 | 成年女人色毛片 | 澳门黄色录像 | 一区二区美女 | 牛牛在线| 五月婷婷综合激情网 | 肥臀浪妇太爽了快点再快点 | 国产精品久久久久久吹潮 | xxxxx亚洲| 日韩av电影在线播放 | 国产成人av在线 | 秋霞毛片少妇激情免费 | 国产96视频 | 91蝌蚪少妇 | 久久久久人妻精品一区二区三区 | 国产新婚疯狂做爰视频 | 日本打屁股网站 | 久久亚洲AV无码专区成人国产 | 手机av网站 | 亚洲天堂一区二区 | 性按摩玩人妻hd中文字幕 | 国产精品爱啪在线线免费观看 | 色综合综合网 | 芒果视频污污 |