Stack Labs Blog moves to Dev.to | Le Blog Stack Labs déménage sur Dev.to 🚀
OpenFaaS - Un FaaS sur son orchestrateur de conteneurs
Temps de lecture estimé : 7 minutes
Si vous possédez un cloud privé et que vous rêvez d’y installer une infrastructure Serverless ; si vous avez un compte sur un cloud public et que vous hésitez encore à utiliser ses services Serverless pour garder un contrôle sur vos fonctions, sachez que vous pouvez installer une plateforme Function As a Service
sur votre orchestrateur de conteneurs avec la solution OpenFaaS.
Note : Cet article présente un exemple de déploiement d’OpenFaas sur AWS EKS. La même technique s’applique au déploiement d’OpenFaaS sur un minikube, un serveur on-premise ou toute autre plateforme cloud telle que GKE ou OpenShift.
Serverless, c’est quoi déjà ?
Dans une architecture traditionnelle, on a toujours besoin d’un backend pour les traitements côté serveur. L’idée d’une architecture Serverless est de se passer de ce serveur d’application et de son infrastructure. Comment ? En exécutant le code qui représente le backend sur une plateforme Function As a Service
. Toute l’architecture devra être pensée en fonctions
. Le code de la fonction devra être léger et s’exécuter rapidement.
Pourquoi OpenFaaS ?
Les cloud publics proposent tous une plateforme Function As a Service
. Leur solution répond à la plupart des cas d’usage et nous aide à gagner du temps et à reduire nos coûts. Mais selon certains besoins métiers, on peut être freiné par certaines limitations comme l’accès aux logs du système, la durée du timeout, les ressources mémoires ou encore le langage utilisé.
Heureusement aujourd’hui, des solutions alternatives existent pour déployer sa propre infrastructure Serverless. On peut citer OpenFaaS, Apache OpenWhisk ou knative. Celui qui est le plus en vogue aujourd’hui est incontestablement OpenFaaS.
OpenFaaS est un framework, il permet d’exécuter des fonctions Serverless sur du Docker ou du Kubernetes.
OpenFaaS supporte aujourd’hui les langages suivants : Node.js, Python, Go, Java, C#, PHP, et Ruby. Il nous suffit de spécifier un fichier (handler.py
/handler.js
) et le framework se chargera de créer l’image Docker pour nous. Il est aussi possible de construire sa propre image.
Architecture
Chaque fonction déployée sur OpenFaaS a pour effet de créer sur Kubernetes un Deployment
et un Service
. Le Deployment
a par défaut un seul réplica et donc au minimum un seul pod pour servir le trafic. On peut le voir sur le schéma ci-dessous OpenFaaS operator
, qui est accessible via kubectl
ou faas-cli
:
Pour en savoir plus sur l’Architecture d’OpenFaaS
Installation
Il y a différentes manières d’installer OpenFaaS sur son orchestrateur de containers. Soit manuellement via un kubectl
ou directement depuis un package helm
. Dans cet article nous allons décrire les étapes permettant de déployer OpenFaaS sur un cluster Kubernetes sur AWS via Helm. Voir avec minikube
Prerequis
- eksctl CLI.
- AWS CLI.
- Kubernetes CLI.
- Helm CLI.
- OpenFaaS CLI.
Créer le cluster EKS
On va créer un cluster simple sur AWS EKS sur la région Ireland
avec 2 nodes.
eksctl create cluster --name=eks-openfaas-overview --nodes-min=2 --nodes-max=3 --node-type=t3.medium --node-volume-size=5 --auto-kubeconfig --region=eu-west-1 --version=1.11
eksctl
est basé sur aws cloudformation
et nous aide à déployer rapidement un cluster sur aws.
Installer le serveur Helm sur le cluster
Helm est le meilleur outil permettant d’installer des packages sur K8S.
kubectl -n kube-system create sa tiller
serviceaccount/tiller created
kubectl create clusterrolebinding tiller-cluster-rule \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:tiller
clusterrolebinding.rbac.authorization.k8s.io/tiller-cluster-rule created
helm init --upgrade --service-account tiller
$HELM_HOME has been configured at $HOME/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
[..]
Happy Helming!
Installer les namespaces OpenFaaS
Les services core
d’OpenFaaS sont créés dans le namespace openfaas
tandis que les services de chaque fonction sont dans openfaas-fn
kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml
namespace/openfaas created
namespace/openfaas-fn created
Déployer OpenFaaS sur le cluster
Première étape, récupèrer le repo openfaas
depuis helm
helm repo add openfaas https://openfaas.github.io/faas-netes/
"openfaas" has been added to your repositories
Seconde étape, déployer OpenFaaS avec Helm
(Si vous faites les tests depuis votre propre compte AWS, il est recommandé de créer un secret
pour sécuriser votre API Gateway, voir Secrets et Auth)
helm upgrade openfaas --install openfaas/openfaas \
--namespace openfaas \
--set functionNamespace=openfaas-fn \
--set serviceType=LoadBalancer \
--set gateway.replicas=2 \
--set queueWorker.replicas=2
Release "openfaas" does not exist. Installing it now.
NAME: openfaas
LAST DEPLOYED: Mon Jan 28 19:06:13 2019
NAMESPACE: openfaas
STATUS: DEPLOYED
[..]
==> v1/Service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
alertmanager ClusterIP 10.104.93.105 <none> 9093/TCP 1s
gateway-external LoadBalancer 10.110.3.97 <pending> 8080:30950/TCP 1s
gateway ClusterIP 10.109.238.95 <none> 8080/TCP 1s
nats ClusterIP 10.103.150.181 <none> 4222/TCP 1s
prometheus ClusterIP 10.99.131.109 <none> 9090/TCP 1s
==> v1beta1/Deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
alertmanager 1 1 1 0 1s
faas-idler 1 1 1 0 1s
gateway 2 2 2 0 1s
nats 1 1 1 0 1s
prometheus 1 1 1 0 1s
queue-worker 2 2 2 0 1s
[..]
La commande va créer un loadbalancer, 2 réplicas et 2 queue-workers pour la haute disponibilité.
Une fois les services déployés, l’External-IP
sera disponible (à récupèrer depuis kubectl get svc -n openfaas -o wide
). La dernière étape consiste à exporter l’URL d’OpenFaaS.
export OPENFAAS_URL=$(kubectl get svc -n openfaas gateway-external -o jsonpath='{.status.loadBalancer.ingress[*].hostname}'):8080
(sur minikube on ferait : export OPENFAAS_URL=http://$(minikube ip):31112
)
Déployer une fonction
Il est possible de déployer sa fonction de 3 manières:
- soit depuis l’UI,
- soit depuis un appel REST,
- ou via la cli d’OpenFaaS
faas-cli
installé préalablement.
Pour faire simple, nous allons prendre une fonction déjà créée depuis OpenFaaS Function Store
. Vous pouvez voir la liste depuis faas-cli store list
:
faas-cli store deploy colorise
Deployed. 202 Accepted.
URL: http://123456789.eu-west-1.elb.amazonaws.com:8080/function/colorise
La fonction sera automatiquement déployée sur OpenFaaS. Testons notre fonction avec la CLI :
echo -n 'https://www.stack-labs.com/images/cover.jpg' | faas-cli invoke colorise > stackerteam.jpg
Créer sa propre fonction
On peut écrire notre propre fonction avec un langage supporté par OpenFaaS ou en créant notre propre template. Un template OpenFaaS consiste en un Dockerfile et un entrypoint (pas accessible par l’utilisateur). Le code est à écrire dans un fichier handler.
On peut vérifier les images OpenFaaS disponibles en lançant les commandes :
faas-cli template pull
faas-cli new --list
La commande faas-cli new
sert à initialiser une fonction. On indique le langage souhaité et le préfixe correspondant au repository du registry docker.
faas-cli new --lang go hey-stacker --prefix=123456789.dkr.ecr.eu-west-1.amazonaws.com
Cela créera les fichiers suivants :
./hey-stacker.yml
./hey-stacker/
./hey-stacker/handler.go
Editer handler.go :
package function
import (
"fmt"
)
// Handle a serverless request
func Handle(req []byte) string {
return fmt.Sprintf("Hey, Stacker. You said: %s", string(req))
}
Pour déployer la fonction sur OpenFaaS, on lance la commande :
faas-cli up -f hey-stacker.yml
[0] > Building hey-stacker.
Clearing temporary build folder: ./build/hey-stacker/
Preparing ./hey-stacker/ ./build/hey-stacker/function
Building: 123456789.dkr.ecr.eu-west-1.amazonaws.com/hey-stacker:latest with go template. Please wait..
Sending build context to Docker daemon 6.656kB
Step 1/20 : FROM golang:1.10.4-alpine3.8 as builder
[..]
Step 20/20 : CMD ["./fwatchdog"]
---> Using cache
---> a69c3283ca02
Successfully built a69c3283ca02
Successfully tagged 123456789.dkr.ecr.eu-west-1.amazonaws.com/hey-stacker:latest
Image: 123456789.dkr.ecr.eu-west-1.amazonaws.com/hey-stacker:latest built.
[0] < Building hey-stacker done.
[0] worker done.
[0] > Pushing hey-stacker [123456789.dkr.ecr.eu-west-1.amazonaws.com/hey-stacker:latest].
The push refers to repository [123456789.dkr.ecr.eu-west-1.amazonaws.com/hey-stacker]
[..]
[0] < Pushing hey-stacker [123456789.dkr.ecr.eu-west-1.amazonaws.com/hey-stacker:latest] done.
[0] worker done.
Deploying: hey-stacker.
Deployed. 202 Accepted.
URL: http://123456789.eu-west-1.elb.amazonaws.com:8080/function/hey-stacker
Cette commande est équivalente à l’ensemble de ces commandes : construction de l’image, push de l’image sur le registry et déploiement de la fonction sur OpenFaaS.
faas-cli build && \
faas-cli push && \
faas-cli deploy
On peut invoquer la fonction comme décrit plus haut ou via l’UI d’OpenFaaS. Dans cet exemple, on invoque la fonction directement depuis l’UI.
Monitoring
OpenFaaS met à notre disposition d’autres outils tels que Prometheus
et Grafana
pour monitorer nos applications.
kubectl -n openfaas run --image=stefanprodan/faas-grafana:4.6.3 --port=3000 grafana
kubectl expose deploy/grafana --type ClusterIP -n openfaas --port 3000
kubectl port-forward -n openfaas svc/grafana 3000:3000
On peut voir dans cet exemple, la liste des fonctions déployées.
Conclusion
OpenFaaS nous donne la possibilité de déployer des fonctions de façon plus custom qu’on le ferait avec une fonction Serverless sur un cloud public. Très pratique lorsqu’on souhaite déployer une infrastructure Serverless sur un orchestrateur existant et bénéficier de tous ses avantages.
Références :