成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇帶你kubebuilder 實戰: status & event

開發 項目管理
想知道一個節點池有多少的節點,現在的資源占比是多少,這樣可以清晰的知道我們現在的水位線是多少,除此之外也想知道節點池數量發生變化的相關事件信息,什么時候節點池增加或者是減少了一個節點等。

[[399605]]

在上篇文章當中我們實現了 NodePool Operator 基本的 CURD 功能,跑了一小段時間之后除了 CURD 之外我們有了更高的需求,想知道一個節點池有多少的節點,現在的資源占比是多少,這樣可以清晰的知道我們現在的水位線是多少,除此之外也想知道節點池數量發生變化的相關事件信息,什么時候節點池增加或者是減少了一個節點等。

需求

我們先整理一下需求

能夠通過 kubectl get Nodepool了解當前的節點池的以下信息

  • 節點池的狀態,是否異常
  • 節點池現在包含多少個節點
  • 節點池的資源情況現在有多少 CPU、Memory

能夠通過事件信息得知 controller 的錯誤情況以及節點池內節點的變化情況

實現

Status

先修改一下 status 對象,注意要確保下面的 //+kubebuilder:subresource:status注釋存在,這個表示開啟 status 子資源,status 對象修改好之后需要重新執行一遍 make install

  1. // NodePoolStatus defines the observed state of NodePool 
  2. type NodePoolStatus struct { 
  3.  // status=200 說明正常,其他情況為異常情況 
  4.  Status int `json:"status"
  5.  
  6.  // 節點的數量 
  7.  NodeCount int `json:"nodeCount"
  8.  
  9.  // 允許被調度的容量 
  10.  Allocatable corev1.ResourceList `json:"allocatable,omitempty" protobuf:"bytes,2,rep,name=allocatable,casttype=ResourceList,castkey=ResourceName"
  11.  
  12. //+kubebuilder:object:root=true 
  13. //+kubebuilder:resource:scope=Cluster 
  14. //+kubebuilder:subresource:status 
  15.  
  16. // NodePool is the Schema for the nodepools API 
  17. type NodePool struct { 

然后修改 Reconcile 中的邏輯

  1. func (r *NodePoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { 
  2.  // ...... 
  3.  
  4.  if len(nodes.Items) > 0 { 
  5.   r.Log.Info("find nodes, will merge data""nodes", len(nodes.Items)) 
  6. +  pool.Status.Allocatable = corev1.ResourceList{} 
  7. +  pool.Status.NodeCount = len(nodes.Items) 
  8.   for _, n := range nodes.Items { 
  9.    n := n 
  10.  
  11.    // 更新節點的標簽和污點信息 
  12.    err := r.Update(ctx, pool.Spec.ApplyNode(n)) 
  13.    if err != nil { 
  14.     return ctrl.Result{}, err 
  15.    } 
  16.  
  17. +   for name, quantity := range n.Status.Allocatable { 
  18. +    q, ok := pool.Status.Allocatable[name
  19. +    if ok { 
  20. +     q.Add(quantity) 
  21. +     pool.Status.Allocatable[name] = q 
  22. +     continue 
  23. +    } 
  24. +    pool.Status.Allocatable[name] = quantity 
  25. +   } 
  26.   } 
  27.  } 
  28.  
  29.   // ...... 
  30.    
  31. + pool.Status.Status = 200 
  32. + err = r.Status().Update(ctx, pool) 
  33.  return ctrl.Result{}, err 

修改好了之后我們提交一個 NodePool 測試一下

  1. apiVersion: nodes.lailin.xyz/v1 
  2. kind: NodePool 
  3. metadata: 
  4.   name: worker 
  5. spec: 
  6.   taints: 
  7.     - key: node-pool.lailin.xyz 
  8.       value: worker 
  9.       effect: NoSchedule 
  10.   labels: 
  11.     "node-pool.lailin.xyz/worker""10" 
  12.   handler: runc 

可以看到我們現在是有兩個 worker 節點

  1. ▶ kubectl get no  
  2. NAME                 STATUS   ROLES                  AGE   VERSION 
  3. kind-control-plane   Ready    control-plane,master   29m   v1.20.2 
  4. kind-worker          Ready    worker                 28m   v1.20.2 
  5. kind-worker2         Ready    worker                 28m   v1.20.2 

 然后我們看看 NodePool,可以發現已經存在了預期的 status

  1. status: 
  2.   allocatable: 
  3.     cpu: "8" 
  4.     ephemeral-storage: 184026512Ki 
  5.     hugepages-1Gi: "0" 
  6.     hugepages-2Mi: "0" 
  7.     memory: 6129040Ki 
  8.     pods: "220" 
  9.   nodeCount: 2 
  10.   status: 200 

現在這樣只能通過查看 yaml 詳情才能看到,當 NodePool 稍微多一些的時候就不太方便,我們現在給NodePool 增加一些 kubectl 展示的列

  1. +//+kubebuilder:printcolumn:JSONPath=".status.status",name=Status,type=integer 
  2. +//+kubebuilder:printcolumn:JSONPath=".status.nodeCount",name=NodeCount,type=integer 
  3. //+kubebuilder:object:root=true 
  4. //+kubebuilder:resource:scope=Cluster 
  5. //+kubebuilder:subresource:status 

如上所示只需要添加好對應的注釋,然后執行 make install即可

然后再執行 kubectl get NodePool 就可以看到對應的列了

  1. ▶ kubectl get NodePool  
  2. NAME     STATUS   NODECOUNT 
  3. worker   200      2 

Event

我們在 controller 當中添加 Recorder 用來記錄事件,K8s 中事件有 Normal 和 Warning 兩種類型

  1. // NodePoolReconciler reconciles a NodePool object 
  2. type NodePoolReconciler struct { 
  3.  client.Client 
  4.  Log      logr.Logger 
  5.  Scheme   *runtime.Scheme 
  6. + Recorder record.EventRecorder 
  7.  
  8. func (r *NodePoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { 
  9.   
  10. + // 添加測試事件 
  11. + r.Recorder.Event(pool, corev1.EventTypeNormal, "test""test"
  12.  
  13.  pool.Status.Status = 200 
  14.  err = r.Status().Update(ctx, pool) 
  15.  return ctrl.Result{}, err 

添加好之后還需要在 main.go 中加上 Recorder的初始化邏輯

  1. if err = (&controllers.NodePoolReconciler{ 
  2.   Client:   mgr.GetClient(), 
  3.   Log:      ctrl.Log.WithName("controllers").WithName("NodePool"), 
  4.   Scheme:   mgr.GetScheme(), 
  5. +  Recorder: mgr.GetEventRecorderFor("NodePool"), 
  6.  }).SetupWithManager(mgr); err != nil { 
  7.   setupLog.Error(err, "unable to create controller""controller""NodePool"
  8.   os.Exit(1) 
  9.  } 

加好之后我們運行一下,然后在 describe Nodepool 對象就能看到事件信息了

  1. Events: 
  2.   Type    Reason  Age   From      Message 
  3.   ----    ------  ----  ----      ------- 
  4.   Normal  test    4s    NodePool  test 

監聽更多資源

之前我們所有的代碼都是圍繞著 NodePool 的變化來展開的,但是我們如果修改了 Node 的相關標簽,將 Node 添加到一個 NodePool,Node 上對應的屬性和 NodePool 的 status 信息也不會改變。如果我們想要實現上面的效果就需要監聽更多的資源變化。

在 controller 當中我們可以看到一個 SetupWithManager方法,這個方法說明了我們需要監聽哪些資源的變化

  1. // SetupWithManager sets up the controller with the Manager. 
  2. func (r *NodePoolReconciler) SetupWithManager(mgr ctrl.Manager) error { 
  3.  return ctrl.NewControllerManagedBy(mgr). 
  4.   For(&nodesv1.NodePool{}). 
  5.   Complete(r) 

其中 NewControllerManagedBy是一個建造者模式,返回的是一個 builder 對象,其包含了用于構建的 For、Owns、Watches、WithEventFilter等方法

這里我們就可以利用 ``Watches方法來監聽 Node 的變化,我們這里使用handler.Funcs`自定義了一個入隊器

監聽 Node 對象的更新事件,如果存在和 NodePool 關聯的 node 對象更新就把對應的 NodePool 入隊

  1. // SetupWithManager sets up the controller with the Manager. 
  2. func (r *NodePoolReconciler) SetupWithManager(mgr ctrl.Manager) error { 
  3.  return ctrl.NewControllerManagedBy(mgr). 
  4.   For(&nodesv1.NodePool{}). 
  5.   Watches(&source.Kind{Type: &corev1.Node{}}, handler.Funcs{UpdateFunc: r.nodeUpdateHandler}). 
  6.   Complete(r) 
  7.  
  8. func (r *NodePoolReconciler) nodeUpdateHandler(e event.UpdateEvent, q workqueue.RateLimitingInterface) { 
  9.  ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second
  10.  defer cancel() 
  11.  
  12.  oldPool, err := r.getNodePoolByLabels(ctx, e.ObjectOld.GetLabels()) 
  13.  if err != nil { 
  14.   r.Log.Error(err, "get node pool err"
  15.  } 
  16.  if oldPool != nil { 
  17.   q.Add(reconcile.Request{ 
  18.    NamespacedName: types.NamespacedName{Name: oldPool.Name}, 
  19.   }) 
  20.  } 
  21.  
  22.  newPool, err := r.getNodePoolByLabels(ctx, e.ObjectOld.GetLabels()) 
  23.  if err != nil { 
  24.   r.Log.Error(err, "get node pool err"
  25.  } 
  26.  if newPool != nil { 
  27.   q.Add(reconcile.Request{ 
  28.    NamespacedName: types.NamespacedName{Name: newPool.Name}, 
  29.   }) 
  30.  } 
  31.  
  32. func (r *NodePoolReconciler) getNodePoolByLabels(ctx context.Context, labels map[string]string) (*nodesv1.NodePool, error) { 
  33.  pool := &nodesv1.NodePool{} 
  34.  for k := range labels { 
  35.   ss := strings.Split(k, "node-role.kubernetes.io/"
  36.   if len(ss) != 2 { 
  37.    continue 
  38.   } 
  39.   err := r.Client.Get(ctx, types.NamespacedName{Name: ss[1]}, pool) 
  40.   if err == nil { 
  41.    return pool, nil 
  42.   } 
  43.  
  44.   if client.IgnoreNotFound(err) != nil { 
  45.    return nil, err 
  46.   } 
  47.  } 
  48.  return nil, nil 

總結

今天我們完善了 status & event 和自定義對象 watch 下一篇我們看一下如何對我們的 Operator 進行測試

 

責任編輯:姜華 來源: mohuishou
相關推薦

2021-05-12 06:18:19

KubeBuilderOperatork8s

2021-05-17 05:51:31

KubeBuilderOperator測試

2021-05-18 05:40:27

kubebuilderwebhook進階

2021-05-08 09:02:48

KubeBuilderOperatork8s

2023-04-20 08:00:00

ES搜索引擎MySQL

2021-05-20 06:57:16

RabbitMQ開源消息

2021-06-16 08:28:25

unary 方法函數技術

2022-02-24 07:56:42

開發Viteesbuild

2025-01-17 07:00:00

2022-03-10 08:31:51

REST接口規范設計Restful架構

2022-02-21 09:44:45

Git開源分布式

2023-05-12 08:19:12

Netty程序框架

2021-07-28 10:02:54

建造者模式代碼

2021-07-14 08:24:23

TCPIP 通信協議

2021-08-11 07:02:21

npm包管理器工具

2021-06-30 00:20:12

Hangfire.NET平臺

2022-04-08 08:32:40

mobx狀態管理庫redux

2020-11-27 08:02:41

Promise

2023-02-28 23:04:15

2021-11-24 08:51:32

Node.js監聽函數
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美精品一区在线发布 | 欧美专区在线视频 | 亚洲精品视频一区 | 日韩精品在线播放 | 女同久久另类99精品国产 | 99精品久久久国产一区二区三 | 亚洲午夜精品视频 | 噜噜噜噜狠狠狠7777视频 | 国产成人在线视频播放 | 国产成人一区二区三区精 | 国产精久久久 | 亚洲精品综合 | 91精品久久久久久久久 | 欧美高清dvd | 午夜视频在线观看网站 | 91精品国产91综合久久蜜臀 | 91免费入口 | 在线中文字幕视频 | 国产欧美日韩综合精品一区二区 | 欧美极品在线 | av男人天堂影院 | 日本不卡一区二区三区在线观看 | 91免费在线 | 国产精品欧美一区二区三区不卡 | 性色的免费视频 | 蜜桃视频成人 | 国产原创在线观看 | 欧美激情五月 | 亚洲精品一区在线 | 九九色综合 | 亚洲一区二区久久 | 久久国产综合 | 看特级黄色片 | 91免费版在线观看 | 99精品视频在线观看免费播放 | 日韩av成人在线 | 日韩在线观看中文字幕 | 天天影视网天天综合色在线播放 | 6996成人影院网在线播放 | 精品亚洲91 | 羞羞在线视频 |