Skip to content

Commit b5b71fd

Browse files
LucasRoesleralexellis
authored andcommitted
Switch from OF client to OF lister interface
**What** - Use the informer/lister to get Profiles instead of the REST client, this should be more efficient and low impact on the k8s API because it maintains an internal cache of the profiles Signed-off-by: Lucas Roesler <[email protected]>
1 parent dfef8d9 commit b5b71fd

File tree

4 files changed

+41
-25
lines changed

4 files changed

+41
-25
lines changed

k8s/factory.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,27 @@
44
package k8s
55

66
import (
7-
openfaasv1 "github.com/openfaas/faas-netes/pkg/client/clientset/versioned/typed/openfaas/v1"
7+
v1 "github.com/openfaas/faas-netes/pkg/client/listers/openfaas/v1"
88
"k8s.io/client-go/kubernetes"
99
)
1010

11+
// NamespacedProfiler is a subset of the v1.ProfileLister that is needed for the function factory
12+
// to support Profiles
13+
type NamespacedProfiler interface {
14+
Profiles(namespace string) v1.ProfileNamespaceLister
15+
}
16+
1117
// FunctionFactory is handling Kubernetes operations to materialise functions into deployments and services
1218
type FunctionFactory struct {
1319
Client kubernetes.Interface
1420
Config DeploymentConfig
15-
OFClient openfaasv1.OpenfaasV1Interface
21+
Profiler NamespacedProfiler
1622
}
1723

18-
func NewFunctionFactory(clientset kubernetes.Interface, config DeploymentConfig, ofClient openfaasv1.OpenfaasV1Interface) FunctionFactory {
24+
func NewFunctionFactory(clientset kubernetes.Interface, config DeploymentConfig, profiler NamespacedProfiler) FunctionFactory {
1925
return FunctionFactory{
2026
Client: clientset,
2127
Config: config,
22-
OFClient: ofClient,
28+
Profiler: profiler,
2329
}
2430
}

k8s/profiles.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"strings"
77

88
v1 "github.com/openfaas/faas-netes/pkg/apis/openfaas/v1"
9-
openfaasv1 "github.com/openfaas/faas-netes/pkg/client/clientset/versioned/typed/openfaas/v1"
109

1110
appsv1 "k8s.io/api/apps/v1"
1211
corev1 "k8s.io/api/core/v1"
@@ -53,7 +52,7 @@ func (c profileCMClient) Get(ctx context.Context, namespace string, names ...str
5352

5453
// profileCRDClient implements PolicyClient using the openfaas CRD Profile
5554
type profileCRDClient struct {
56-
client openfaasv1.ProfilesGetter
55+
client NamespacedProfiler
5756
}
5857

5958
func (c profileCRDClient) Get(ctx context.Context, namespace string, names ...string) ([]Profile, error) {
@@ -62,7 +61,8 @@ func (c profileCRDClient) Get(ctx context.Context, namespace string, names ...st
6261
// this is where we would consider using an informer/lister. The throughput on this
6362
// API. We expect will be similar to the secrets API, since we only use it during
6463
// function Deploy
65-
profile, err := c.client.Profiles(namespace).Get(ctx, name, metav1.GetOptions{})
64+
// Note Lister interfaces do not have context yet
65+
profile, err := c.client.Profiles(namespace).Get(name)
6666
if err != nil {
6767
return nil, err
6868
}
@@ -74,7 +74,7 @@ func (c profileCRDClient) Get(ctx context.Context, namespace string, names ...st
7474
// NewProfileClient returns the ProfilerClient powered by the Profile CRD
7575
func (f FunctionFactory) NewProfileClient() ProfileClient {
7676
// this is where we can replace with an informer/listener in the future
77-
return &profileCRDClient{client: f.OFClient}
77+
return &profileCRDClient{client: f.Profiler}
7878
}
7979

8080
// NewProfileClient returns the ProfilerClient powered by ConfigMaps

main.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ func main() {
9494

9595
log.Printf("DeploymentConfig: %+v\n", deployConfig)
9696

97-
factory := k8s.NewFunctionFactory(kubeClient, deployConfig, faasClient.OpenfaasV1())
98-
9997
// the sync interval does not affect the scale to/from zero feature
10098
// auto-scaling is does via the HTTP API that acts on the deployment Spec.Replicas
10199
defaultResync := time.Minute * 5
@@ -106,13 +104,20 @@ func main() {
106104
faasInformerOpt := informers.WithNamespace(config.DefaultFunctionNamespace)
107105
faasInformerFactory := informers.NewSharedInformerFactoryWithOptions(faasClient, defaultResync, faasInformerOpt)
108106

107+
// this is where we need to swap to the faasInformerFactory
108+
profileInformerOpt := informers.WithNamespace(config.ProfilesNamespace)
109+
profileInformerFactory := informers.NewSharedInformerFactoryWithOptions(faasClient, defaultResync, profileInformerOpt)
110+
profileLister := profileInformerFactory.Openfaas().V1().Profiles().Lister()
111+
factory := k8s.NewFunctionFactory(kubeClient, deployConfig, profileLister)
112+
109113
setup := serverSetup{
110-
config: config,
111-
functionFactory: factory,
112-
kubeInformerFactory: kubeInformerFactory,
113-
faasInformerFactory: faasInformerFactory,
114-
kubeClient: kubeClient,
115-
faasClient: faasClient,
114+
config: config,
115+
functionFactory: factory,
116+
kubeInformerFactory: kubeInformerFactory,
117+
faasInformerFactory: faasInformerFactory,
118+
profileInformerFactory: profileInformerFactory,
119+
kubeClient: kubeClient,
120+
faasClient: faasClient,
116121
}
117122

118123
if !operator {
@@ -142,9 +147,11 @@ func runController(setup serverSetup) {
142147

143148
log.Println("waiting for openfaas CRD cache sync")
144149
faasInformerFactory.WaitForCacheSync(stopCh)
150+
setup.profileInformerFactory.WaitForCacheSync(stopCh)
145151
log.Println("cache sync complete")
146152
go faasInformerFactory.Start(stopCh)
147153
go kubeInformerFactory.Start(stopCh)
154+
go setup.profileInformerFactory.Start(stopCh)
148155

149156
lister := endpointsInformer.Lister()
150157
functionLookup := k8s.NewFunctionLookup(config.DefaultFunctionNamespace, lister)
@@ -190,6 +197,7 @@ func runOperator(setup serverSetup) {
190197

191198
glog.Infof("Waiting for cache sync in main")
192199
kubeInformerFactory.WaitForCacheSync(stopCh)
200+
setup.profileInformerFactory.WaitForCacheSync(stopCh)
193201
glog.Infof("Cache sync done")
194202

195203
ctrl := controller.NewController(
@@ -204,6 +212,7 @@ func runOperator(setup serverSetup) {
204212

205213
go faasInformerFactory.Start(stopCh)
206214
go kubeInformerFactory.Start(stopCh)
215+
go setup.profileInformerFactory.Start(stopCh)
207216

208217
go srv.Start()
209218
if err := ctrl.Run(1, stopCh); err != nil {
@@ -214,12 +223,13 @@ func runOperator(setup serverSetup) {
214223
// serverSetup is a container for the config and clients needed to start the
215224
// faas-netes controller or operator
216225
type serverSetup struct {
217-
config types.BootstrapConfig
218-
kubeClient *kubernetes.Clientset
219-
faasClient *clientset.Clientset
220-
functionFactory k8s.FunctionFactory
221-
kubeInformerFactory kubeinformers.SharedInformerFactory
222-
faasInformerFactory informers.SharedInformerFactory
226+
config types.BootstrapConfig
227+
kubeClient *kubernetes.Clientset
228+
faasClient *clientset.Clientset
229+
functionFactory k8s.FunctionFactory
230+
kubeInformerFactory kubeinformers.SharedInformerFactory
231+
faasInformerFactory informers.SharedInformerFactory
232+
profileInformerFactory informers.SharedInformerFactory
223233
}
224234

225235
func setupLogging() {
@@ -231,7 +241,7 @@ func setupLogging() {
231241
f2 := klogFlags.Lookup(f1.Name)
232242
if f2 != nil {
233243
value := f1.Value.String()
234-
f2.Value.Set(value)
244+
_ = f2.Value.Set(value)
235245
}
236246
})
237247
}

pkg/controller/deployment.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func newDeployment(
137137
if err != nil {
138138
// TODO: a simple warning doesn't seem strong enough if a profile can't be found or there is
139139
// some other error
140-
glog.Warningf("Function %s can not retrieve required Profiles: %v", function.Spec.Name, err)
140+
glog.Warningf("Function %s can not retrieve required Profiles in %s: %v", function.Spec.Name, profileNamespace, err)
141141
}
142142
for _, profile := range profileList {
143143
factory.RemoveProfile(profile, deploymentSpec)
@@ -151,7 +151,7 @@ func newDeployment(
151151
if err != nil {
152152
// TODO: a simple warning doesn't seem strong enough if a profile can't be found or there is
153153
// some other error
154-
glog.Warningf("Function %s can not retrieve required Profiles: %v", function.Spec.Name, err)
154+
glog.Warningf("Function %s can not retrieve required Profiles in %s: %v", function.Spec.Name, profileNamespace, err)
155155
}
156156
// TODO: remove this or refactor to just print names
157157
glog.Infof("Function %s: Applying profiles %+v", function.Spec.Name, profileList)

0 commit comments

Comments
 (0)