Skip to content

OpenFaaS function is scaled down to zero when min and max replicas are set to 1 #931

Description

@szefoka

Hi,

I have a problem with OpenFaaS when setting the min and max replicas to 1, to avoid scaling of the function.

labels:
com.openfaas.scale.min: "1"
com.openfaas.scale.max: "1"

However the serving pod is scaled down to zero once in every minute.

Expected Behaviour

The serving pod of the function shouldn't be scaled down to zero.

Current Behaviour

Serving pod of the function is scaled down to zero in every minute

Output of kubectl get deployments -n openfaas-fn -w
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
myfunc 0 1 1 1 116m
myfunc 0 1 1 1 116m
myfunc 0 0 0 0 116m
myfunc 1 0 0 0 116m
myfunc 1 0 0 0 116m
myfunc 1 0 0 0 116m
myfunc 1 1 1 0 116m
myfunc 1 1 1 1 116m
myfunc 0 1 1 1 117m
myfunc 0 1 1 1 117m
myfunc 0 0 0 0 117m
myfunc 1 0 0 0 118m
myfunc 1 0 0 0 118m
myfunc 1 0 0 0 118m
myfunc 1 1 1 0 118m
myfunc 1 1 1 1 118m

Possible Solution

I have investigated the code of OpenFaaS and found the bottom lines in faas/gateway/handlers/alerthandler.go:

// CalculateReplicas decides what replica count to set depending on current/desired amount
func CalculateReplicas(status string, currentReplicas uint64, maxReplicas uint64, minReplicas uint64, scalingFactor uint64) uint64 {
newReplicas := currentReplicas
step := uint64((float64(maxReplicas) / 100) * float64(scalingFactor))

if status == "firing" {
	if currentReplicas == 1 {
		newReplicas = step
	} else {
		if currentReplicas+step > maxReplicas {
			newReplicas = maxReplicas
		} else {
			newReplicas = currentReplicas + step
		}
	}
} else { // Resolved event.
	newReplicas = minReplicas
}

return newReplicas

}

When calculating steps and it happens that maxReplicas is 1 and scaling factor is not set, so its value is 20% by default (according to https://docs.openfaas.com/architecture/autoscaling/) the step value is set to 0 after converting the whole calculation to uint64.

According to the bottom lines, newReplcias are set to 0 in my case.
if currentReplicas == 1 {
newReplicas = step

Solution is to set newReplicas to 1 in case maxReplicas is 1 and steps is 0 when currentReplicas equals to 1.

Steps to Reproduce (for bugs)

Append the bottom lines to the function's yml file, and redeploy the function.
labels:
com.openfaas.scale.min: "1"
com.openfaas.scale.max: "1"

After starting to call the function with curl or ab or whatever, the serving pod is scaled down to zero.

Context

I wanted to try how OpenFaaS works without scaling.

Your Environment

  • FaaS-CLI version ( Full output from: faas-cli version ): 0.7.7

  • Docker version docker version (e.g. Docker 17.0.05 ): 18.06.1-ce

  • Are you using Docker Swarm or Kubernetes (FaaS-netes)? FaaS-netes

  • Operating System and version (e.g. Linux, Windows, MacOS): Ubuntu 16.04, Kernel 4.4.0-134-generic

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions