Why use SlimFaas?
To test slimfaas on your local machine by using kubernetes with Docker Desktop, please use these commands:
git clone https://github.com/AxaFrance/slimfaas.git
cd slimfaas/demo
# Create slimfaas service account and pods
kubectl apply -f deployment-slimfaas.yml
# Expose SlimFaaS service as NodePort or Ingress
kubectl apply -f slimfaas-nodeport.yml
# or
# kubectl apply -f slimfaas-ingress.yml
# Install three instances of fibonacci functions
# fibonacci1, fibonacci2 and fibonacci3
kubectl apply -f deployment-functions.yml
# Install MySql
kubectl apply -f deployment-mysql.yml
# to run Single Page webapp demo (optional) on http://localhost:8000
docker run -p 8000:8000 --rm axaguildev/fibonacci-webapp:latest
Now, you can access your pod via SlimFaas proxy:
Synchronous way:
Asynchronous way:
Just wake up function:
Get function status:
List all function status:
Send event to every function replicas (which deployment subscribe to the event name) in synchronous way:
Single Page WebApp demo:
Enjoy slimfaas!!!!
To test slimfaas on your local machine by using kubernetes with Docker Desktop, please use these commands:
git clone https://github.com/AxaFrance/slimfaas.git
cd slimfaas
docker-compose up
Now, you can access your pod via SlimFaas proxy:
Enjoy slimfaas!!!!
SlimFaas act as an HTTP proxy with 2 modes:
To publish the message to every replicas in "Ready" state of the function
sample-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: fibonacci1
spec:
selector:
matchLabels:
app: fibonacci1
template:
metadata:
labels:
app: fibonacci1
annotations:
# Just add SlimFaas annotation to your pods and that's it !
SlimFaas/Function: "true"
SlimFaas/ReplicasMin: "0"
SlimFaas/ReplicasAtStart: "1"
SlimFaas/ReplicasStartAsSoonAsOneFunctionRetrieveARequest: "false"
SlimFaas/TimeoutSecondBeforeSetReplicasMin: "300"
SlimFaas/NumberParallelRequest : "10"
SlimFaas/Schedule: |
{"TimeZoneID":"Europe/Paris","Default":{"WakeUp":["07:00"],"ScaleDownTimeout":[{"Time":"07:00","Value":20},{"Time":"21:00","Value":10}]}}
SlimFaas/DependsOn: "mysql,fibonacci2" # comma separated list of deployment or statefulset names
SlimFaas/SubscribeEvents: "Public:my-event-name1,Private:my-event-name2,my-event-name3" # comma separated list of event names
SlimFaas/DefaultVisibility: "Public" # Public or Private (private can be accessed only by internal namespace https call from pods)
SlimFaas/UrlsPathStartWithVisibility: "Private:/mypath/subPath,Private:/mysecondpath" # Public or Private (private can be accessed only by internal namespace https call from pods)
spec:
serviceAccountName: default
containers:
- name: fibonacci1
image: docker.io/axaguildev/fibonacci:latest
resources:
limits:
memory: "96Mi"
cpu: "50m"
requests:
memory: "96Mi"
cpu: "10m"
ports:
- containerPort: 8080
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: slimfaas
spec:
replicas: 3
podManagementPolicy: Parallel
serviceName: slimfaas
selector:
matchLabels:
app: slimfaas
template:
metadata:
labels:
app: slimfaas
spec:
volumes:
- name: slimfaas-volume
emptyDir:
sizeLimit: 10Mi
serviceAccountName: admin # Use a service account with admin role
containers:
- name: slimfaas
image: docker.io/axaguildev/slimfaas:latest
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 3
periodSeconds: 10
timeoutSeconds: 8
terminationGracePeriodSeconds: 30
env:
- name: BASE_FUNCTION_URL
value: "http://{function_name}.{namespace}.svc.cluster.local:8080"
- name: BASE_FUNCTION_POD_URL # require for publish route
value: "http://{pod_ip}:5000"
- name: BASE_SLIMDATA_URL
value: "http://{pod_name}.slimfaas.{namespace}.svc.cluster.local:3262/" # Don't expose this port, it can also be like "http://{pod_ip}:3262/" but if you can use DNS it's better
- name: SLIMFAAS_PORTS
value: "5000" # can be like "5000,6000,7000" if you want to expose more ports
- name: NAMESPACE
value: "default"
- name: SLIMDATA_DIRECTORY
value: "/database"
# If you want to send event to an url which is not a SlimFaas function, you can use this env variable
# use comma to separate event name and url, use => to separate event name and destination url.
# urls are separated by ;
#- name: SLIMFAAS_SUBSCRIBE_EVENTS
# value: "my-event-name1=>http://localhost:5002;http://localhost:5003,my-event-name2=>http://localhost:5002"
# If you want to use just one pod for testing purpose, you can use this env variable
#- name: SLIMDATA_CONFIGURATION
# value: |
# {"coldStart":"true"}
# If you are not on kubernetes for example docker-compose, you can use this env variable, but you will lose auto-scale
#- name: MOCK_KUBERNETES_FUNCTIONS
# value: "{"Functions":[{"Name":"fibonacci","NumberParallelRequest":1}],"Slimfaas":[{"Name":"slimfaas-1"}]}"
# Configure CORS allowed Origins, default is *, you can use a comma separated list example: http://localhost:3000,http://localhost:3001
#- name: SLIMFAAS_CORS_ALLOW_ORIGIN
# Optional, longer is the delay, less CPU and RAM is used
#- name : HISTORY_SYNCHRONISATION_WORKER_DELAY_MILLISECONDS
# value : "500" # default equivalent to 0,5 seconds
# Optional, longer is the delay, less CPU and RAM is used
#- name : REPLICAS_SYNCHRONISATION_WORKER_DELAY_MILLISECONDS
# value : "2000" # default equivalent to 2 seconds
# Optional, longer is the delay, less CPU and RAM is used
#- name : SLIM_WORKER_DELAY_MILLISECONDS
# value : "50" # default equivalent to 50 milliseconds
# Optional, longer is the delay, less CPU and RAM is used
#- name : SCALE_REPLICAS_WORKER_DELAY_MILLISECONDS
# value : "1000" # default equivalent to 1 seconds
# Optional
# name : TIME_MAXIMUM_WAIT_FOR_AT_LEAST_ONE_POD_STARTED_FOR_SYNC_FUNCTION
# value : "10000" # default equivalent to 10 seconds
# Optional
# name : POD_SCALED_UP_BY_DEFAULT_WHEN_INFRASTRUCTURE_HAS_NEVER_CALLED
# value : "false" # default equivalent to false
# Optional
# name : SLIMFAAS_ALLOW_UNSECURE_SSL
# value : "false" # default equivalent to false
# Optional
# name: HEALTH_WORKER_DELAY_MILLISECONDS
# value: "1000" # default equivalent to 1 seconds
# Optional
# name: HEALTH_WORKER_DELAY_TO_EXIT_SECONDS
# value: "60" # default equivalent to 10 seconds
# name : SLIMDATA_CONFIGURATION # represent SlimData internal configuration, more documentation here: https://dotnet.github.io/dotNext/features/cluster/raft.html
# value : | #default values
# {
# "partitioning":"false",
# "lowerElectionTimeout":"150",
# "upperElectionTimeout":"300",
# "requestTimeout":"00:00:00.3000000",
# "rpcTimeout":"00:00:00.1500000",
# "coldStart":"false",
# "requestJournal:memoryLimit":"5",
# "requestJournal:expiration":"00:01:00",
# "heartbeatThreshold":"0.5",
# }
volumeMounts:
- name: slimfaas-volume
mountPath: /database
resources:
limits:
memory: "76Mi"
cpu: "400m"
requests:
memory: "76Mi"
cpu: "250m"
ports:
- containerPort: 5000
- containerPort: 3262
# You can use this section to define a persistent volume claim
#volumeClaimTemplates:
#- metadata:
# name: slimfaas-volume
# spec:
# accessModes: [ "ReadWriteOnce" ]
# storageClassName: managed-csi # or any other storage class available in your cluster
# volumeMode: Filesystem
# resources:
# requests:
# storage: 10Mi
---
apiVersion: v1
kind: Service
metadata:
name: slimfaas
spec:
selector:
app: slimfaas
ports:
- name: "http"
port: 80
targetPort: 5000
- name: "slimdata"
port: 3262
targetPort: 3262
[!WARNING] Yours service name must be the same as the SlimFaas Deployment/StatefulSet name
{
"TimeZoneID":"Europe/Paris", # Time Zone ID can be found here: https://nodatime.org/TimeZones
"Default":{
"WakeUp":["07:00"], // Wake up your infrastructure at 07:00
"ScaleDownTimeout":[
{"Time":"07:00","Value":20}, // Scale down after 20 seconds of inactivity after 07:00
{"Time":"21:00","Value":10} // Scale down after 10 seconds of inactivity after 21:00
]
}
}
We used OpenFaas for a long time and we love it. But we encountered many OpenFaas issues:
We would like to use Knative but:
So we decided to create SlimFaas to have a quick and simple replacement proxy solution that can expose Prometheus metrics. Now we have a solution not coupled to anything. SlimFaas is simple, light, fast and plug and play!
Instead of creating many pods, SlimFaas use internally many workers in the same pod:
SlimData is a simple redis like database included inside SlimFaas executable. It is based on Raft algorithm offered by awesome https://github.com/dotnet/dotNext library. By default, SlimData use a second HTTP port 3262 to expose its API. Don't expose it and keep it internal.
SlimFaas requires at least 3 nodes in production. 2 nodes are required to keep the database in a consistent state.
If you want to use just one pod for testing purpose, you can use this env variable:
This will allow to start a pod alone as a leader. SlimFaas can to scale up and down by using classic Horizontal Pod Autoscaler (HPA).
Why .NET?