k8s源码设计模式之Factory

工厂方法是一种创建型设计模式,详情可参考工厂方法
如何创建一个informer
1
2
3
   // 创建对应资源的informer
factory := informers.NewSharedInformerFactory(clientset, time.Minute)
informer := factory.Core().V1().Pods().Informer()
工厂方法构造
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// 返回一个结构体sharedInformerFactory指针,该结构体实现了接口SharedInformerFactory
func NewSharedInformerFactory(client kubernetes.Interface, defaultResync time.Duration) SharedInformerFactory {
return NewSharedInformerFactoryWithOptions(client, defaultResync)
}

func NewSharedInformerFactoryWithOptions(client kubernetes.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory {
factory := &sharedInformerFactory{
client: client,
namespace: v1.NamespaceAll,
defaultResync: defaultResync,
informers: make(map[reflect.Type]cache.SharedIndexInformer),
startedInformers: make(map[reflect.Type]bool),
customResync: make(map[reflect.Type]time.Duration),
}

// Apply all options
for _, opt := range options {
factory = opt(factory)
}

return factory
}

type SharedInformerFactory interface {
internalinterfaces.SharedInformerFactory
ForResource(resource schema.GroupVersionResource) (GenericInformer, error)
WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool

Admissionregistration() admissionregistration.Interface
Internal() apiserverinternal.Interface
Apps() apps.Interface
Autoscaling() autoscaling.Interface
Batch() batch.Interface
Certificates() certificates.Interface
Coordination() coordination.Interface
Core() core.Interface
Discovery() discovery.Interface
Events() events.Interface
Extensions() extensions.Interface
Flowcontrol() flowcontrol.Interface
Networking() networking.Interface
Node() node.Interface
Policy() policy.Interface
Rbac() rbac.Interface
Scheduling() scheduling.Interface
Storage() storage.Interface
}

// 以Core()方法为例,实现了V1()方法,返回值为一个接口
type Interface interface {
// V1 provides access to shared informers for resources in V1.
V1() v1.Interface
}

// v1.Interface
type Interface interface {
// ComponentStatuses returns a ComponentStatusInformer.
ComponentStatuses() 设计模式ComponentStatusInformer
// ConfigMaps returns a ConfigMapInformer.
ConfigMaps() ConfigMapInformer
// Endpoints returns a EndpointsInformer.
Endpoints() EndpointsInformer
// Events returns a EventInformer.
Events() EventInformer
// LimitRanges returns a 设计模式LimitRangeInformer.
LimitRanges() LimitRangeInformer
// Namespaces returns a NamespaceInformer.
Namespaces() NamespaceInformer
// Nodes returns a NodeInformer.
Nodes() NodeInformer
// PersistentVolumes returns a PersistentVolumeInformer.
PersistentVolumes() PersistentVolumeInformer
// PersistentVolumeClaims returns a PersistentVolumeClaimInformer.
PersistentVolumeClaims() PersistentVolumeClaimInformer
// Pods returns a PodInformer.
Pods() PodInformer
// PodTemplates returns a PodTemplateInformer.
PodTemplates() PodTemplateInformer
// ReplicationControllers returns a ReplicationControllerInformer.
ReplicationControllers() ReplicationControllerInformer
// ResourceQuotas returns a ResourceQuotaInformer.
ResourceQuotas() ResourceQuotaInformer
// Secrets returns a SecretInformer.
Secrets() SecretInformer
// Services returns a ServiceInformer.
Services() ServiceInformer
// ServiceAccounts returns a ServiceAccountInformer.
ServiceAccounts() ServiceAccountInformer
}

// 以Pods()为例,该方法返回PodInformer接口
// 实现了Informer和Lister()方法
type PodInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1.PodLister
}
factory.Core().V1().Pods().Informer()

1.首先调用Core()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
// Core()返回结构体group指针,group实现了V1()方法
func (f *sharedInformerFactory) Core() core.Interface {
return core.New(f, f.namespace, f.tweakListOptions)
}

type group struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}
func (g *group) V1() v1.Interface {
return v1.New(g.factory, g.namespace, g.tweakListOptions)
}

2.调用V1()方法

1
2
3
4
5
6
7
8
9
10
// V1()返回结构体version的指针,version实现了v1.Interface中的所有方法
func (g *group) V1() v1.Interface {
return v1.New(g.factory, g.namespace, g.tweakListOptions)
}

type version struct {
factory internalinterfaces.SharedInformerFactory
namespace string
tweakListOptions internalinterfaces.TweakListOptionsFunc
}

4.调用Pods()方法

1
2
3
4
// 返回podInformer指针,podInformer实现了Informer(),Lister()方法
func (v *version) Pods() PodInformer {
return &podInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}

5.最后调用Informer()方法,完成对象创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 调用InformerFor
// staging/src/k8s.io/client-go/informers/core/v1/pod.go
func (f *podInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&corev1.Pod{}, f.defaultInformer)
}

// staging/src/k8s.io/client-go/informers/factory.go
func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer {
f.lock.Lock()
defer f.lock.Unlock()

informerType := reflect.TypeOf(obj)
// 此处会检查informer是否存在,如果存在则直接返回
// 复用informer,节省资源
informer, exists := f.info设计模式rmers[informerType]
if exists {
return informer
}

resyncPeriod, exists := f.customResync[informerType]
if !exists {
resyncPeriod = f.defaultResync
}

informer = newFunc(f.client, resyncPeriod)
f.informers[informerType] = informer

return informer
}

REF:
1.client-go/informers/factory.go
2.client-go/informers/core/interface.go
3.client-go/informers/core/v1/interface.go
4.client-go/informers/core/v1/pod.go