One place for hosting & domains

      OpenFaaS

      Ausführen serverloser Funktionen mit OpenFaaS auf DigitalOcean Kubernetes


      Der Autor wählte den Free and Open Source Fund, um eine Spende im Rahmen des Programms Write for DOnations zu erhalten.

      Einführung

      Üblicherweise erfordert das Hosting einer Softwareanwendung im Internet Infrastrukturmanagement, Planung und Überwachung für ein monolithisches System. Im Gegensatz zu diesem traditionellen Ansatz gliedert die serverless Architektur (auch bekannt als Function as a Service oder FaaS) Ihre Anwendung in Funktionen auf. Bei diesen Funktionen handelt es sich um zustandslose, in sich geschlossene, ereignisausgelöste, funktional vollständige Entitäten, die über von Ihnen verwaltete APIs kommunizieren, statt über die zugrunde liegende Hardware und die explizite Bereitstellung der Infrastruktur. Die Funktionen sind vom Design her skalierbar, übertragbar, schneller einzurichten und einfacher zu testen als gewöhnliche Anwendungen. Damit die serverlose Architektur im Prinzip funktionieren kann, ist eine plattformunabhängige Art der Paketierung und Orchestrierung von Funktionen erforderlich.

      OpenFaaS ist ein Open-Source-Framework zur Implementierung der serverlosen Architektur auf Kubernetes, wobei Docker-Container zur Speicherung und Ausführung von Funktionen verwendet werden. Es ermöglicht die Paketierung eines beliebigen Programms als Container und die Verwaltung einer Funktion über die Befehlszeile oder die integrierte Web-Benutzeroberfläche. OpenFaaS verfügt über eine ausgezeichnete Unterstützung für Metriken und bietet eine automatische Skalierung der Funktionen bei steigender Nachfrage.

      In diesem Tutorial werden Sie OpenFaaS auf Ihrem DigitalOcean Kubernetes-Cluster in Ihrer Domäne einsetzen und es mit kostenlosen Let’s Encrypt TLS-Zertifikaten sichern. Sie werden auch die Web-Benutzeroberfläche erkunden und bestehende und neue Funktionen mithilfe von faas-cli, dem offiziellen Befehlszeilen-Tool, implementieren. Am Ende verfügen Sie über ein flexibles System für die Bereitstellung serverloser Funktionen.

      Voraussetzungen

      • Ein DigitalOcean Kubernetes-Cluster, bei dem Ihre Verbindung standardmäßig als kubectl konfiguriert ist. Der Cluster muss über mindestens 8 GB RAM und 4 für OpenFaaS verfügbare CPU-Cores verfügen (bei stärkerer Nutzung sind mehr erforderlich). Eine Anleitung zur Konfiguration von kubectl finden Sie unter dem Schritt Verbinden mit Ihrem Cluster, wenn Sie Ihren Cluster erstellen. Um einen Kubernetes-Cluster in DigitalOcean zu erstellen, lesen Sie unser Dokument Kubernetes Schnellstart.
      • Auf Ihrem lokalen Rechner installiertes Docker. Folgen Sie den Schritten 1 und 2 für Ihre Distribution in Installieren von Docker.
      • Einen Account bei Docker Hub zur Speicherung von Docker-Images, die Sie in diesem Tutorial erstellen werden.
      • Auf Ihrem lokalen Rechner installiertes faas-cli, das offizielle CLI-Tool zur Verwaltung von OpenFaaS. Anweisungen für mehrere Plattformen finden Sie in den offiziellen Dokumentationen.
      • Auf Ihrem lokalen Rechner installierten Helm-Paketmanager. Schließen Sie dazu Schritt 1 ab und fügen Sie das Repository stable von Schritt 2 des Tutorials Installieren von Software auf Kubernetes-Clustern mit dem Helm 3-Paketmanager hinzu.
      • In Ihrem Cluster mit Helm installierten Nginx Ingress Controller und Cert Manager, um OpenFaaS mit Ingress-Ressourcen freizugeben. Folgen Sie dazu den Anweisungen unter Einrichten eines Nginx Ingress unter DigitalOcean Kubernetes mit Helm.
      • Ein vollständig registrierter Domänenname zum Hosten von OpenFaaS, der auf den vom Nginx Ingress verwendeten Load Balancer verweist. Dieses Tutorial verwendet durchgehend openfaas.your_domain. Sie können einen Domänennamen unter Namecheap günstig erwerben oder einen kostenlosen von Freenom herunterladen oder einfach die Domänenregistrierungsstelle Ihrer Wahl verwenden.

      Anmerkung: Der von Ihnen in diesem Tutorial verwendete Domänenname muss sich von dem Domänennamen unterscheiden, der in dem vorbereitenden Tutorial Einrichten eines Nginx Ingress auf DigitalOcean Kubernetes verwendet wird.

      Schritt 1 – Installieren von OpenFaaS mit Helm

      In diesem Schritt installieren Sie OpenFaaS mit Helm auf Ihrem Kubernetes-Cluster und stellen es in Ihrer Domäne zur Verfügung.

      Als Teil der Voraussetzung des Nginx Ingress Controllers haben Sie Beispieldienste und einen Ingress erstellt. Sie werden sie in diesem Tutorial nicht benötigen, sodass Sie diese durch Ausführen der folgenden Befehle löschen können:

      • kubectl delete -f hello-kubernetes-first.yaml
      • kubectl delete -f hello-kubernetes-second.yaml
      • kubectl delete -f hello-kubernetes-ingress.yaml

      Da Sie Funktionen als Kubernetes-Objekte bereitstellen werden, ist es hilfreich, sie und OpenFaaS selbst in getrennten Namespaces in Ihrem Cluster zu speichern. Der Namespace von OpenFaaS wird als openfaas bezeichnet und der Namespace der Funktionen ist openfaas-fn. Erstellen Sie diese in Ihrem Cluster, indem Sie den folgenden Befehl ausführen:

      • kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml

      Sie sehen die folgende Ausgabe:

      Output

      namespace/openfaas created namespace/openfaas-fn created

      Als Nächstes müssen Sie das OpenFaaS Helm-Repository hinzufügen, das das OpenFaaS-Chart hostet. Führen Sie dazu folgenden Befehl aus:

      • helm repo add openfaas https://openfaas.github.io/faas-netes/

      Helm wird die folgende Ausgabe anzeigen:

      Output

      "openfaas" has been added to your repositories

      Aktualisieren Sie den Chart-Cache von Helm:

      Sie sehen die folgende Ausgabe:

      Output

      Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "openfaas" chart repository ...Successfully got an update from the "jetstack" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈

      Bevor Sie OpenFaaS installieren, müssen Sie Chart-Parameter anpassen. Sie werden diese auf Ihrem lokalen Rechner in einer Datei namens values.yaml speichern. Erstellen und öffnen Sie die Datei mit Ihrem Texteditor:

      Fügen Sie die folgenden Zeilen hinzu:

      values.yaml

      functionNamespace: openfaas-fn
      generateBasicAuth: true
      
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.class: "nginx"
        hosts:
          - host: openfaas.your_domain
            serviceName: gateway
            servicePort: 8080
            path: /
      

      Zuerst geben Sie den Namespace an, in dem Funktionen gespeichert werden, indem Sie openfaas-fn der Variablen functionNamespace zuweisen. Indem Sie generateBasicAuth auf true setzen, weisen Sie Helm an, eine obligatorische Authentifizierung beim Zugriff auf die OpenFaaS Web-Benutzeroberfläche einzurichten und eine Kombination von Admin-Benutzername und Passwort für Sie zu erzeugen.

      Dann aktivieren Sie die Ingress-Erstellung und konfigurieren sie weiter, um den Nginx Ingress-Controller zur Bereitstellung des OpenFaaS-Dienstes gateway in Ihrer Domäne zu verwenden.

      Denken Sie daran, openfaas.your_domain durch Ihre gewünschte Domäne aus den Voraussetzungen zu ersetzen. Wenn Sie fertig sind, speichern und schließen Sie die Datei.

      Installieren Sie zum Schluss OpenFaaS in den Namespace openfaas mit den angepassten Werten:

      • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

      Sie sehen die folgende Ausgabe:

      Output

      Release "openfaas" does not exist. Installing it now. NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

      Die Ausgabe zeigt, dass die Installation erfolgreich war. Führen Sie den folgenden Befehl aus, um das Passwort für den Account admin zu ermitteln:

      • echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode) | tee openfaas-password.txt

      Das entschlüsselte Passwort wird in die Ausgabe und gleichzeitig mit tee in eine Datei namens openfaas-password.txt geschrieben. Notieren Sie sich die Ausgabe, bei der es sich um Ihr OpenFaaS-Passwort für das Konto admin handelt.

      Durch Ausführen des folgenden Befehls können Sie beobachten, wie OpenFaaS-Container verfügbar werden:

      • kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"

      Wenn alle aufgelisteten Bereitstellungen ready sind, geben Sie zum Beenden STRG + C ein.

      Sie können nun in Ihrem Webbrowser zu der angegebenen Domäne navigieren. Geben Sie bei Aufforderung admin als Benutzername und das zugehörige Passwort ein. Sie sehen dann die Web-Benutzeroberfläche von OpenFaaS:

      OpenFaaS – Leeres Bedienfeld

      Sie haben OpenFaaS erfolgreich installiert und das Bedienfeld in Ihrer Domäne verfügbar gemacht. Als Nächstes sichern Sie es mit kostenlosen TLS-Zertifikaten von Let’s Encrypt.

      Schritt 2 – Aktivieren von TLS für Ihre Domäne

      In diesem Schritt sichern Sie Ihre ungeschützte Domäne mit Let’s Encrypt-Zertifikaten, die vom Zertifikatsmanager bereitgestellt werden.

      Dazu müssen Sie die Ingress-Konfiguration in values.yaml bearbeiten. Öffnen Sie sie zum Bearbeiten:

      Fügen Sie die hervorgehobenen Zeilen hinzu:

      values.yaml

      generateBasicAuth: true
      
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: letsencrypt-prod
        tls:
          - hosts:
              - openfaas.your_domain
            secretName: openfaas-crt
        hosts:
          - host: openfaas.your_domain
            serviceName: gateway
            servicePort: 8080
            path: /
      

      Der Block tls definiert, in welchem Secret die Zertifikate für ihre (unter hosts aufgelisteten) Seiten ihre Zertifikate speichern, die der ClusterIssuer letsencrypt-prod ausstellt. In der Regel muss das angegebene Secret für jeden Ingress in Ihrem Cluster unterschiedlich sein.

      Vergessen Sie nicht, openfaas.your_domain​​​ durch Ihre gewünschte Domäne zu ersetzen. Speichern und schließen Sie danach die Datei.

      Wenden Sie die Änderungen in Ihrem Cluster an, indem Sie folgenden Befehl ausführen:

      • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

      Sie sehen die folgende Ausgabe:

      Output

      Release "openfaas" has been upgraded. Happy Helming! NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 2 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

      Sie müssen einige Minuten warten, bis die Server von Let’s Encrypt ein Zertifikat für Ihre Domäne ausstellen. In der Zwischenzeit können Sie den Fortschritt verfolgen, indem Sie sich die Ausgabe des folgenden Befehls ansehen:

      • kubectl describe certificate openfaas-crt -n openfaas

      Das Ende der Ausgabe wird ähnlich wie dieses aussehen:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal GeneratedKey 24m cert-manager Generated a new private key Normal Requested 16m cert-manager Created new CertificateRequest resource "openfaas-crt-1017759607" Normal Issued 16m cert-manager Certificate issued successfully

      Wenn die letzte Ausgabezeile Certificate issued successfully lautet, können Sie die Ausgabe durch Drücken von STRG + C beenden. Sie sehen das Vorhängeschloss links neben der Adressleiste in Ihrem Browser, das anzeigt, dass Ihre Verbindung sicher ist.

      Sie haben Ihre OpenFaaS-Domäne mit kostenlosen TLS-Zertifikaten von Let’s Encrypt gesichert. Jetzt werden Sie die Web-Benutzeroberfläche verwenden und Funktionen von dort aus verwalten.

      Schritt 3 – Bereitstellen von Funktionen über die Web-Benutzeroberfläche

      In diesem Abschnitt werden Sie die Web-Benutzeroberfäche von OpenFaaS erkunden und dann Funktionen von dort bereitstellen, verwalten und aufrufen.

      Die Web-Benutzeroberfläche von OpenFaaS verfügt über zwei Hauptteile: Auf der linken Seite eine Spalte, in der die bereitgestellten Funktionen aufgelistet werden, und das zentrale Bedienfeld, in dem Sie detaillierte Informationen über eine ausgewählte Funktion sehen und mit dieser interagieren können.

      Um eine neue Funktion bereitzustellen, klicken Sie oben links unter dem OpenFaaS-Logo auf die Schaltfläche Deploy New Function. Es wird ein Dialogfeld angezeigt, in dem Sie aufgefordert werden, eine Funktion auszuwählen:

      OpenFaaS – Dialogfeld Bereitstellen einer neuen Funktion

      Die Registerkarte FROM STORE listet vorgefertigte Funktionen aus dem offiziellen OpenFaaS Function Store auf, die Sie sofort bereitstellen können. Jede Funktion wird mit einer kurzen Beschreibung angezeigt und Sie können das Link-Symbol rechts neben einer Funktion auswählen, um einen Blick auf ihren Quellcode zu werfen. Um eine Store-Funktion aus der Liste bereitzustellen, wählen Sie diese aus und klicken Sie dann auf die Schaltfläche DEPLOY.

      Sie können auch Ihre eigene Funktion bereitstellen, indem Sie zu der Registerkarte CUSTOM wechseln:

      OpenFaaS – Bereitstellen einer benutzerdefinierten Funktion

      Hier müssen Sie ein Docker-Image Ihrer Funktion angeben, das speziell für OpenFaaS konfiguriert und in einer Docker-Registrierung (wie z. B. Docker Hub) verfügbar ist. In diesem Schritt stellen Sie eine vorgefertigte Funktion aus dem OpenFaaS Store bereit. Im nächsten Schritt erstellen Sie benutzerdefinierte Funktionen und stellen diese im Docker Hub bereit.

      Sie stellen die Funktion NodeInfo bereit, die Informationen über den Rechner zurückgibt, auf dem sie bereitgestellt wird, wie CPU-Architektur, Anzahl der Cores, gesamt verfügbarer RAM-Speicher und Betriebszeit (in Sekunden).

      Wählen Sie aus der Liste der Store-Funktionen NodeInfo und klicken Sie auf DEPLOY. Es wird bald in der Liste der bereitgestellten Funktionen angezeigt.

      OpenFaaS – NodeInfo bereitgestellt

      Wählen Sie sie aus. Im mittleren Teil des Bildschirms sehen sie grundlegende Informationen über die bereitgestellte Funktion.

      OpenFaaS – Info über bereitgestellte Funktion

      Der Status der Funktion wird in Echtzeit aktualisiert und sollte schnell zu Ready wechseln. Wenn über längere Zeit Not Ready angezeigt wird, ist es sehr wahrscheinlich, dass Ihrem Cluster die Ressourcen fehlen, um einen neuen Pod zu akzeptieren. Im Abschnitt Größenänderung von Droplets finden Sie Informationen darüber, wie Sie dies beheben können.

      Sobald Ready erscheint, ist die bereitgestellte Funktion unter der angegebenen URL zugänglich. Um sie zu testen, können Sie in Ihrem Browser zu der URL navigieren oder sie über das Feld Invoke function aufrufen, das sich unter der Funktionsinfo befindet.

      OpenFaaS – Bereitgestellte Funktion aufrufen

      Sie können zwischen Text, JSON und Download wählen, um die Art der Antwort anzugeben, die Sie erwarten. Wenn Sie möchten, dass die Abfrage ein POST anstelle von GET ist, können Sie im Feld Request body Abfragedaten bereitstellen.

      Um die Funktion nodeinfo aufzurufen, klicken Sie auf die Schaltfläche INVOKE. OpenFaaS erstellt und führt eine HTTP-Abfrage gemäß den gewählten Optionen aus und füllt die Antwortfelder mit den empfangenen Daten aus.

      OpenFaaS – Antwort der Funktion nodeinfo

      Der Antwortstatus ist HTTP 200 OK. Das bedeutet, dass die Abfrage erfolgreich ausgeführt wurde. Response body enthält Systeminformationen, die die Funktion NodeInfo sammelt, d. h. sie ist zugänglich und funktioniert korrekt.

      Um eine Funktion zu löschen, wählen Sie sie aus der Liste aus und klicken Sie auf das Mülleimer-Symbol in der rechten oberen Ecke der Seite. Wenn Sie dazu aufgefordert werden, klicken Sie zur Bestätigung auf OK. Der Status der Funktion wechselt zu Not Ready (was bedeutet, dass sie aus dem Cluster entfernt wird) und die Funktion wird bald nicht mehr auf der Benutzeroberfläche vorhanden sein.

      In diesem Schritt haben Sie die Web-Benutzeroberfläche von OpenFaaS verwendet sowie Funktionen von dort bereitgestellt und verwaltet. Sie werden nun sehen, wie Sie OpenFaaS-Funktionen über die Befehlszeile bereitstellen und verwalten können.

      Schritt 4 – Verwalten von Funktionen mit faas-cli

      In diesem Abschnitt konfigurieren Sie die faas-cli für die Arbeit mit Ihrem Cluster. Anschließend werden Sie Ihre vorhandenen Funktionen über die Befehlszeile bereitstellen und verwalten.

      Um zu vermeiden, dass Sie Ihre OpenFaaS-Domäne bei jeder Ausführung der faas-cli angeben müssen, speichern Sie sie in einer Umgebungsvariable namens OPENFAAS_URL, deren Wert die faas-cli automatisch abholt und während der Ausführung verwendet.

      Öffnen Sie .bash_profile in Ihrem Stammverzeichnis zur Bearbeitung:

      Fügen Sie die folgende Zeile hinzu:

      ~/.bash_profile

      . . .
      export OPENFAAS_URL=https://openfaas.your_domain
      

      Denken Sie daran, openfaas.your_domain​​​ durch Ihre gewünschte Domäne zu ersetzen. Speichern und schließen Sie danach die Datei.

      Um sich nicht erneut anmelden zu müssen, werten Sie die Datei manuell aus:

      Stellen Sie nun sicher, dass Sie faas-cli auf Ihrem lokalen Rechner installiert haben. Falls Sie es noch nicht installiert haben, folgen Sie den Anleitungen in den offiziellen Dokumentationen.

      Richten Sie dann Ihre Anmeldedaten ein, indem Sie den folgenden Befehl ausführen:

      • cat ~/openfaas-password.txt | faas-cli login --username admin --password-stdin

      Die Ausgabe sieht ungefähr so aus:

      Output

      Calling the OpenFaaS server to validate the credentials... credentials saved for admin https://openfaas.your_domain

      Um eine Funktion aus dem Store bereitzustellen, führen Sie den folgenden Befehl aus:

      • faas store deploy function_name

      Sie können die Bereitstellung von nodeinfo versuchen, indem Sie Folgendes ausführen:

      • faas store deploy nodeinfo

      Sie sehen eine Ausgabe wie die folgende:

      Output

      Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/nodeinfo

      Um bereitgestellte Funktionen auflisten zu können, führen Sie faas list aus:

      Ihre vorhandenen Funktionen werden angezeigt:

      Output

      Function Invocations Replicas nodeinfo 0 1

      Um detaillierte Informationen über eine bereitgestellte Funktion zu erhalten, verwenden Sie faas describe:

      Die Ausgabe wird ähnlich dieser sein:

      Name:                nodeinfo
      Status:              Ready
      Replicas:            1
      Available replicas:  1
      Invocations:         0
      Image:               functions/nodeinfo-http:latest
      Function process:
      URL:                 https://openfaas.your_domain/function/nodeinfo
      Async URL:           https://openfaas.your_domain/async-function/nodeinfo
      Labels:              faas_function : nodeinfo
                           uid : 514253614
      Annotations:         prometheus.io.scrape : false
      

      Sie können eine Funktion mit faas invoke aufrufen:

      Sie erhalten die folgende Meldung:

      Output

      Reading from STDIN - hit (Control + D) to stop.

      Dann können Sie einen Request Body bereitstellen. Wenn Sie dies tun, ist die Methode POST anstelle von GET. Wenn Sie die Dateneingabe abgeschlossen haben oder die Anforderung GET sein soll, drücken Sie STRG + D. faas-cli führt dann die abgeleitete Abfrage aus und gibt die Antwort aus, ähnlich wie bei der Web-Benutzeroberfläche.

      Zum Löschen einer Funktion führen Sie faas remove aus:

      Sie erhalten die folgende Ausgabe:

      Output

      Deleting: nodeinfo. Removing old function.

      Führen Sie faas list erneut aus, um zu sehen, dass nodeinfo entfernt wurde.

      Output

      Function Invocations Replicas

      In diesem Schritt haben Sie Funktionen in Ihrem Cluster von der Befehlszeile aus mit Hilfe von faas-cli bereitgestellt, aufgelistet, aufgerufen und entfernt. im nächsten Schritt erstellen Sie Ihre eigene Funktion und stellen sie in Ihrem Cluster bereit.

      Schritt 5 – Erstellen und Bereitstellen einer neuen Funktion

      Erstellen Sie nun eine Beispielfunktion von Node.JS unter Verwendung von faas-cli und stellen Sie diese auf Ihrem Cluster bereit.

      Die daraus resultierende Funktion wird als Docker-Container gepackt und auf Docker Hub veröffentlicht. Um Container veröffentlichen zu können, müssen Sie sich anmelden, indem Sie den folgenden Befehl ausführen:

      Geben Sie Ihren Docker Hub-Benutzernamen und Ihr Passwort ein, wenn Sie zum Beenden des Anmeldevorgangs aufgefordert werden.

      Speichern Sie die Beispielfunktion Node.JS in einem Ordner namens sample-js-function. Erstellen Sie diese mit dem folgenden Befehl:

      Navigieren Sie dorthin:

      Füllen Sie das Verzeichnis mit der Vorlage einer JS-Funktion, indem Sie den folgenden Befehl ausführen:

      • faas new sample-js --lang node

      Die Ausgabe sieht in etwa folgendermaßen aus:

      Output

      2020/03/24 17:06:08 No templates found in current directory. 2020/03/24 17:06:08 Attempting to expand templates from https://github.com/openfaas/templates.git 2020/03/24 17:06:10 Fetched 19 template(s) : [csharp csharp-armhf dockerfile go go-armhf java11 java11-vert -x java8 node node-arm64 node-armhf node12 php7 python python-armhf python3 python3-armhf python3-debian ru by] from https://github.com/openfaas/templates.git Folder: sample-js created. ___ _____ ____ / _ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ / _ '_ | |_ / _` |/ _` ___ | |_| | |_) | __/ | | | _| (_| | (_| |___) | ___/| .__/ ___|_| |_|_| __,_|__,_|____/ |_| Function created in folder: sample-js Stack file written: sample-js.yml ...

      Wie in der Ausgabe geschrieben, befindet sich der Code für die Funktion selbst im Ordner sample-js, während sich die OpenFaaS-Konfiguration für die Funktion in der Datei sample-js.yaml befindet. Unter dem Verzeichnis sample-js (das einem regulären Node.JS-Projekt ähnelt) befinden sich zwei Dateien, handler.js und package.json.

      handler.js enthält tatsächlichen JS-Code, der eine Antwort zurückgibt, wenn die Funktion aufgerufen wird. Der Inhalt des Handlers sieht wie folgt aus:

      sample-js-function/sample-js/handler.js

      "use strict"
      
      module.exports = async (context, callback) => {
          return {status: "done"}
      }
      

      Er exportiert eine Lambda-Funktion mit zwei Parametern, einem Kontext mit Abfragedaten und einem Callback, mit dem Sie Antwortdaten zurückübergeben können, anstatt sie nur zurückzugeben.

      Öffnen Sie diese Datei zur Bearbeitung:

      • nano sample-js/handler.js

      Ändern Sie die hervorgehobene Zeile wie folgt:

      sample-js-function/sample-js/handler.js

      "use strict"
      
      module.exports = async (context, callback) => {
          return {status: "<h1>Hello Sammy!</h1>"}
      }
      

      Wenn Sie fertig sind, speichern und schließen Sie die Datei. Diese OpenFaaS-Funktion wird, wenn sie aufgerufen wird, Hello Sammy! in die Antwort schreiben.

      Öffnen Sie als Nächstes die Konfigurationsdatei zur Bearbeitung:

      Sie wird wie folgt aussehen:

      sample-js-function/sample-js.yml

      version: 1.0
      provider:
        name: openfaas
        gateway: https://openfaas.your_domain
      functions:
        sample-js:
          lang: node
          handler: ./sample-js
          image: sample-js:latest
      

      Für den provider gibt sie openfaas und ein Standard-Gateway an. Dann definiert sie die Funktion sample-js, gibt ihre Sprache (node), ihren Handler und den Namen des Docker-Image an, den Sie ändern müssen, um den Benutzernamen Ihres Docker Hub-Accounts einzufügen:

      sample-js-function/sample-js.yml

      version: 1.0
      provider:
        name: openfaas
        gateway: http://127.0.0.1:8080
      functions:
        sample-js:
          lang: node
          handler: ./sample-js
          image: your_docker_hub_username/sample-js:latest
      

      Speichern und schließen Sie die Datei.

      Erstellen Sie dann das Docker-Image, verschieben Sie es zum Docker-Hub und stellen Sie es in Ihrem Cluster bereit, und zwar gleichzeitig, indem Sie den folgenden Befehl ausführen:

      Es wird eine umfangreiche Ausgabe (hauptsächlich von Docker) erfolgen, die so endet:

      Output

      . . . [0] < Pushing sample-js [your_docker_hub_username/sample-js:latest] done. [0] Worker done. Deploying: sample-js. Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/sample-js

      Rufen Sie Ihre neu bereitgestellte Funktion auf, um sicherzustellen, dass sie funktioniert:

      Drücken Sie STRG + D. Sie sehen die folgende Ausgabe:

      Output

      <h1>Hello Sammy!</h1>

      Das bedeutet, dass die Funktion gepackt und korrekt bereitgestellt wurde.

      Sie können die Funktion entfernen, indem Sie Folgendes ausführen:

      Sie haben nun erfolgreich eine benutzerdefinierte Node.JS-Funktion auf Ihrer OpenFaaS-Instanz in Ihrem Cluster erstellt und bereitgestellt.

      Zusammenfassung

      Sie haben OpenFaaS auf Ihrem DigitalOcean Kubernetes-Cluster bereitgestellt und können nun sowohl vorgefertigte als auch benutzerdefinierte Funktionen bereitstellen. Jetzt sind Sie in der Lage, die Function-as-a-Service-Architektur zu implementieren, was die Ressourcennutzung erhöhen und Leistungsverbesserungen für Ihre Anwendungen bewirken kann.

      Wenn Sie mehr über erweiterte OpenFaaS-Funktionen erfahren möchten, wie z. B. die automatische Skalierung für Ihre eingesetzten Funktionen und die Überwachung ihrer Leistung, besuchen Sie die offizielle Dokumentation.



      Source link

      Выполнение бессерверных функций при помощи OpenFaas на DigitalOcean Kubernetes


      Автор выбрал фонд Free and Open Source Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Обычно для хостинга программного приложения в сети Интернет требуется наличие возможностей по управлению инфраструктурой, планированию и мониторингу для создания надежной системы. В отличие от такого традиционного подхода, бессерверная архитектура (также известная как function as a service или FaaS) разбивает ваше приложение на функции. Эти функции без сохранения состояния полностью независимы и срабатывают при событии. Контролируемое вами выполнение функций осуществляется через API, а не через явно выделенную инфраструктуру и базовые аппаратные средства. Функции обладают масштабируемой структурой, они портативны, их быстрее настроить и проверить по сравнению с обычными приложениями. Для работы бессерверной архитектуры в основном требуется независимый от платформы способ упаковки и контроля функций.

      OpenFaas – это система с открытым исходным кодом для внедрения бессерверной архитектуры на Kubernetes с использованием контейнеров Docker для хранения и запуска функций. Она позволяет упаковать любую программу в контейнер и обеспечить ее работу в виде функции с помощью командной строки или интегрированного веб-интерфейса пользователя. OpenFaaS отлично поддерживает метрику и автоматически масштабирует функции при увеличении нагрузки.

      В этом руководстве вы развернете OpenFaaS в кластере DigitalOcean Kubernetes на вашем домене и защитите ее при помощи сертификатов TLS от Let’s Encrypt. Вы также познакомитесь с веб-интерфейсом пользователя и развернете существующие и новые функции при помощи официального инструмента командной строки faas-cli. В результате вы получите гибкую систему для развертывания бессерверных функций.

      Предварительные требования

      • Кластер DigitalOcean Kubernetes с вашим подключением, настроенным с помощью kubectl по умолчанию. Кластер должен иметь минимум 8 Гб ОЗУ и 4 ядра процессора для работы OpenFaas (или более при увеличенной нагрузке). Инструкции по настройке kubectl описаны в шаге Подключение кластера, где вы создадите ваш кластер. Процесс создания кластера Kubernetes в DigitalOcean, см. Быстрое начало работы с Kubernetes.
      • Docker, установленный на вашем компьютере. В дополнение к шагам 1 и 2 см. Установка Docker.
      • В этом руководстве вы создадите учетную запись Docker Hub для хранения образов Docker.
      • faas-cli,официальный инструмент командной строки для управления OpenFaaS, установленный на вашем компьютере. Инструкции для различных платформ содержатся в официальной документации.
      • Диспетчер пакетов Helm, установленный на вашем компьютере. Для этого выполните шаг 1 и добавьте репозиторий stable из шага 2 из руководства Установка программного обеспечения в кластерах Kubernetes с помощью диспетчера пакетов Helm 3.
      • Nginx Ingress-контроллер и Cert-Manager, установленные на вашем кластере с помощью Helm, для опубликования OpenFaaS с использованием ресурсов Ingress. Инструкции содержатся в Настройка Nginx Ingress на DigitalOcean Kubernetes с помощью Helm.
      • Зарегистрированное полное доменное имя для хостинга OpenFaaS, указывающее на средство балансировки нагрузки, используемое в Nginx Ingress. В этом руководстве мы будем использовать имя openfaas.your_domain. Вы можете купить доменное имя на Namecheap, получить его бесплатно на Freenom или воспользоваться услугами любого предпочитаемого регистратора доменных имен.

      Примечание. Доменное имя, которое вы будете использовать в этом руководстве, должно отличаться от имени из предварительного руководства “Настройка Nginx Ingress на DigitalOcean Kubernetes с помощью Helm”.

      Шаг 1 — Установка OpenFaaS с помощью Helm

      На этом шаге вы установите OpenFaaS для кластера Kubernetes с помощью Helm и опубликуете ее на вашем домене.

      В предварительном руководстве по контроллеру Nginx Ingress вы создали образцы Services и Ingress. Они не нужны в этом руководстве, удалите их, выполнив следующие команды:

      • kubectl delete -f hello-kubernetes-first.yaml
      • kubectl delete -f hello-kubernetes-second.yaml
      • kubectl delete -f hello-kubernetes-ingress.yaml

      Поскольку вы развертываете функции в виде объектов Kubernetes, сохраняйте их и OpenFaaS в отдельных пространствах имен в вашем кластере. Пространство имен для OpenFaaS будет называться openfaas, а пространство имен для функций openfaas-fn. Создайте пространства в кластере, выполнив следующую команду:

      • kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml

      Вывод должен выглядеть так:

      Output

      namespace/openfaas created namespace/openfaas-fn created

      Далее вам необходимо добавить репозиторий OpenFaaS в Helm для хостинга чарта OpenFaaS. Для этого запустите следующую команду:

      • helm repo add openfaas https://openfaas.github.io/faas-netes/

      В результате в Helm появится следующее:

      Output

      "openfaas" has been added to your repositories

      Обновите кэш чарта в Helm:

      Вывод должен выглядеть так:

      Output

      Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "openfaas" chart repository ...Successfully got an update from the "jetstack" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈

      Перед установкой OpenFaaS вам необходимо настроить некоторые параметры чарта. Параметры хранятся в файле values.yaml на вашем компьютере. Создайте и откройте этот файл в текстовом редакторе:

      Добавьте следующие строки:

      values.yaml

      functionNamespace: openfaas-fn
      generateBasicAuth: true
      
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.class: "nginx"
        hosts:
          - host: openfaas.your_domain
            serviceName: gateway
            servicePort: 8080
            path: /
      

      Сначала укажите пространство имен для сохранения функций, присвоив значение openfaas-fn​​​​​​ переменной functionNamespace. Установка значения true для generateBasicAuth приведет к тому, что Helm будет запрашивать обязательную аутентификацию при доступе к веб-интерфейсу пользователя OpenFaaS и создаст имя администратора и пароль для доступа.

      Далее активируйте создание Ingress и продолжите настройку конфигурации для использования контроллера Nginx Ingress и обслуживания шлюза OpenFaaS на вашем домене.

      Замените openfaas.your_domain на предпочтительный для вас домен из предварительного руководства. После внесения изменений сохраните и закройте файл.

      Установите OpenFaaS в пространство имен openfaas с заданными значениями:

      • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

      Результат будет выглядеть следующим образом:

      Output

      Release "openfaas" does not exist. Installing it now. NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

      В результате вам сообщат, что установка выполнена успешно. Выполните следующую команду для получения пароля для учетной записи admin.

      • echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode) | tee openfaas-password.txt

      В результате вы получите декодированный пароль, который будет одновременно записан в файл openfaas-password.txt при помощи tee. Запомните пароль для учетной записи admin в OpenFaas.

      Для отображения контейнеров OpenFaaS выполните следующую команду:

      • kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"

      Когда все перечисленные развертывания получат статус ready, нажмите CTRL + C для выхода.

      Далее перейдите к домену через ваш веб-браузер. При запросе введите имя пользователя admin и соответствующий пароль. Вы увидите веб-интерфейс пользователя OpenFaaS:

      OpenFaaS — пустая панель управления

      Вы успешно установили OpenFaaS и опубликовали ее панель управления в вашем домене. Защитите ее при помощи сертификатов TLS от Let’s Encrypt.

      Шаг 2 — Активация TLS для вашего домена

      На этом шаге вы защитите ваш опубликованный домен при помощи сертификатов Let’s Encrypt от Cert-Manager.

      Измените конфигурацию Ingress в values.yaml. Откройте его для редактирования:

      Добавьте выделенные строки:

      values.yaml

      generateBasicAuth: true
      
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: letsencrypt-prod
        tls:
          - hosts:
              - openfaas.your_domain
            secretName: openfaas-crt
        hosts:
          - host: openfaas.your_domain
            serviceName: gateway
            servicePort: 8080
            path: /
      

      В блоке tls определяется Secret, где сертификаты для ваших сайтов (перечислены под hosts) будут сохранять сертификаты, выпущенные letsencrypt-prod ClusterIssuer. В общем, каждый Ingress в вашем кластере должен иметь свой Secret.

      Замените openfaas.your_domain на желаемый домен, а затем сохраните и закройте файл.

      Примените изменения, внесенные в ваш кластер, с помощью следующей команды:

      • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

      Вывод должен выглядеть так:

      Output

      Release "openfaas" has been upgraded. Happy Helming! NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 2 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

      Дождитесь, пока серверы Let’s Encrypt выпустят сертификат для вашего домена. Обычно это занимает несколько минут. Вы можете отслеживать прогресс выполнения задачи при помощи следующей команды:

      • kubectl describe certificate openfaas-crt -n openfaas

      Конечная часть полученного результата будет выглядеть примерно так:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal GeneratedKey 24m cert-manager Generated a new private key Normal Requested 16m cert-manager Created new CertificateRequest resource "openfaas-crt-1017759607" Normal Issued 16m cert-manager Certificate issued successfully

      Когда в последней строке полученного результата отобразится Certificate issued successfully​​​, выполните выход, нажав CTRL + C. Обновите домен в браузере для тестирования. Слева от адресной строки появится замок, это будет обозначать, что ваше соединение защищено.

      Вы защитили ваш домен OpenFaaS при помощи бесплатных сертификатов TLS от Let’s Encrypt. Далее вы сможете использовать веб-интерфейс пользователя для управления функциями.

      Шаг 3 — Развертывание функций через веб-интерфейс пользователя

      В этом разделе вы познакомитесь с веб-интерфейсом пользователя OpenFaaS, научитесь разворачивать, управлять и вызывать функции.

      Веб-интерфейс пользователя OpenFaaS состоит из двух частей: в левой части указаны все развернутые функции, а в центральной части находится подробная информация о выбранной функции, с которой можно взаимодействовать.

      Для развертывания новой функции нажмите кнопку Deploy New Function под логотипом OpenFaaS вверху слева. На экране появится диалоговое окно, где вас попросят выбрать функцию:

      OpenFaaS — диалоговое окно для развертывания новой функции

      На вкладке FROM STORE находятся готовые функции из официального магазина функций OpenFaaS. Вы можете использовать их. Каждая функция имеет короткое описание, также можно увидеть исходный код, нажав на значок ссылки справа от нужной функции. Для развертывания функции из списка в магазине, выберите ее, а затем нажмите кнопку DEPLOY.

      Вы можете также использовать собственную функцию, для этого перейдите на вкладку CUSTOM:

      OpenFaaS - Развертывание пользовательской функции

      Здесь необходимо указать образ Docker вашей функции, специально настроенный для OpenFaaS и доступный в реестре Docker (например в Docker Hub). На этом шаге вы развернете готовую функцию из магазина OpenFaaS, далее вы научитесь создавать и разворачивать пользовательские функции в Docker Hub.

      Вы развернете функцию NodeInfo, которая возвращает информацию о компьютере, где она развернута. Информация может включать, например, данные об архитектуре ЦП, количестве ядер, общем объеме ОЗУ и времени работы (в секундах).

      Выберите NodeInfo из списка готовых функций в магазине и нажмите DEPLOY. На экране появится список развернутых функций.

      OpenFaaS - Развернутая функция NodeInfo

      Выберите развернутую функцию в центральной части экрана, чтобы получить основную информацию о ней.

      OpenFaaS - Информация о развернутой функции

      Статус функции обновляется в режиме реального времени и должен быстро переключиться на Ready. Если статус Not Ready сохраняется, это может означать, что в вашем кластере недостаточно ресурсов для приема нового пода. См. Как изменить размер дроплета для решения этой проблемы.

      После появления Ready развернутая функция станет доступна по указанному URL-адресу. Для проверки перейдите по URL в вашем браузере, или выполните вызов функции с панели Invoke function под информацией о функции.

      OpenFaaS — вызов развернутой функции

      Вы можете выбирать между Text, JSON и Download, чтобы указать тип ожидаемого ответа. Если необходим запрос POST вместо GET, введите данные по запросу в поле Request body.

      Для вызова функции nodeinfo нажмите кнопку INVOKE. OpenFaaS создаст и выполнит запрос HTTP согласно выбранным опциям, а также заполнит поля ответа полученными данными.

      OpenFaaS - Ответ функции nodeinfo

      Ответ HTTP 200 OK означает, что запрос был выполнен успешно. Тело ответа будет содержать системную информацию, собранную функцией NodeInfo. Это будет означать, что функция доступна и работает правильно.

      Для удаления функции выберите ее из списка и нажмите на значок корзины в правом верхнем углу страницы. Нажмите OK при запросе для подтверждения действия. После чего статус функции изменится на Not Ready​​​ (это будет означать, что функция была удалена из кластера).В скором времени функция пропадет из пользовательского интерфейса.

      На этом шаге вы использовали веб-интерфейс пользователя OpenFaaS для развертывания и управления функциями. Далее вы научитесь развертывать и управлять функциями OpenFaaS при помощи командной строки.

      Шаг 4 — Управление функциями с помощью faas-cli

      В этом разделе вы настроите faas-cli для работы с вашим кластером. Далее вы научитесь развертывать и управлять функциями с помощью командной строки.

      Сохраните домен OpenFaas в переменной среды OPENFAAS_URL, чтобы не указывать его при каждом использовании faas-cli. Значение домена будет автоматически браться из переменной среды и использоваться во время выполнения функции.

      Откройте .bash_profile в вашей домашней директории для редактирования:

      Добавьте следующую строку:

      ~/.bash_profile

      . . .
      export OPENFAAS_URL=https://openfaas.your_domain
      

      Замените openfaas.your_domain на желаемый домен, а затем сохраните и закройте файл.

      Чтобы не входить в систему еще раз, самостоятельно оцените файл:

      Убедитесь, что faas-cli установлен на вашем компьютере. Если он не установлен, следуйте инструкциям из официальной документации.

      Настройте ваши учетные данные для входа, выполнив следующую команду:

      • cat ~/openfaas-password.txt | faas-cli login --username admin --password-stdin

      Вывод будет выглядеть следующим образом:

      Output

      Calling the OpenFaaS server to validate the credentials... credentials saved for admin https://openfaas.your_domain

      Для развертывания функции из магазина, выполните следующую команду:

      • faas store deploy function_name

      Разверните nodeinfo, выполнив:

      • faas store deploy nodeinfo

      Результат будет выглядеть примерно следующим образом:

      Output

      Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/nodeinfo

      Для получения списка развернутых функций выполните faas list​​​:

      На экране появятся установленные функции:

      Output

      Function Invocations Replicas nodeinfo 0 1

      Для подробной информации по развернутой функции выполните faas describe:

      Результат будет выглядеть примерно следующим образом:

      Name:                nodeinfo
      Status:              Ready
      Replicas:            1
      Available replicas:  1
      Invocations:         0
      Image:               functions/nodeinfo-http:latest
      Function process:
      URL:                 https://openfaas.your_domain/function/nodeinfo
      Async URL:           https://openfaas.your_domain/async-function/nodeinfo
      Labels:              faas_function : nodeinfo
                           uid : 514253614
      Annotations:         prometheus.io.scrape : false
      

      Для вызова функции выполните faas invoke​​​:

      На экране появится следующее сообщение:

      Output

      Reading from STDIN - hit (Control + D) to stop.

      Далее можно сделать запрос. Для запроса используйте POST вместо GET. После ввода данных или в случае, если вы захотите сделать запрос GET, нажмите CTRL + D. Интерфейс faas-cli выполнит необходимый запрос и отобразит ответ наподобие ответа веб-интерфейса пользователя.

      Для удаления функции выполните faas remove:

      На экране появится следующее сообщение:

      Output

      Deleting: nodeinfo. Removing old function.

      Выполните faas list​​​ еще раз, чтобы убедится в удалении nodeinfo:

      Output

      Function Invocations Replicas

      На этом шаге вы научились развертывать, выводить в виде списка, вызывать и удалять функции в кластере при помощи командной строки faas-cli. На следующем шаге вы создадите свою функцию и развернете ее в кластере.

      Шаг 5 — Создание и развертывание новой функции

      Сейчас вы создадите образец функции Node.JS при помощи командной строки faas-cli и развернете его в кластере.

      Созданная функция будет упакована в виде контейнера Docker и опубликована в Docker Hub. Для публикования контейнеров войдите в систему, выполнив следующую команду:

      Для завершения процесса входа введите ваше имя пользователя и пароль Docker Hub.

      Образец функции Node.JS сохраняется в папке sample-js-function​​​. Создайте файл с помощью следующей команды:

      Перейдите в директорию:

      Поместите шаблон JS функции в директорию, выполнив следующую команду:

      • faas new sample-js --lang node

      Итоговый результат будет выглядеть следующим образом:

      Output

      2020/03/24 17:06:08 No templates found in current directory. 2020/03/24 17:06:08 Attempting to expand templates from https://github.com/openfaas/templates.git 2020/03/24 17:06:10 Fetched 19 template(s) : [csharp csharp-armhf dockerfile go go-armhf java11 java11-vert -x java8 node node-arm64 node-armhf node12 php7 python python-armhf python3 python3-armhf python3-debian ru by] from https://github.com/openfaas/templates.git Folder: sample-js created. ___ _____ ____ / _ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ / _ '_ | |_ / _` |/ _` ___ | |_| | |_) | __/ | | | _| (_| | (_| |___) | ___/| .__/ ___|_| |_|_| __,_|__,_|____/ |_| Function created in folder: sample-js Stack file written: sample-js.yml ...

      Код самой функции находится в папке sample-js​​​, а конфигурация OpenFaas для нее в файле sample-js.yaml​​​. В директории sample-js (которая напоминает обычный проект Node.JS) находятся два файла — handler.js и package.json.

      handler.js​​​ содержит фактический код JS для возврата ответа при вызове функции. Содержимое handler выглядит следующим образом:

      sample-js-function/sample-js/handler.js

      "use strict"
      
      module.exports = async (context, callback) => {
          return {status: "done"}
      }
      

      Он экспортирует lambda function с двумя параметрами, context с данными запроса и callback, которые вы можете использовать для обратной передачи данных запроса вместо выполнения обычного возврата.

      Откройте этот файл для редактирования:

      • nano sample-js/handler.js

      Измените выделенную строку следующим образом:

      sample-js-function/sample-js/handler.js

      "use strict"
      
      module.exports = async (context, callback) => {
          return {status: "<h1>Hello Sammy!</h1>"}
      }
      

      После внесения изменений сохраните и закройте файл. При вызове этой функции OpenFaaS на экране появится сообщение Hello Sammy!​​​ в ответ на запрос.

      Далее откройте файл конфигурации для редактирования:

      Он будет выглядеть следующим образом:

      sample-js-function/sample-js.yml

      version: 1.0
      provider:
        name: openfaas
        gateway: https://openfaas.your_domain
      functions:
        sample-js:
          lang: node
          handler: ./sample-js
          image: sample-js:latest
      

      Он определяет openfaas и шлюз по умолчанию для provider. Затем определяет функцию sample-js, ее язык (node), handler и имя образа Docker, которые необходимо изменить для включения вашего имени пользователя учетной записи Docker Hub, например:

      sample-js-function/sample-js.yml

      version: 1.0
      provider:
        name: openfaas
        gateway: http://127.0.0.1:8080
      functions:
        sample-js:
          lang: node
          handler: ./sample-js
          image: your_docker_hub_username/sample-js:latest
      

      Сохраните и закройте файл.

      Создайте образ Docker, переместите его в Docker Hub и разверните в вашем кластере. Выполните все действия одновременно, используя следующую команду:

      На экране появится большой объем данных (в основном из Docker), которые будут завершаться примерно следующим:

      Output

      . . . [0] < Pushing sample-js [your_docker_hub_username/sample-js:latest] done. [0] Worker done. Deploying: sample-js. Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/sample-js

      Вызовите вашу новую развернутую функцию, чтобы проверить, что она работает:

      Нажмите CTRL + D. На экране появится следующее:

      Output

      <h1>Hello Sammy!</h1>

      Это означает, что функция упакована и развернута правильно.

      Вы можете удалить функцию, выполнив команду:

      Вы успешно создали и развернули пользовательскую функцию Node.JS в OpenFaaS в вашем кластере.

      Заключение

      Вы развернули OpenFaaS в вашем кластере DigitalOcean Kubernetes и готовы развернуть и начать пользоваться как готовыми, так и пользовательскими функциями. Вы научились внедрять архитектуру Function as a Service, которая поможет вам оптимизировать использование ресурсов и увеличит производительность ваших приложений.

      Подробная информация по продвинутым возможностям OpenFaaS, например, по автоматическому масштабированию развернутых функций и мониторингу их работы содержится в официальной документации.



      Source link

      Cómo ejecutar funciones sin servidores usando OpenFAaS en Kubernetes de DigitalOcean


      El autor seleccionó la Free and Open Source Fund para recibir una donación como parte del programa Write for DOnations.

      Introducción

      Normalmente, para alojar una aplicación de software en Internet se requiere gestión, planificación y seguimiento de infraestructuras para un sistema monolítico. A diferencia de este enfoque tradicional, la arquitectura sin servidores (también conocida como función como servicio o “FaaS”) descompone su aplicación en funciones. Estas funciones son entidades sin estados previos, autocontenidas, incluso activadas y funcionalmente completas que se comunican a través de las API que gestiona en lugar del aprovisionamiento de hardware subyacente o infraestructuras explícitas. Las funciones son escalables por diseño, portátiles, de configuración más rápida y más fáciles de probar que las aplicaciones comunes. Para funcionar, la arquitectura sin servidor en principio requiere un método para encapsular y organizar funciones independiente de la plataforma.

      OpenFaaS es un marco de código abierto que permite implementar la arquitectura sin servidor en Kubernetes usando contenedores de Docker para almacenar y ejecutar funciones. Permite que cualquier programa se encapsule como un contenedor y se administre como una función a través de la línea de comandos o la IU web integrada. OpenFaaS tiene una excelente compatibilidad para métricas y ofrece autoescalado para funciones cuando se incrementa la demanda.

      A través de este tutorial, implementará OpenFaaS a su clúster de Kubernetes de DigitalOcean en su dominio y lo protegerá usando certificados TLS gratuitos de Let’s Encrypt. También explorará su IU web e implementará funciones existentes y nuevas usando faas-cli, la herramienta de línea de comandos oficial. Al final, tendrá un sistema flexible para implementar funciones sin servidor.

      Requisitos previos

      • Un clúster de Kubernetes de DigitalOcean con su conexión configurada como kubectl predeterminado. El clúster debe tener al menos 8 GB de RAM y 4 núcleos de CPU disponibles para OpenFAaS (necesitará más si el uso es mayor). Verá las instrucciones para configurar kubectl en el paso Establecer conexión con su clúster cuando cree su clúster. Para crear un clúster de Kubernetes en DigitalOcean, consulte la Guía de inicio rápido de Kubernetes.
      • Docker instalado en su máquina local. Siguiendo los pasos 1 y 2 para su distribución, consulte Cómo instalar Docker.
      • Una cuenta en Docker Hub para almacenar imágenes de Docker que creará durante este tutorial.
      • faas-cli, la herramienta oficial de CLI para gestionar OpenFaaS, debe estar instalada en su máquina local. Si desea acceder a instrucciones para varias plataformas, consulte los documentos oficiales.
      • Un administrador de paquetes de Helm instalado en su máquina local. Para ello, complete el paso 1 y añada el repositorio stable del paso 2 del tutorial Cómo instalar software en clústeres de Kubernetes con el gestor de paquetes de Helm 3.
      • El controlador de Ingress de Nginx y Cert-Manager instalados en su clúster usando Helm para exponer OpenFaaS usando los recursos de Ingress. Para hacerlo, consulte Cómo configurar un Ingress de Nginx en Kubernetes de DigitalOcean usando Helm.
      • Un nombre de dominio registrado por completo para alojar OpenFaaS apuntando al equilibrador de carga utilizado por el Ingress de Nginx. Para este tutorial, se utilizará openfaas.your_domain en todo momento. Puede adquirir un nombre de dominio en Namecheap, obtener uno gratuito en Freenom o utilizar un registrador de dominios que elija.

      Nota: El nombre de dominio que use en este tutorial debe ser distinto del que use en el tutorial “Cómo configurar un Ingress de Nginx en Kubernetes de DigitalOcean”, de los requisitos previos.

      Paso 1: Instalar OpenFAaS usando Helm

      En este paso, instalará OpenFaaS en su clúster de Kubernetes usando Helm y lo expondrá en su dominio.

      Como parte del requisito previo del controlador de Ingress de Nginx, creó servicios de ejemplo y un Ingress. No los necesitará en este tutorial, por lo que puede eliminarlos ejecutando los siguientes comandos:

      • kubectl delete -f hello-kubernetes-first.yaml
      • kubectl delete -f hello-kubernetes-second.yaml
      • kubectl delete -f hello-kubernetes-ingress.yaml

      Debido a que implementará funciones como objetos de Kubernetes, le resultará útil almacenarlas y hacer lo mismo con el propio OpenFaaS en espacios de nombres separados en su clúster. El espacio de nombre de OpenFaaS se llamará openfaas y el de las funciones se llamará openfaas-fn. Créelos en su clúster ejecutando el siguiente comando:

      • kubectl apply -f https://raw.githubusercontent.com/openfaas/faas-netes/master/namespaces.yml

      Verá el siguiente resultado:

      Output

      namespace/openfaas created namespace/openfaas-fn created

      A continuación, deberá añadir el repositorio de Helm de OpenFaaS, en el que se aloja el chart de OpenFaaS. Para hacer esto, ejecute el siguiente comando:

      • helm repo add openfaas https://openfaas.github.io/faas-netes/

      Helm mostrará el siguiente resultado:

      Output

      "openfaas" has been added to your repositories

      Actualice la caché del chart de Helm:

      Verá el siguiente resultado:

      Output

      Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "openfaas" chart repository ...Successfully got an update from the "jetstack" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈ Happy Helming!⎈

      Antes de instalar OpenFaaS, deberá personalizar algunos parámetros del chart. Los almacenará en su máquina local, en un archivo llamado values.yaml. Cree y abra el archivo con su editor de texto:

      Añada las siguientes líneas:

      values.yaml

      functionNamespace: openfaas-fn
      generateBasicAuth: true
      
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.class: "nginx"
        hosts:
          - host: openfaas.your_domain
            serviceName: gateway
            servicePort: 8080
            path: /
      

      Primero, especifique el espacio de nombre donde se almacenarán las funciones asignando openfaas-fn a la variable functionNamespace. Al fijar generateBasicAuth en el valor true, ordenará a Helm que configure la autenticación obligatoria cuando acceda a la IU web de OpenFaaS y que genere una combinación de nombre de usuario y contraseña de administrador para usted.

      A continuación, habilite la creación de Ingress y configúrelo para que use el controlador de Ingress de Nginx y proporcione el servicio de OpenFaaS gateway en su dominio.

      Recuerde sustituir openfaas.your_domain por el dominio que desee de los requisitos previos. Cuando termine, guarde y cierre el archivo.

      Por último, instale OpenFaaS en el espacio de nombres openfass con los valores personalizados:

      • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

      Verá lo siguiente:

      Output

      Release "openfaas" does not exist. Installing it now. NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

      Según se muestra en el resultado, la instalación se realizó correctamente. Ejecute el siguiente comando para ver la contraseña de la cuenta admin:

      • echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode) | tee openfaas-password.txt

      La contraseña decodificada se escribe en el resultado y en un archivo llamado openfaas-password.txt al mismo tiempo usando tee. En el resultado, verá que esa es su contraseña de OpenFaaS para la cuenta admin.

      Puede ver los contenedores de OpenFaaS disponibles ejecutando el siguiente comando:

      • kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas"

      Cuando todas las implementaciones se muestren como ready, escriba CTRL + C para salir.

      Ahora podrá dirigirse al dominio especificado en su navegador web. Introduzca admin como nombre de usuario y la contraseña correspondiente cuando se le solicite. Verá la IU web de OpenFaaS:

      OpenFaaS: panel de control vacío

      Instaló OpenFaaS correctamente y expuso su panel de control en su dominio. A continuación, lo protegerá usando certificados TLS gratuitos de Let´s Encrypt.

      Paso 2: Habilitar TLS para su dominio

      En este paso, protegerá su dominio expuesto usando certificados de Let´s Encrypt proporcionados por cert-manager.

      Para hacerlo, deberá editar la configuración de ingress en values.yaml. Ábralo​​​ para editarlo:

      Añada las líneas destacadas:

      values.yaml

      generateBasicAuth: true
      
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.class: "nginx"
          cert-manager.io/cluster-issuer: letsencrypt-prod
        tls:
          - hosts:
              - openfaas.your_domain
            secretName: openfaas-crt
        hosts:
          - host: openfaas.your_domain
            serviceName: gateway
            servicePort: 8080
            path: /
      

      El bloque tls define el secreto en el que se almacenarán los certificados de sus sitios (enumerados en hosts), lo que el ClusterIssuer letsencrypt-prod emite. Normalmente, el Secret especificado debe ser diferente para cada Ingress de su clúster.

      Recuerde sustituir openfaas.your_domain por el dominio que desee, y luego guarde y cierre el archivo.

      Aplique los cambios a su clúster ejecutando el siguiente comando:

      • helm upgrade openfaas --install openfaas/openfaas --namespace openfaas -f values.yaml

      Verá el siguiente resultado:

      Output

      Release "openfaas" has been upgraded. Happy Helming! NAME: openfaas LAST DEPLOYED: ... NAMESPACE: openfaas STATUS: deployed REVISION: 2 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l "release=openfaas, app=openfaas" To retrieve the admin password, run: echo $(kubectl -n openfaas get secret basic-auth -o jsonpath="{.data.basic-auth-password}" | base64 --decode)

      Deberá esperar unos minutos para que los servidores de Let´s Encrypt emitan un certificado para su dominio. Mientras tanto, puede rastrear su progreso observando el resultado del siguiente comando:

      • kubectl describe certificate openfaas-crt -n openfaas

      El final del resultado será similar a este:

      Output

      Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal GeneratedKey 24m cert-manager Generated a new private key Normal Requested 16m cert-manager Created new CertificateRequest resource "openfaas-crt-1017759607" Normal Issued 16m cert-manager Certificate issued successfully

      Cuando en la última línea del resultado se muestre Certificate issued successfully, podrá salir pulsando CTRL + C. Reinice su dominio en su navegador para probar. En la parte izquierda de la barra de direcciones de su navegador, visualizará el candado. Este indicará que la conexión es segura.

      De esta manera, protegió su dominio de OpenFaaS usando certificados TLS gratuitos de Let´s Encrypt. Ahora usará la IU web y administrará funciones desde ella.

      Paso 3: Implementar funciones a través de la IU web

      En esta sección, explorará la IU web de OpenFaaS y luego implementará, administrará e invocará funciones desde ella.

      La IU web de OpenFaaS consta de dos partes principales: en el lado izquierdo, una columna en la que se enumerarán las funciones implementadas y el panel central, donde verá información detallada sobre una función seleccionada y podrá interactuar con ella.

      Para implementar una nueva función, haga clic en el botón Deploy New Function que está debajo del logo de OpenFaaS, en la parte superior izquierda. Verá un cuadro de diálogo en el que se le solicitará elegir una función:

      OpenFaaS: cuadro de diálogo Deploy a New Function

      En la pestaña FROM STORE, se enumeran funciones previamente creadas desde la OpenFass Function Store que puede implementar directamente. Cada función tiene una descripción breve y puede seleccionar el ícono del enlace a la derecha de una función para ver su código fuente. Para implementar una función de almacén desde esta lista, selecciónela y haga clic en el botón DEPLOY.

      También puede suministrar su propia función pasando a la pestaña CUSTOM:

      OpenFaaS: implementar una función personalizada

      Aquí, deberá especificar una imagen de Docker de su función que esté configurada específicamente para OpenFaaS y disponible en un registro de Docker (como Docker Hub). En este paso, implementará una función ya creada desde la tienda de OpenFaaS y luego, en los siguientes pasos, creará e implementará funciones personalizadas en Docker Hub.

      Aplicará la función NodeInfo, que ofrece datos sobre la máquina en la que se implementa, como los de arquitectura de CPU, número de núcleos, memoria RAM total disponible y tiempo de actividad (en segundos).

      Desde la lista de funciones de la tienda, seleccione NodeInfo y haga clic en DEPLOY. Pronto aparecerá en la lista de funciones implementadas.

      OpenFaaS: implementación de NodeInfo

      Selecciónelo. En la parte central de la pantalla, verá información básica sobre la función implementada.

      OpenFaaS: información sobre la función implementada

      El estado de la función se actualiza en tiempo real y pronto debería pasar a ser Ready. Si su valor permanece en Not Ready durante mucho tiempo, es probable que su clúster carezca de los recursos para aceptar un nuevo pod. Puede consultar Cómo redimensionar Droplets si necesita información para solucionar el inconveniente.

      Una vez que el valor sea Ready, podrá acceder a la función implementada en la URL indicada. Para probar esto, puede visitar la URL en su navegador o invocarla desde el panel Invoke function situado debajo de la información de la función.

      OpenFaaS: Invoke function implementada

      Puede seleccionar entre Text, JSON y Download para indicar el tipo de respuesta que espera. Si desea que la solicitud sea POST en vez de GET, puede suministrar datos de la solicitud en el campo Request body.

      Para invocar la función nodeinfo, haga clic en el botón INVOKE. OpenFaaS creará y ejecutará una solicitud HTTP según las opciones seleccionadas y completará los campos de respuesta con los datos recibidos.

      OpenFaaS: respuesta de la función nodeinfo

      El estado de respuesta es HTTP 200 OK, lo cual significa que la solicitud se ejecutó correctamente. El cuerpo de respuesta contiene información del sistema que recopila la función NodeInfo, lo que significa que es posible acceder a ella de forma adecuada y que funciona correctamente.

      Para eliminar una función, selecciónela de la lista y haga clic en el ícono de la papelera de la esquina superior derecha de la página. Cuando se le solicite, haga clic en OK para confirmar. El estado de la función cambiará a Not Ready (es decir, que se eliminará del clúster) y esta pronto desaparecerá también de la IU.

      En este paso, utilizó la IU web de OpenFaaS, además de implementar y administrar funciones desde ella. Ahora aprenderá a implementar y administrar funciones de OpenFaaS usando la línea de comandos.

      Paso 4: Administrar funciones usando faas-cli

      En esta sección, configurará la faas-cli para que funcione con su clúster. A continuación, implementará y gestionará sus funciones existentes a través de la línea de comandos.

      Para evitar tener que especificar su dominio de OpenFaaS cada vez que ejecute faas-cli, lo almacenará en una variable de entorno llamada OPENFAAS_URL, cuyo valor tomará y usará faas-cli automáticamente durante la ejecución.

      Abra .bash_profile en su directorio de inicio para editarlo:

      Añada la siguiente línea:

      ~/.bash_profile

      . . .
      export OPENFAAS_URL=https://openfaas.your_domain
      

      Recuerde sustituir openfaas.your_domain por su dominio, y luego guarde y cierre el archivo.

      Para evitar tener que iniciar sesión de nuevo, evalúe manualmente el archivo:

      Ahora, asegúrese de tener faas-cli instalado en su máquina local. Si aún no lo instaló, hágalo siguiendo las instrucciones descritas en los documentos oficiales.

      A continuación, configure sus credenciales de inicio de sesión ejecutando el siguiente comando:

      • cat ~/openfaas-password.txt | faas-cli login --username admin --password-stdin

      El resultado tendrá este aspecto:

      Output

      Calling the OpenFaaS server to validate the credentials... credentials saved for admin https://openfaas.your_domain

      Para implementar una función desde el almacén, ejecute el siguiente comando:

      • faas store deploy function_name

      Puede intentar implementar nodeinfo ejecutando lo siguiente:

      • faas store deploy nodeinfo

      Verá un resultado como el siguiente:

      Output

      Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/nodeinfo

      Para enumerar las funciones implementadas, ejecute faas list:

      Aparecerán sus funciones existentes:

      Output

      Function Invocations Replicas nodeinfo 0 1

      Para obtener información detallada sobre una función implementada, utilice faas describe:

      El resultado será similar a este:

      Name:                nodeinfo
      Status:              Ready
      Replicas:            1
      Available replicas:  1
      Invocations:         0
      Image:               functions/nodeinfo-http:latest
      Function process:
      URL:                 https://openfaas.your_domain/function/nodeinfo
      Async URL:           https://openfaas.your_domain/async-function/nodeinfo
      Labels:              faas_function : nodeinfo
                           uid : 514253614
      Annotations:         prometheus.io.scrape : false
      

      Puede invocar una función con faas invoque:

      Recibirá el siguiente mensaje:

      Output

      Reading from STDIN - hit (Control + D) to stop.

      A continuación, podrá proporcionar un cuerpo de solicitud. Si lo hace, el método será POST en vez de GET. Cuando termine con la entrada de datos o desee que la solicitud sea GET, presione CTRL + D. La faas-cli ejecutará la solicitud inferida y mostrará la respuesta, de igual manera que la IU web.

      Para eliminar una función, ejecute faas remove:

      Recibirá el siguiente resultado:

      Output

      Deleting: nodeinfo. Removing old function.

      Ejecute faas list de nuevo para ver que nodeinfo se eliminó:

      Output

      Function Invocations Replicas

      En este paso, implementó, enumeró, invocó y eliminó funciones de su clúster desde la línea de comandos usando faas-cli. En el siguiente paso, creará su propia función y la implementará en su clúster.

      Paso 5: Crear e implementar una nueva función

      Ahora, creará una función de ejemplo Node.JS usando faas-cli y la implementará en su clúster.

      La función resultante que creará se empaquetará como un contenedor de Docker y se publicará en Docker Hub. Para poder publicar contenedores, deberá iniciar sesión ejecutando el siguiente comando:

      Ingrese su nombre de usuario y contraseña de Docker Hub cuando se le solicite para finalizar el proceso de inicio de sesión.

      Almacene la función de ejemplo Node.JS en una carpeta llamada sample-js-function. Créela usando el siguiente comando:

      Diríjase a ella:

      Complete el directorio con la plantilla de una función de JS ejecutando el siguiente comando:

      • faas new sample-js --lang node

      El resultado tendrá el siguiente aspecto:

      Output

      2020/03/24 17:06:08 No templates found in current directory. 2020/03/24 17:06:08 Attempting to expand templates from https://github.com/openfaas/templates.git 2020/03/24 17:06:10 Fetched 19 template(s) : [csharp csharp-armhf dockerfile go go-armhf java11 java11-vert -x java8 node node-arm64 node-armhf node12 php7 python python-armhf python3 python3-armhf python3-debian ru by] from https://github.com/openfaas/templates.git Folder: sample-js created. ___ _____ ____ / _ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ / _ '_ | |_ / _` |/ _` ___ | |_| | |_) | __/ | | | _| (_| | (_| |___) | ___/| .__/ ___|_| |_|_| __,_|__,_|____/ |_| Function created in folder: sample-js Stack file written: sample-js.yml ...

      Como se muestra en el resultado, el código para la función se encuentra en la carpeta sample-js, mientras que la configuración de OpenFaaS para la función se encuentra en el archivo sample-js.yaml. En el directorio sample-js (que se parece a un proyecto normal de Node.Js) hay dos archivos: handler.js y package.json.

      handler.js contiene código de JS real que mostrará una respuesta cuando se invoque la función. El contenido del operador tiene el siguiente aspecto:

      sample-js-function/sample-js/handler.js

      "use strict"
      
      module.exports = async (context, callback) => {
          return {status: "done"}
      }
      

      Exporta una lambda function con dos parámetros, un context con datos de la solicitud y un callback que puede usar para transmitir datos de respuesta, en vez de solo devolverlo.

      Abra este archivo para editarlo:

      • nano sample-js/handler.js

      Cambie la línea resaltada como se indica:

      sample-js-function/sample-js/handler.js

      "use strict"
      
      module.exports = async (context, callback) => {
          return {status: "<h1>Hello Sammy!</h1>"}
      }
      

      Cuando termine, guarde y cierre el archivo. Cuando se invoque, esta función de OpenFaaS escribirá Hello Sammy! en la respuesta.

      A continuación, abra el archivo de configuración para su edición:

      Tendrá el siguiente aspecto:

      sample-js-function/sample-js.yml

      version: 1.0
      provider:
        name: openfaas
        gateway: https://openfaas.your_domain
      functions:
        sample-js:
          lang: node
          handler: ./sample-js
          image: sample-js:latest
      

      Para el provider, especifica openfaas y una puerta de enlace predeterminada. A continuación, define la función sample-js, especifica su lenguaje (node), su operador y nombre de imagen de Docker, que deberá modificar para incluir su nombre de usuario de la cuenta de Docker Hub, como se indica:

      sample-js-function/sample-js.yml

      version: 1.0
      provider:
        name: openfaas
        gateway: http://127.0.0.1:8080
      functions:
        sample-js:
          lang: node
          handler: ./sample-js
          image: your_docker_hub_username/sample-js:latest
      

      Guarde y cierre el archivo.

      A continuación, cree la imagen de Docker, envíela a Docker Hub e impleméntela en su clúster al mismo tiempo ejecutando el siguiente comando:

      Habrá muchos resultados (principalmente de Docker), que terminarán de forma similar a esta:

      Output

      . . . [0] < Pushing sample-js [your_docker_hub_username/sample-js:latest] done. [0] Worker done. Deploying: sample-js. Deployed. 202 Accepted. URL: https://openfaas.your_domain/function/sample-js

      Invoque su función recién implementada para asegurarse de que funcione:

      Pulse CTRL + D. Verá el siguiente resultado:

      Output

      <h1>Hello Sammy!</h1>

      Esto significa que la función se empaquetó e implementó correctamente.

      Puede eliminar la función ejecutando lo siguiente:

      Con esto. habrá creado e implementado correctamente una función de Node.JS personalizada en su instancia de OpenFaaS de su clúster.

      Conclusión

      Implementó OpenFaaS en su clúster de Kubernetes de DigitalOcean y está listo para implementar funciones previamente creadas y personalizadas, y para acceder a ellas. Ahora podrá implementar la Function como una arquitectura de servicio, que puede aumentar el uso de recursos y mejorar el rendimiento de sus aplicaciones.

      Si desea obtener más información sobre funciones de OpenFaaS avanzadas, como ajuste de escala automático para sus funciones implementadas y la supervisión del rendimiento de estas, consulte los documentos oficiales.



      Source link