Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add namespace in function name for metrics #1488

Merged
merged 3 commits into from
Nov 2, 2020

Conversation

viveksyngh
Copy link
Contributor

@viveksyngh viveksyngh commented Mar 22, 2020

This commit adds namespace in function names while logging metrics to
prometheus, irrespective of the function is invoked with namespace suffix
or not.

This is also required to add multiple namespace support to faas-idler

https://github.com/openfaas-incubator/faas-idler/issues/37 which is part
of openfaas/faas-netes#511

Signed-off-by: Vivek Singh [email protected]

Description

Motivation and Context

  • I have raised an issue to propose this change (required)
  • My issue has received approval from the maintainers or lead with the design/approved label

How Has This Been Tested?

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I've read the CONTRIBUTION guide
  • I have signed-off my commits with git commit -s
  • I have added tests to cover my changes.
  • All new and existing tests passed.

gateway/handlers/notifiers.go Outdated Show resolved Hide resolved
gateway/metrics/exporter.go Outdated Show resolved Hide resolved
e.services = services
} else {
for _, namespace := range namespaces {
services, err := e.getFunctions(endpointURL, namespace)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this works well for now, but I also suspect a larger discussion is needed about how/if we move this into the provider sending a request per namespace every second seems like something the provider should encapsulate so that it can optimize that behavior as it best makes sense for itself.

This current implementation would create a "thundering herd"-like problem with no way to really streamline or optimize it. For example, the k8s provider should be able to request the existing functions from several/all namespaces in a single request.

Perhaps we need a new endpoint in the provider that allows the gateway to send 0, 1, or more namespaces as part of the request. When it is 0, it would request for all namespaces, otherwise the response would send back a list of functions for the provided namespaces. Alternatively, we could allow a special _all value. Then 0 namespaces == default, 1 or more applied as obvious, _all return functions from all possible namespaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely agree and we should move function aggregation logic to the provider.

I think we can modify the exiting function list endpoint using some special query parameters like _all, for which will combine functions from all namespaces and return it. Otherwise it works as it is working now. I think it will be a very minimal change compared to having a new endpoint. For new endpoint we will have to write different logic depending on the provider at several places.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introducing a thundering herd issue concerns me. What are the alternatives to doing that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thundering herd issue is because every 5 second (configurable) it tries to get all namespaces and then for each namespace it lists its functions to count service/replica count of functions.

Solution is to use a new endpoint or existing which list all functions across all namespaces so that we don't have to make these multiple calls. This implementation can be done in faas-netes which will be efficient.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@viveksyngh can you write a bash loop to deploy 100-200 functions and then measure the effect of the patch?

Copy link
Member

@alexellis alexellis Sep 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for j in {1..10} do ;
  kubectl create namespace $i #annotate it
  for i in {1..10} do ;
   faas-cli deploy --image figlet --name fn$I --namespace $j
  done
done

Perhaps create 10-20 in 10 different namespaces

gateway/metrics/exporter.go Outdated Show resolved Hide resolved
@@ -72,9 +82,45 @@ func (e *Exporter) StartServiceWatcher(endpointURL url.URL, metricsOptions Metri
ticker := time.NewTicker(interval)
quit := make(chan struct{})

timeout := 3 * time.Second
go func() {
for {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this new segment of code for? I was mainly expecting this PR to set a default suffix in the invocation URL when there was not one given.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New segment of code is for getting replica count of the services, which was not having support for multiple namespace. It was only getting replica count for the functions present in default namespace.

@alexellis
Copy link
Member

This was reviewed several weeks ago in a members call with @viveksyngh and @LucasRoesler - we had a concern about performance and paused the patch. We need to review the solution and see if there are alternatives with other trade-offs (this still may be the best option)

@viveksyngh
Copy link
Contributor Author

viveksyngh commented Jul 29, 2020

Testing :

k3d create 

export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')"

arkade install openfaas --set clusterRole=true



kubectl port-forward -n openfaas svc/gateway 8080:8080 &

PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode; echo)

echo -n $PASSWORD | faas-cli login --username admin --password-stdin

kubectl -n openfaas run \
--image=stefanprodan/faas-grafana:4.6.3 \
--port=3000 \
grafana

kubectl -n openfaas expose deployment grafana \
--type=NodePort \
--name=grafana

kubectl port-forward -n openfaas svc/grafana 3000:3000 &

kubectl port-forward -n openfaas svc/prometheus 9090:9090 &

kubectl create namespace fn

kubectl annotate ns/fn openfaas=1

faas-cli namespaces
Namespaces:
 - fn
 - openfaas-fn



faas-cli store deploy figlet 

faas-cli store deploy figlet -n fn

faas-cli store deploy nodeinfo -n fn

faas-cli store deploy leftpad

echo "Hello" | faas-cli invoke figlet -n fn

echo "Hello" | faas-cli invoke figlet

echo "Hello" | faas-cli invoke leftpad

echo "Hello" | faas-cli invoke nodeinfo -n fn


➜  ~ faas-cli list -n fn
Function                      	Invocations    	Replicas
figlet                        	1              	1
nodeinfo                      	0              	1
➜  ~ faas-cli list
Function                      	Invocations    	Replicas
figlet                        	1              	1
leftpad                       	1              	1

Before Changes

Screen Shot 2020-07-29 at 3 31 13 PM
Screen Shot 2020-07-29 at 3 31 04 PM
Screen Shot 2020-07-29 at 3 30 44 PM

After Changes

Edit the Gateway deployment to use docker image viveksyngh/gateway:metrics-with-namespace-1

faas-cli list -n openfaas-fn
Function                      	Invocations    	Replicas
figlet                        	2              	1
leftpad                       	1              	1
➜  ~ faas-cli list -n fn
Function                      	Invocations    	Replicas
nodeinfo                      	5              	1
figlet                        	3              	1

Screen Shot 2020-07-29 at 4 17 58 PM
Screen Shot 2020-07-29 at 4 17 39 PM
Screen Shot 2020-07-29 at 4 17 27 PM

return services, nil
}

func (e *Exporter) getNamespaces(endpointURL url.URL) ([]string, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the CLI's code for this?

for {
select {
case <-ticker.C:
func (e *Exporter) getFunctions(endpointURL url.URL, namespace string) ([]types.FunctionStatus, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the CLI here instead?

@alexellis
Copy link
Member

@viveksyngh we will need a rebase on this.

After some discussion with @LucasRoesler, we thought this PR should be merged and then load-tested later.

This commit adds namespace in function names while logging metrics to
prometheus, irrespective of the function is invoked with namespace suffix
or not.

This is also required to add multiple namespace support to faas-idler

https://github.com/openfaas-incubator/faas-idler/issues/37 which is part
of openfaas/faas-netes#511

Signed-off-by: Vivek Singh <[email protected]>
@viveksyngh viveksyngh force-pushed the metrics-with-namespace branch from f0e633a to 3118134 Compare October 29, 2020 16:58
@alexellis
Copy link
Member

@LucasRoesler could you give this a final pass?

Copy link
Member

@LucasRoesler LucasRoesler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexellis I think we are ready. Let's follow up in a future PR to consolidate those places we can/should use the cli

Copy link
Member

@alexellis alexellis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved

@alexellis alexellis merged commit c9c2b39 into openfaas:master Nov 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants