Commentaires
Serverless, PHP et Symfony
Depuis une dizaine d’années, le monde du déploiement et de l’hébergement
d’applications web change à une vitesse phénoménale. L’arrivée de
AWS et
de leurs VMs en deux
clics, puis l’arrivée de PaaS
comme Heroku (d'ailleurs, consultez
l'article d'Alex sur Symfony & Heroku
si vous ne l'avez pas encore lu !), puis l’arrivée des conteneurs
(ou containers). Dans le viseur aujourd’hui, ce sont
les Faas ou
« serverless ».
Aujourd’hui, nous étudierons en quoi ces nouvelles offres
« serverless » ont un intérêt pour nous,
utilisateurs et créateurs d’applications web. Nous verrons également
comment utiliser ces offres pour votre application Symfony.
Qu’est-ce que serverless
D’après le nom, en francais « sans-serveur », on peut comprendre l’idée :
il n’y a pas de serveur à gérer. Cela veut dire pas de machine dédiée
chez OVH, pas de EC2 chez AWS ou encore pas de dyno chez Heroku.
C’est tout simplement un PaaS donc ? Ou bien un hébergement mutualisé à
l’ancienne ? Eh bien… non plus. On peut résumer les « FaaS » par les
points suivants :
-
Pay-as-you really go.
Toutes les autres alternatives, à ma connaissance, facturent un
prix de base par mois, qui inclut une certaine quantité de
trafic et/ou de ressources utilisables. Pour ces offres là, vous
ne payez qu’au nombre d’exécutions.
C’est-à-dire : 0 requêtes = 0 €.
-
Stateless.
Chaque exécution de notre fonction est indépendante. Typiquement,
on ne pourra pas écrire sur le disque dur pour la prochaine
requête. Il faut aussi imaginer que notre fonction sera exécutée
quelque part, mais nous n’avons aucun contrôle sur l’endroit.
-
Scalable. Il n’y a plus de serveur (à votre
connaissance). Ces fonctions sont des processus stateless
exécutés pour quelques millisecondes, voire quelques secondes. Ces
contraintes leur permettent d’être exécutées sur une quantité très
importante de machines, en parallèle, et donc de répondre à des pics
de demande extrêmement importants.
Cela nous donne une solution qui ne coûte rien lorsqu'elle n'est pas
utilisée, mais qui permet une mise à l'échelle (ou de répondre à de gros
pics de trafic) en quelques secondes. Un bon exemple pour prouver
l’intérêt de telles infrastructures est la BBC :
ils utilisent AWS Lambda
pour faire du rendu de frames vidéos en temps
réel. Lorsqu'aucun rendu n’est à effectuer, cela ne leur coute rien,
mais ils peuvent absorber une grande quantité d’exécutions, sans rien
changer à leur infrastructure.
Qui sont les principaux acteurs dans ce domaine ?
Vous l’aurez sans doute compris, Amazon Web Services a un FaaS nommé
"AWS Lamba”,
Google Cloud a les "Google Cloud Functions”,
Azure… "Functions”.
Ces trois offres sont complètes et extrêmement bien intégrées aux
différentes plateformes, mais elles sont aussi propriétaires. Puisque
nous parlons de Symfony, il me semble important de souligner les
alternatives Open-Source, que sont :
-
OpenWhisk, un projet de
la fondation Apache. Il est important de noter que OpenWhisk est
disponible en version gérée par IBM.
Ce sont les IBM Cloud Functions.
-
OpenFaaS et
Fission sont tous
les deux basés sur l’utilisation de conteneurs Docker. Il vous
« suffit » d’un cluster Kubernetes
pour faire tourner ces deux plateformes.
PHP dans tout ça ?
Mises à part les alternatives Open-Source, PHP n’est pas vraiment l’ami
des trois gros « clouds ». Node.js et Go sont les
grands gagnants, PHP n’est même pas officiellement supporté par l’un
d’entre eux. La seule façon de lancer du PHP dans ces nuages consiste à
utiliser « shim.
On package le binaire de PHP dans la fonction, et on demande à un petit script Node de lancer le PHP
(je vous assure, c’est même dans leurs documentations officielles !).
Pourtant… PHP est fait pour ça ! PHP est fait pour lancer des scripts
très courts. Alors que de l’autre côté de la barrière, Node et Go ont
été conçus pour les scripts longs. Je n’ai pas la réponse au « pourquoi »
mais je trouve ça très étonnant.
Deployer notre application Symfony
Nous créerons et déployerons notre application Symfony 4 dans une
fonction OpenWhisk. Nous utilisons cette plateforme pour 3 raisons :
- C’est une plateforme de FaaS Open-Source,
- Elle supporte nativement PHP,
- Elle dispose d’une version pilotée sur le Cloud d’IBM.
Je vous encourage vivement à l'essayer par vous même avec IBM Cloud Functions.
C’est en effet gratuit pour les premiers 400,000 GB-seconds, ce qui est
bien plus qu’il n'en faut pour votre « side project » !.
-
Configurer
wsk
, le client OpenWhisk
Si vous suivez mon conseil, créez votre compte IBM Cloud et suivez
la documentation pour configurer "wsk”.
Sinon, configurez "wsk” par vous meme :)
-
Créer une application Symfony
Vous avez probablement lu le post de Nicolas,
et savez donc que l’on démarre une application Symfony 4 avec
composer
:
$ composer create-project symfony/skeleton my-app && cd my-app
-
Installer le « bridge OpenWhisk
$ composer req sroze/openwhisk-bundle
-
Préparer l’archive de l'application
$ zip -X -r ../my-app.zip * .env*
-
Créer ou mettre à jour la fonction
$ wsk action update skeleton-symfony --kind php:7.1 skeleton-symfony.zip --web true
-
Récupérer l’URL de la fonction
$ wsk action get skeleton-symfony --url</td>
Ouvrez la fonction et vous devriez avoir l’application !
Que s’est-il passé ?
Ces quelques étapes très simples pour déployer votre application Symfony
peuvent être troublantes. Détaillons ce qu’il s’est passé.
-
Vous avez configuré votre environnement local afin de parler au
serveur OpenWhisk. Rien de magique là dedans.
-
Vous avez créé une application Symfony. C’est très simple, c’est le
tout nouveau squelette Symfony. Je vous recommande
l’article de Nicolas pour en savoir plus sur Symfony 4.
-
Vous avez installé le pont OpenWhisk pour votre application Symfony.
C’est un paquet
et avant tout une recette pour Symfony Flex,
le nouveau système de gestion de configuration de Symfony. Cette
recette a créé un nouveau contrôleur frontral
(remplaçant votre
public/index.php
)
qui sera exécuté lorsque la fonction est invoquée dans le « cloud ».
Ce contrôleur frontral transforme la requête de type
OpenWhisk Web Action
en objet
HttpFoundation Request,
puis il réalise l'opération inverse pour la réponse.
-
Puisqu’une application Symfony est un ensemble de fichiers, nous
devons utiliser une application de type package.
Ce type d’application est tout simplement un fichier ZIP de votre
dossier.
-
Vous avez créé la fonction dans OpenWhisk. Typiquement, le fichier ZIP
a été téléchargé quelque part et rendu accessible aux conteneurs qui
lancent ensuite vos fichiers PHP. Vous avez également utilisé l'option
--web
qui précise à OpenWhisk de
faire en sorte que cette fonction soit accessible « depuis le web ».
-
Une fois la fonction créée, il ne vous reste plus qu’a récupérer
l’URL de la fonction pour l’exécuter.
« serverless », le framework
En général, vous ne déployez pas une seule fonction mais plusieurs. Vous
n'utiliserez pas que HTTP comme déclencheur de fonction mais aussi un
système de file (queue), un événement dans une base
de données, etc.
Gérer « manuellement » tous ces cas peut s'avérer être beaucoup de
travail, à la fois très répétitif et difficile à maintenir. C’est la
raison pour laquelle "serverless”
existe. Il s'agit d'un framework écrit en Node qui simplifie la gestion
de nos fonctions. Il fait aussi office de couche d'abstraction avec
OpenWhisk, AWS Lamba et toutes ces plateformes.
Installez serverless et son extension pour OpenWhisk,
puis créez le fichier serverless.yml
dans le dossier parent de l’application my-app
que avons
créé plus tôt :
service: my-project
provider:
name: openwhisk
runtime: php
package:
individually: true
functions:
first-app:
handler: my-app/index.main
2nd-app:
handler: 2nd-app/index.main
plugins:
- serverless-openwhisk
Déployez !
$ serverless deploy
Conclusion
J’espère que cet article vous a permis d’en savoir plus à propos de ces
« functions as a service ». Il est clair que ce
nouveau genre d’offre constitue un futur encore plus simple et moins
coûteux pour expérimenter diverses idées, tout en créant des
architectures dimensionnables naturellement. Les outils sont toujours
relativement expérimentaux et rares, mais je n’ai aucun doute
qu’ensemble nous pouvons améliorer les outils pour Symfony !
Happy serverlessing 😁