kubernetesのイベントを収集、格納、アラームする
3639 ワード
背景:
企業内でますます多くのサービスがkubernetesに移行するにつれて、ユーザーはkubernetesに関する情報の取得をより切実にし、彼らは自分のサービスインスタンスが何を「経験した」のかを知りたいと思っています.例えば、業務異常があるとき、自分のインスタンスが再起動されたかどうかを知りたいと思っています.オンラインに失敗したときも、最初に原因を知りたいと思っています.さらに、これらがリアルタイムで通知され、後で表示されることを望んでいます.しかし、通常、kubectlなど、クラスタサーバに直接接触することはできません.そのため、良い解決策が必要です.
需要分解:
上記の要件は、次の4つの基本機能に分解できます. kubernetes上のイベント情報 をリアルタイムで取得できる.異常事象に対してリアルタイム警報を行うことができる .は、問題が に遡るようにイベントをより永続的に保持することができる.保存されたイベントを問い合わせることができる .
これらの機能はすべて合理的に聞こえ、kubernetes.ioにはEvents in Stackdriverもイベントのストレージについて話しています.
これは、「イベントはkubernetesのオブジェクトリソースとして、並べ替えに役立ちますが、多くのイベントがetcdに格納されると、パフォーマンスと容量の圧力が大きくなるため、etcdではデフォルトで最近1時間しか保存されません.そのため、より永続的に保存するには、サードパーティ製のツールが必要です」と述べています.
具体的には、1.7+バージョンでは、Google Kubernetes Engineでcloud loggingが有効になっている場合、デフォルトでは、最小優先度で可能な限り少ないリソース(通常0.1コアのCPUと0.1 Gのメモリ)を使用するevent-exporterがクラスタ内に配備されます.
よさそうですが、機能1、3、4だけで対応するアラームはありません.またGKEを使用していないものも直接使用できないことは明らかです.
kubewatchやその背後にあるカスタムコントローラのようなオープンソースプロジェクトをもう一度調べました.ここでは、コントローラを自分で実装する方法を簡単に振り返ってみましょう.はcacheを通過する.NewListWatchFromClient新規リスト はcacheを通過する.NewSharedIndexInformer+ListWatcher新しいinformer workqueueを介してRateLimitingQueueまたは他のタイプのキュー を新規作成 informerにhandlerを追加し、OnAddなどのイベント情報をキューに入れる . informer を起動データのローカルキャッシュへの同期完了を待つ worker持続消費queueのイベントを起動し、フィルタリング、アラーム、記憶などの処理を行う.
しかしkubewatchは直接要求を満たすことができず、pod、service、deploymentなどの様々なリソースタイプを傍受しているが、Eventタイプだけが欠けており、異なるタイプに対してinformerを起動し、異なるタイプのリソースのイベントフォーマットが異なり、互換性のために共通情報のみを伝達するため、フィールドは少ない.したがって,処理を再簡略化し,Eventタイプのみを傍受し,すべてのフィールドを解析することができる.次のようになります.
ここで説明するのはeventオブジェクトの削除イベントであり、通常は期限切れのイベントのクリーンアップであり、直接破棄すればよい.
コード:https://github.com/gok8s/kube-eventalert
企業内でますます多くのサービスがkubernetesに移行するにつれて、ユーザーはkubernetesに関する情報の取得をより切実にし、彼らは自分のサービスインスタンスが何を「経験した」のかを知りたいと思っています.例えば、業務異常があるとき、自分のインスタンスが再起動されたかどうかを知りたいと思っています.オンラインに失敗したときも、最初に原因を知りたいと思っています.さらに、これらがリアルタイムで通知され、後で表示されることを望んでいます.しかし、通常、kubectlなど、クラスタサーバに直接接触することはできません.そのため、良い解決策が必要です.
需要分解:
上記の要件は、次の4つの基本機能に分解できます.
これらの機能はすべて合理的に聞こえ、kubernetes.ioにはEvents in Stackdriverもイベントのストレージについて話しています.
これは、「イベントはkubernetesのオブジェクトリソースとして、並べ替えに役立ちますが、多くのイベントがetcdに格納されると、パフォーマンスと容量の圧力が大きくなるため、etcdではデフォルトで最近1時間しか保存されません.そのため、より永続的に保存するには、サードパーティ製のツールが必要です」と述べています.
具体的には、1.7+バージョンでは、Google Kubernetes Engineでcloud loggingが有効になっている場合、デフォルトでは、最小優先度で可能な限り少ないリソース(通常0.1コアのCPUと0.1 Gのメモリ)を使用するevent-exporterがクラスタ内に配備されます.
よさそうですが、機能1、3、4だけで対応するアラームはありません.またGKEを使用していないものも直接使用できないことは明らかです.
kubewatchやその背後にあるカスタムコントローラのようなオープンソースプロジェクトをもう一度調べました.ここでは、コントローラを自分で実装する方法を簡単に振り返ってみましょう.
しかしkubewatchは直接要求を満たすことができず、pod、service、deploymentなどの様々なリソースタイプを傍受しているが、Eventタイプだけが欠けており、異なるタイプに対してinformerを起動し、異なるタイプのリソースのイベントフォーマットが異なり、互換性のために共通情報のみを伝達するため、フィールドは少ない.したがって,処理を再簡略化し,Eventタイプのみを傍受し,すべてのフィールドを解析することができる.次のようになります.
lw := cache.NewListWatchFromClient(
kubeClient.CoreV1().RESTClient(), //
"events", //
"", // ,
fields.Everything()) // ,
informer := cache.NewSharedIndexInformer(lw, &api_v1.Event{}, 0, cache.Indexers{})
c := controller.NewResourceController(kubeClient, informer, config)
func NewResourceController(client kubernetes.Interface, informer cache.SharedIndexInformer, config config.Config) *Controller {
queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
var newEvent Event
var err error
informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
evt := obj.(*api_v1.Event)
newEvent.Key, err = cache.MetaNamespaceKeyFunc(obj)
if err == nil {
logrus.Debugf(" , :CreateEvent, :%+v", evt)
queue.Add(newEvent.Key)
}
},
UpdateFunc: func(old, new interface{}) {
oldEvt := old.(*api_v1.Event)
newEvt := new.(*api_v1.Event)
if !reflect.DeepEqual(newEvt.Source, oldEvt.Source) && oldEvt.Reason != newEvt.Reason {
newEvent.Obj = newEvt
newEvent.Key, err = cache.MetaNamespaceKeyFunc(old)
if err == nil {
queue.Add(newEvent.Key)
}
}
},
DeleteFunc: func(obj interface{}) {
evt := obj.(*api_v1.Event)
flog.Log().Infof("%+v", evt)
newEvent.Obj = evt
newEvent.Type = DeleteEvent
newEvent.Key, err = cache.DeletionHandlingMetaNamespaceKeyFunc(obj)
if err == nil {
logrus.Debugf(" , :DeleteEvent, :%+v", evt)
}
},
})
return &Controller{
clientset: client,
informer: informer,
queue: queue,
config: config,
}
}
// Run starts the kubewatch controller
func (c *Controller) Run(stopCh
ここで説明するのはeventオブジェクトの削除イベントであり、通常は期限切れのイベントのクリーンアップであり、直接破棄すればよい.
コード:https://github.com/gok8s/kube-eventalert