kubernetes apiserver源码: filter-chain TrackStarted

96 阅读1分钟

TrackStarted

// handler是一层包一层,先执行外面的,再执行里面的
// 也就是说先执行TrackStarted, 再执行WithAuthentication
// 开始认证
handler = genericapifilters.WithAuthentication(handler, c.Authentication.Authenticator, failedHandler, c.Authentication.APIAudiences)
// 记录身份认证开始时间
handler = filterlatency.TrackStarted(handler, "authentication")

  • filterlatency.TrackStarted(handler, "authentication")
// TrackStarted measures the timestamp the given handler has started execution
// by attaching a handler to the chain.
func TrackStarted(handler http.Handler, name string) http.Handler {
	return trackStarted(handler, name, utilclock.RealClock{})
}

这里有个模式,就是TrackStarted只是透传和添加默认参数,将第一个字母小写trackStarted,才是真正的逻辑。

  • trackStarted(handler, name, utilclock.RealClock{})
func trackStarted(handler http.Handler, name string, clock utilclock.PassiveClock) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()
                // 从Context中获取requestFilterRecord
		if fr := requestFilterRecordFrom(ctx); fr != nil {
			fr.name = name
			fr.startedTimestamp = clock.Now() // 设置认证开始时间为当前时间
                        // dispatch to next
			handler.ServeHTTP(w, r)
			return
		}
                // 如果没有requestFilterRecord则创建一个
		fr := &requestFilterRecord{
			name:             name,
			startedTimestamp: clock.Now(),
		}
                // + 放到Context中
		r = r.WithContext(withRequestFilterRecord(ctx, fr))
		handler.ServeHTTP(w, r)
	})
}

  • r = r.WithContext(withRequestFilterRecord(ctx, fr))

// withRequestFilterRecord attaches the given request filter record to the parent context.
func withRequestFilterRecord(parent context.Context, fr *requestFilterRecord) context.Context {
	return apirequest.WithValue(parent, requestFilterRecordKey, fr)
}

// WithValue returns a copy of parent in which the value associated with key is val.
func WithValue(parent context.Context, key interface{}, val interface{}) context.Context {
	return context.WithValue(parent, key, val)
}

TrackCompleted

记录结束时间,并更新metric数据

// TrackCompleted measures the timestamp the given handler has completed execution and then
// it updates the corresponding metric with the filter latency duration.
func TrackCompleted(handler http.Handler) http.Handler {
	return trackCompleted(handler, utilclock.RealClock{}, func(ctx context.Context, fr *requestFilterRecord, completedAt time.Time) {
                // 3.2 计算认证耗时,调用prometheus客户端存储
		metrics.RecordFilterLatency(ctx, fr.name, completedAt.Sub(fr.startedTimestamp))
	})
}
func trackCompleted(handler http.Handler, clock utilclock.PassiveClock, action func(context.Context, *requestFilterRecord, time.Time)) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// The previous filter has just completed.  
		completedAt := clock.Now() // 1. 认证过程结束,记录时间戳

		defer handler.ServeHTTP(w, r) // dispatch next at the end

		ctx := r.Context()
                // 2. 这里读取开始时间
		if fr := requestFilterRecordFrom(ctx); fr != nil {
			action(ctx, fr, completedAt) // 3.1 执行传入函数action
		}
	})
}

  • metrics.RecordFilterLatency(ctx, fr.name, completedAt.Sub(fr.startedTimestamp))
func RecordFilterLatency(ctx context.Context, name string, elapsed time.Duration) {
	requestFilterDuration.WithContext(ctx).WithLabelValues(name).Observe(elapsed.Seconds())
}