Serverless : Déployer une application Single Page (SPA) via OpenFaaS et K3S …
Tags: docker, serverless, rancher, kubernetes
Published: 2019-08-24 16:48:16

---
title: Serverless : Déployer une application Single Page (SPA) via OpenFaaS et K3S …
published: true
tags: docker,serverless,rancher,kubernetes
canonical_url: https://medium.com/@abenahmed1/serverless-d%C3%A9ployer-une-application-single-page-spa-via-openfaas-et-k3s-458a32957c0e
---

# Serverless : Déployer une application Single Page (SPA) via OpenFaaS et K3S …

![](https://cdn-images-1.medium.com/max/1024/1*R-8Zu_DV5g2bdz3fv3HyLA.jpeg)

Pour commencer cette expérience, déploiement d’un premier noeud Ubuntu 18.04 LTS de type CX11 (à 1 vCPU et 2 Go RAM) dans Hetzner Cloud :

![](https://cdn-images-1.medium.com/max/1024/1*1xcsMMGBpDejcHJuMXOxWQ.jpeg)

en utilisant K3S et ce fichier _cloud-init_ (en tant que noeud maître du cluster Kubernetes) :

- [k3s: Lightweight Kubernetes](https://k3s.io/)
- [Truly thrifty cloud hosting - Hetzner Online GmbH](https://www.hetzner.com/cloud)

![](https://cdn-images-1.medium.com/max/1024/1*_Yd_QAfZj_0i3aomZJb90Q.png)

![](https://cdn-images-1.medium.com/max/1024/1*vqD3MUUbu7Ln3vteuIgzKQ.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*ch6omo7gObjvlIXUXJOUPQ.jpeg)

Le noeud maître est prêt :

![](https://cdn-images-1.medium.com/max/1024/1*fJXFhFW3lB-m68mv_V0_jg.jpeg)

Puis je déploie trois autres noeuds Ubuntu 18.04 LTS (toujours de type CX11 à 1 vCPU et 2 Go de mémoire vive) via ce fichier _cloud-init_ :

![](https://cdn-images-1.medium.com/max/1024/1*ScJgvQv_go5HR1P7Y_S7bQ.png)

![](https://cdn-images-1.medium.com/max/1024/1*8cpeKCRG84IBlyW63epBjw.jpeg)

Le cluster Kubernetes est en fonction :

![](https://cdn-images-1.medium.com/max/1024/1*SdlGmLk_scpbF5gVkYqJGg.jpeg)

J’utilise comme d’habitude ZeroTier en conjonction de MetalLB pour assurer un service de Load Balancing dans ce cluster :

- [MetalLB](https://metallb.universe.tf/)
- [Download](https://www.zerotier.com/download/)

![](https://cdn-images-1.medium.com/max/1024/1*Z7LyTy_noDhdTsxOZqBa9A.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*mCtR1Uoc0AmYsYFVr7kY5g.jpeg)

```
$ kubectl apply -f [https://raw.githubusercontent.com/google/metallb/v0.8.1/manifests/metallb.yaml](https://raw.githubusercontent.com/google/metallb/v0.8.1/manifests/metallb.yaml)

$ kubectl apply -f config.yaml
```

![](https://cdn-images-1.medium.com/max/908/1*16lvRGlAJTUswbyPav2sYQ.png)<figcaption>config.yaml</figcaption>

Je récupère sur le noeud maître OpenFaaS CLI :

![](https://cdn-images-1.medium.com/max/1024/1*OJ_Fp9WIIiSAZd9Zw39LcQ.jpeg)

J’installe Helm :

[Helm - The Package Manager for Kubernetes.](https://helm.sh/docs/using_helm/#installing-helm)

```
$ curl -L https://git.io/get\_helm.sh | bash

$ kubectl --namespace kube-system create serviceaccount tiller

$ kubectl create clusterrolebinding tiller-cluster-rule \
 --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

$ kubectl --namespace kube-system patch deploy tiller-deploy \
 -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
```

et je peux alors déployer OpenFaaS dans le cluster :

[openfaas/faas-netes](https://github.com/openfaas/faas-netes/blob/master/chart/openfaas/README.md)

![](https://cdn-images-1.medium.com/max/1024/1*Mdjz9hJO9oIogvM0G4ur6w.png)

Via l’adresse IP fournie par le service de Load Balancing, je peux accéder au portail d’OpenFaaS :

![](https://cdn-images-1.medium.com/max/1024/1*b7BjQOtUctamBowibdY_TA.jpeg)

Je lance le déploiement de mon application Single Page (en l’occurence ici mon chatbot) :

- [deep75/pwafcbot](https://github.com/deep75/pwafcbot)
- [Serverless: Publier ses Progressive Web Apps avec les Azure Functions Proxies …](https://medium.com/@abenahmed1/serverless-publier-ses-progressive-web-apps-avec-les-azure-functions-proxies-65e400a973d1)

> via une fonction sur la base du template OpenFaaS (conçu par Alex Ellis) pour les sites statiques (utilisant Nginx pour servir le contenu). Celle-çi est d’abord construite localement sous la forme d’une image Docker qui sera poussée vers le Docker Hub (on peut également utiliser son Docker Registry privé) puis vers la plateforme OpenFaaS :

[alexellis/static-site-template](https://github.com/alexellis/static-site-template)

![](https://cdn-images-1.medium.com/max/1024/1*JeHnThBfZSdHxx2Pm1Z_GA.png)

![](https://cdn-images-1.medium.com/max/1024/1*8GYBaoUEanSrbr1l1EIr0A.png)

![](https://cdn-images-1.medium.com/max/892/1*D1j7ayMwtch3cmL57swcSw.png)<figcaption>vocalbot.yml</figcaption>

La fonction apparaît sur le portail OpenFaaS :

![](https://cdn-images-1.medium.com/max/1024/1*742CfziIhzIvwor21yUmQA.jpeg)

et je peux utiliser l’adresse fournie au moment du déploiement de la fonction pour accéder à mon chatbot :

![](https://cdn-images-1.medium.com/max/799/1*YbtUR2f5pJle1NJFEK3pvw.jpeg)

![](https://cdn-images-1.medium.com/max/702/0*rSs19Pty_iHdTFKa.jpg)

Une autre variante sur la base du template OpenFaaS Node.js 10 Express :

[openfaas-incubator/node10-express-template](https://github.com/openfaas-incubator/node10-express-template)

Je récupère le template et je crée ma nouvelle fonction en m’inspirant du projet Leaderboard-app d’Alex Ellis sur Github :

- [How to build a Serverless Single Page App](https://www.openfaas.com/blog/serverless-single-page-app/)
- [alexellis/leaderboard-app](https://github.com/alexellis/leaderboard-app)

![](https://cdn-images-1.medium.com/max/1024/1*ZwrdrzFcGBUDYvqeDukeuw.png)

Il utilise ce fichier _handler.js_ qui permet de pointer vers le répertoire contenant la page web du Chatbot :

![](https://cdn-images-1.medium.com/max/1024/1*i2ZJDfbkSmJ2HE5AVh4X4w.png)<figcaption>handler.js</figcaption>

avec cette dépendance minimale :

![](https://cdn-images-1.medium.com/max/1024/1*bkwlq1iuy7SsCBIWURoZ2A.png)<figcaption>package.json</figcaption>

Lancement de la construction de la nouvelle fonction :

![](https://cdn-images-1.medium.com/max/1024/1*RLmKGOXtScHkqFenzeVKxA.png)

Suivi de la phase de _“Push & Deploy”_ du Docker Hub vers OpenFaaS :

![](https://cdn-images-1.medium.com/max/1024/1*OMaSBbaCsdQfCE5MGC1EHw.png)

La fonction est déployée :

![](https://cdn-images-1.medium.com/max/1024/1*ZwrGO1V4TkxX2jOlNo7Jzw.jpeg)

L’adresse retournée me permet d’accéder une nouvelle fois vers le contenu statique du chatbot :

![](https://cdn-images-1.medium.com/max/792/1*kU9fnE3WmuFplVaRvu6AaA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*ghe6pamrkAQLMinh2_x07A.jpeg)

Je peux vérifier via le déploiement d’un petit serveur Rancher que le tout ne consomme pas beaucoup de ressources :

![](https://cdn-images-1.medium.com/max/1024/1*TUuo1gRi47MofYcVEDcpfg.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*sleZqKRjDlJ30gspe4KXqA.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*Upf6iKshUiZDRlzVCv3uFw.jpeg)

![](https://cdn-images-1.medium.com/max/1024/1*D_IIE9Q7ybm8Xa55X0mTzw.jpeg)

Alex Ellis propose d’aller plus loin avec une nouvelle stack PLONK apparemment soutenue par la Cloud Native Computing Foundation (CNCF) :

[Introducing the PLONK Stack for Cloud Native Developers](https://www.openfaas.com/blog/plonk-stack/)

![](https://cdn-images-1.medium.com/max/1024/0*WQtjqYDVozm_s7_x.jpg)

On retrouve là une ressemblance avec la stack FONK proposé sur Github par la société Serverless :

![](https://cdn-images-1.medium.com/max/654/0*yG_DIpbINhQyIPTl.jpeg)

- [FONK](http://fonk-apps.io/)
- [fonk-apps/fonk-examples](https://github.com/fonk-apps/fonk-examples/blob/master/deploy.md)
- [Introducing FONK: a serverless LAMP stack for K8S](https://serverless.com/blog/introducing-fonk/)

Comme le rappelle cet ancienne expérience que j’avais réalisée :

[Serverless : déploiement et test de la stack FONK (FaaS — Object store — NoSQL — Kubernetes) via…](https://medium.com/@abenahmed1/serverless-d%C3%A9ploiement-et-test-de-la-stack-fonk-faas-object-store-nosql-kubernetes-via-2b6ccf5ebf05)

A voir si la nouvelle stack PLONK permettra de populariser cette nouvelle génération d’architecture Web qui combine ces technologies dites “_Cloud Native”_ …

![](https://cdn-images-1.medium.com/max/604/0*5G8thvu0bc1ERciL.jpg)

A suivre !