EventRecorder
EventRecorder 接口,拥有3种记录方式:
Event(object runtime.Object, eventtype, reason, message string)
Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{})
AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{})
接口的实现是 recorderImpl
type recorderImpl struct {
scheme *runtime.Scheme k8s资源注册表
source v1.EventSource 上报时间的组件,例如kubelet,kube-controller-manager
*watch.Broadcaster 事件消费
clock clock.Clock 时间相关的接口
}
具体实现如下:
func (recorder *recorderImpl) Event(object runtime.Object, eventtype, reason, message string) {
recorder.generateEvent(object, nil, metav1.Now(), eventtype, reason, message)
}
func (recorder *recorderImpl) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) {
recorder.Event(object, eventtype, reason, fmt.Sprintf(messageFmt, args...))
}
func (recorder *recorderImpl) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) {
recorder.generateEvent(object, annotations, metav1.Now(), eventtype, reason, fmt.Sprintf(messageFmt, args...))
}
可以看到实际上都是根据产生事件的资源object,事件类型(warring,normal),原因,信息然后通过generateEvent()方法构建事件并且记录。
generateEvent 方法把入参构造成一个实际的event,然后记录事件,代码如下:
func (recorder *recorderImpl) generateEvent(object runtime.Object, annotations map[string]string, timestamp metav1.Time, eventtype, reason, message string) {
ref, err := ref.GetReference(recorder.scheme, object) #生成ObjectReference
...
if !util.ValidateEventType(eventtype) { #校验类型合法性
...
}
event := recorder.makeEvent(ref, annotations, eventtype, reason, message) #生成event
event.Source = recorder.source #添加上报事件的组件信息
go func() {
// NOTE: events should be a non-blocking operation
defer utilruntime.HandleCrash()
recorder.Action(watch.Added, event) #进行异步添加事件,这是重点方法
}()
}
Action就实际的记录过程了,源码如下
// Action distributes the given event among all watchers.
func (m *Broadcaster) Action(action EventType, obj runtime.Object) {
// 可以看到实际上就是把事件,存放在了上面图里面说的Broadcaster的incoming里面,供loop方法从incoming里面获取事件
m.incoming <- Event{action, obj}
}
总结:到这里记录事件这块逻辑就完成了,就是根据提供的信息生成事件信息,然后发送到Broadcaster的incoming里面,关于Broadcaster这个结构,下一节会详细来看。
链接:kubernetes 事件(Event)源码分析—三大杀器之EventBroadcaster&broadcasterWatcher