OpenFaaS is serverless functions framework that runs on top of Docker and Kubernetes. In this tutorial, you'll learn how to: Deploy OpenFaaS to a Kubernetes cluster Set up the OpenFaaS CLI Create, build, and deploy serverless functions using the CLI Invoke serverless functions using the CLI Update an existing serverless function Deploy serverless functions using the web interface Monitor your serverless functions with Prometheus and Grafana Prerequisites A . If you don't have a running Kubernetes cluster, follow the instructions from the section below. Kubernetes cluster Set Up a Kubernetes Cluster with Kind A . See the page for details about creating a new account. Docker Hub Account Docker Hub . Refer the page for details about installing kubectl. kubectl Install and Set Up kubectl or higher. To check if Node.js is installed on your computer, type the following command: Node.js 10 node --version The following example output shows that Node.js is installed on your computer: v10.16.3 If Node.js is not installed or you're running an older version, you can download the installer from the page. Downloads This tutorial assumes basic familiarity with Docker and Kubernetes. Set Up a Kubernetes Cluster with Kind (Optional) With Kind, you can run a local Kubernetes cluster using Docker containers as nodes. The steps in this section are . Follow them only if you . optional don't have a running Kubernetes cluster Create a file named , and copy in the following spec: openfaas-cluster.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker # three node (two workers) cluster config 2. Use the kind create cluster command to create a Kubernetes cluster with one control plane and two worker nodes: kind create cluster --config kind-specs/kind-cluster.yaml Creating cluster ... ✓ Ensuring node image (kindest/node:v1.17.0) 🖼 ✓ Preparing nodes 📦 📦 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 ✓ Joining worker nodes 🚜 Set kubectl context to You can now use your cluster with: kubectl cluster-info --context kind-kind Thanks using kind! 😊 "kind" "kind-kind" for Deploy OpenFaaS to a Kubernetes Cluster You can install OpenFaaS using Helm, plain YAML files, or its own installer named which provides a quick and easy way to get OpenFaaS running. In this section, you'll deploy OpenFaaS with . arkade arkade Enter the following command to install : arkade curl -sLS https://dl.get-arkade.dev | sudo sh Downloading package https://github.com/alexellis/arkade/releases/download/0.1.10/arkade-darwin as /Users/andrei/Desktop/openFaaS/faas-hello-world/arkade-darwin Download complete. Running with sufficient permissions to attempt to move arkade to /usr/ /bin New version of arkade installed to /usr/ /bin Creating . _ _ __ _ _ __| | ____ _ __| | ___ / _` | local local alias 'ark' for 'arkade' '__| |/ / _` |/ _` |/ _ \ | (_| | | | < (_| | (_| | __/ \__,_|_| |_|\_\__,_|\__,_|\___| Get Kubernetes apps the easy way Version: 0.1.10 Git Commit: cf96105d37ed97ed644ab56c0660f0d8f4635996 2. Now, install with: openfaas arkade install openfaas Using kubeconfig: /Users/andrei/.kube/config Using helm3 Node architecture: Client: , 2020/03/10 16:20:40 User dir established as: /Users/andrei/.arkade/ https://get.helm.sh/helm-v3.1.1-darwin-amd64.tar.gz /Users/andrei/.arkade/bin/helm3/darwin-amd64 darwin-amd64/ /Users/andrei/.arkade/bin/helm3/README.md darwin-amd64/README.md /Users/andrei/.arkade/bin/helm3/LICENSE darwin-amd64/LICENSE /Users/andrei/.arkade/bin/helm3/helm darwin-amd64/helm 2020/03/10 16:20:43 extracted tarball into /Users/andrei/.arkade/bin/helm3: 3 files, 0 (1.633976582s) has been added to your repositories Hang tight we grab the latest from your chart repositories... ...Successfully got an update from the chart repository ...Successfully got an update from the chart repository ...Successfully got an update from the chart repository ...Successfully got an update from the chart repository Update Complete. ⎈ Happy Helming!⎈ VALUES values.yaml Command: /Users/andrei/.arkade/bin/helm3/helm [upgrade --install openfaas openfaas/openfaas --namespace openfaas --values /var/folders/nz/2gtkncgx56sgrpqvr40qhhrw0000gn/T/charts/openfaas/values.yaml -- gateway.directFunctions= -- faasnetes.imagePullPolicy=Always -- gateway.replicas=1 -- queueWorker.replicas=1 -- clusterRole= -- operator.create= -- openfaasImagePullPolicy=IfNotPresent -- basicAuthPlugin.replicas=1 -- basic_auth= -- serviceType=NodePort] Release does not exist. Installing it now. NAME: openfaas LAST DEPLOYED: Tue Mar 10 16:21:03 2020 NAMESPACE: openfaas STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: To verify that openfaas has started, run: kubectl -n openfaas get deployments -l ======================================================================= = OpenFaaS has been installed. = ======================================================================= curl -SLsf https://cli.openfaas.com | sudo sh kubectl rollout status -n openfaas deploy/gateway kubectl port-forward -n openfaas svc/gateway 8080:8080 & PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath= | base64 --decode; ) -n | faas-cli login --username admin --password-stdin faas-cli store deploy figlet faas-cli list faas-cli store list \ --platform armhf faas-cli store deploy figlet \ --platform armhf Thanks using arkade! "amd64" "x86_64" "Darwin" dirs "openfaas" while "ibm-charts" "openfaas" "stable" "bitnami" set true set set set set false set false set set set true set "openfaas" "release=openfaas, app=openfaas" # Get the faas-cli # Forward the gateway to your machine # If basic auth is enabled, you can now log into your gateway: "{.data.basic-auth-password}" echo echo $PASSWORD # For Raspberry Pi # Find out more at: # https://github.com/openfaas/faas for 3. To verify that the deployments were created, run the command. Specify the namespace and the selector using the and parameters as follows: kubectl get deployments -n -l kubectl get deployments -n openfaas -l "release=openfaas, app=openfaas" If the deployments are not yet ready, you should see something similar to the following example output: NAME READY UP-TO-DATE AVAILABLE AGE alertmanager 0/1 1 0 45s basic-auth-plugin 1/1 1 1 45s faas-idler 0/1 1 0 45s gateway 0/1 1 0 45s nats 1/1 1 1 45s prometheus 1/1 1 1 45s queue-worker 1/1 1 1 45s Once the installation is finished, the output should look like this: NAME READY UP-TO-DATE AVAILABLE AGE alertmanager 1/1 1 1 75s basic-auth-plugin 1/1 1 1 75s faas-idler 1/1 1 1 75s gateway 1/1 1 1 75s nats 1/1 1 1 75s prometheus 1/1 1 1 75s queue-worker 1/1 1 1 75s 4. Check the rollout status of the deployment: gateway kubectl rollout status -n openfaas deploy/gateway The following example output shows that the deployment has been successfully rolled out: gateway deployment successfully rolled out "gateway" 5. Use the command to forward all requests made to to the pod running the service: kubectl port-forward http://localhost:8080 gateway kubectl port-forward -n openfaas svc/gateway 8080:8080 & [1] 78674 Forwarding from 127.0.0.1:8080 -> 8080 Forwarding from [::1]:8080 -> 8080 Note that the ampersand sign ( ) runs the process in the background. You can use the jobs command to show the status of your background processes: & jobs [1] + running kubectl port-forward -n openfaas svc/gateway 8080:8080 6. Issue the following command to retrieve your password and save it into an environment variable named : PASSWORD PASSWORD=$(kubectl get secret -n openfaas basic-auth -o jsonpath= | base64 --decode; ) "{.data.basic-auth-password}" echo Set Up the OpenFaaS CLI OpenFaaS provides a command-line utility you can use to build and deploy your serverless functions. You can install it by following the steps from the page. Installation Create a Serverless Function Using the CLI Now that OpenFaaS and the command-line utility are installed, you can create and deploy serverless functions using the built-in template engine. OpenFaaS provides two types of templates: faas-cli The templates are based on the and use to communicate with your serverless function. Refer to the page for more details about how OpenFaaS Watchdog works. Classic Classic Watchdog stdio Watchdog The templates use HTTP to communicate with your serverless function. These templates are available through the GitHub repository. of-watchdog OpenFaaS Incubator In this tutorial, you'll use a . classic template Run the following command to see the templates available in the official store: faas-cli template store list NAME SOURCE DESCRIPTION csharp openfaas Classic C dockerfile openfaas Classic Dockerfile template go openfaas Classic Golang template java8 openfaas Classic Java 8 template node openfaas Classic NodeJS 8 template php7 openfaas Classic PHP 7 template python openfaas Classic Python 2.7 template python3 openfaas Classic Python 3.6 template python3-dlrs intel Deep Learning Reference Stack v0.4 ML workloads ruby openfaas Classic Ruby 2.5 template node10-express openfaas-incubator Node.js 10 powered by express template ruby-http openfaas-incubator Ruby 2.4 HTTP template python27-flask openfaas-incubator Python 2.7 Flask template python3-flask openfaas-incubator Python 3.6 Flask template python3-http openfaas-incubator Python 3.6 with Flask and HTTP node8-express openfaas-incubator Node.js 8 powered by express template golang-http openfaas-incubator Golang HTTP template golang-middleware openfaas-incubator Golang Middleware template python3-debian openfaas Python 3 Debian template powershell-template openfaas-incubator Powershell Core Ubuntu:16.04 template powershell-http-template openfaas-incubator Powershell Core HTTP Ubuntu:16.04 template rust booyaa Rust template crystal tpei Crystal template csharp-httprequest distantcam C csharp-kestrel burtonr C vertx-native pmlopes Eclipse Vert.x native image template swift affix Swift 4.2 Template lua53 affix Lua 5.3 Template vala affix Vala Template vala-http affix Non-Forking Vala Template quarkus-native pmlopes Quarkus.io native image template perl-alpine tmiklas Perl language template based on Alpine image node10-express-service openfaas-incubator Node.js 10 express.js microservice template crystal-http koffeinfrei Crystal HTTP template rust-http openfaas-incubator Rust HTTP template bash-streaming openfaas-incubator Bash Streaming template # template for # HTTP template # Kestrel HTTP template ☞ Note that you can specify an alternative store for templates. The following example command lists the templates from a repository named : andreipope faas-cli template store list -u https://raw.githubusercontent.com/andreipope/my-custom-store/master/templates.json 2. Download the official templates locally: faas-cli template pull Fetch templates from repository: https://github.com/openfaas/templates.git at master 2020/03/11 20:51:22 Attempting to expand templates from https://github.com/openfaas/templates.git 2020/03/11 20:51:25 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 ruby] from https://github.com/openfaas/templates.git ☞ By default, the above command downloads the templates from the OpenFaaS official GitHub repository. If you want to use a custom repository, then you should specify the URL of your repository. The following example command pulls the templates from a repository named : andreipope faas-cli template pull https://github.com/andreipope/my-custom-store/ 3. To create a new serverless function, run the new command specifying: faas-cli The name of your new function ( ) appfleet-hello-world The lang parameter followed by the programming language template ( ). node faas-cli new appfleet-hello-world --lang node Folder: appfleet-hello-world created. ___ _____ ____ / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | _ \| |_ / _` |/ _` \___ \ | |_| | |_) | __/ | | | _| (_| | (_| |___) | \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/ |_| Function created folder: appfleet-hello-world Stack file written: appfleet-hello-world.yml Notes: You have created a new uses Node.js 12.13.0 and the OpenFaaS Classic Watchdog. npm i --save can be used to add third-party packages like request or cheerio npm documentation: https://docs.npmjs.com/ For high-throughput services, we recommend you use the node12 template uses a different version of the OpenFaaS watchdog. '_ \ / _ \ ' in function which which At this point, your directory structure should look like the following: tree . -L 2 . ├── appfleet-hello-world │ ├── handler.js │ └── package.json ├── appfleet-hello-world.yml └── template ├── 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 └── ruby 21 directories, 3 files Things to note: The file contains the code of your serverless function. You can use the command to list the contents of this file: appfleet-hello-world/handler.js echo cat appfleet-hello-world/handler.js module.exports = async (context, callback) => { {status: } } "use strict" return "done" You can specify the dependencies required by your serverless function in the package.json file. The automatically generated file is just an empty shell: cat appfleet-hello-world/package.json { : , : , : , : , : { : }, : [], : , : } "name" "function" "version" "1.0.0" "description" "" "main" "handler.js" "scripts" "test" "echo \"Error: no test specified\" && exit 1" "keywords" "author" "" "license" "ISC" The spec of the function is stored in the file: appfleet-hello-world appfleet-hello-world.yml cat appfleet-hello-world.yml version: 1.0 provider: name: openfaas gateway: http://127.0.0.1:8080 : appfleet-hello-world: lang: node handler: ./appfleet-hello-world image: appfleet-hello-world:latest functions Build Your Serverless Function 1. Open the file in a plain-text editor, and update the field by prepending your Docker Hub user name to it. The following example prepends my username ( ) to the image field: appfleet-hello-world.yml image andrepopescu12 image: andrepopescu12/appfleet-hello-world:latest Once you've made this change, the appfleet-hello-world.yml file should look similar to the following: version: 1.0 provider: name: openfaas gateway: http://127.0.0.1:8080 : appfleet-hello-world: lang: node handler: ./appfleet-hello-world image: <YOUR-DOCKER-HUB-ACCOUNT>/appfleet-hello-world:latest functions 2. Build the function. Enter the command specifying the argument with the name of the YAML file you edited in the previous step ( ): faas-cli build -f appfleet-hello-world.yml faas-cli build -f appfleet-hello-world.yml [0] > Building appfleet-hello-world. Clearing temporary build folder: ./build/appfleet-hello-world/ Preparing: ./appfleet-hello-world/ build/appfleet-hello-world/ Building: andreipopescu12/appfleet-hello-world:latest with node template. Please .. Sending build context to Docker daemon 10.24kB Step 1/24 : FROM openfaas/classic-watchdog:0.18.1 as watchdog ---> 94b5e0bef891 Step 2/24 : FROM node:12.13.0-alpine as ship ---> 69c8cc9212ec Step 3/24 : COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog ---> Using cache ---> ebab4b723c16 Step 4/24 : RUN chmod +x /usr/bin/fwatchdog ---> Using cache ---> 7952724b5872 Step 5/24 : RUN addgroup -S app && adduser app -S -G app ---> Using cache ---> 33c7f04595d2 Step 6/24 : WORKDIR /root/ ---> Using cache ---> 77b9dee16c79 Step 7/24 : ENV NPM_CONFIG_LOGLEVEL warn ---> Using cache ---> a3d3c0bb4480 Step 8/24 : RUN mkdir -p /home/app ---> Using cache ---> 65457e03fcb1 Step 9/24 : WORKDIR /home/app ---> Using cache ---> 50ab672e5660 Step 10/24 : COPY package.json ./ ---> Using cache ---> 6143e79de873 Step 11/24 : RUN npm i --production ---> Using cache ---> a41566487c6e Step 12/24 : COPY index.js ./ ---> Using cache ---> 566633e78d2c Step 13/24 : WORKDIR /home/app/ ---> Using cache ---> 04c9de75f170 Step 14/24 : COPY /*.json ./ ---> Using cache ---> 85cf909b646a Step 15/24 : RUN npm i --production || : ---> Using cache ---> c088cbcad583 Step 16/24 : COPY --chown=app:app / . ---> Using cache ---> 192db89e5941 Step 17/24 : WORKDIR /home/app/ ---> Using cache ---> ee2b7d7e8bd4 Step 18/24 : RUN chmod +rx -R ./ && chown app:app -R /home/app && chmod 777 /tmp ---> Using cache ---> 81831389293e Step 19/24 : USER app ---> Using cache ---> ca0cade453f5 Step 20/24 : ENV cgi_headers= ---> Using cache ---> afe8d7413349 Step 21/24 : ENV fprocess= ---> Using cache ---> 5471cfe85461 Step 22/24 : EXPOSE 8080 ---> Using cache ---> caaa8ae11dc7 Step 23/24 : HEALTHCHECK --interval=3s CMD [ -e /tmp/.lock ] || 1 ---> Using cache ---> 881b4d2adb92 Step 24/24 : CMD [ ] ---> Using cache ---> 82b586f039df Successfully built 82b586f039df Successfully tagged andreipopescu12/appfleet-hello-world:latest Image: andreipopescu12/appfleet-hello-world:latest built. [0] < Building appfleet-hello-world 2.25s. [0] Worker . Total build time: 2.25s function wait function function function function "true" "node index.js" exit "fwatchdog" done in done 3. You can list your Docker images with: docker images REPOSITORY TAG IMAGE ID CREATED SIZE andreipopescu12/appfleet-hello-world latest 82b586f039df 25 minutes ago 96MB Push Your Image to Docker Hub 1. Log in to Docker Hub. Run the command with the flag followed by your Docker Hub user name. The following example command logs you in as : docker login --username andreipopescu12 docker login --username andreipopescu12 Next, you will be prompted to enter your Docker Hub password: Password: Login Succeeded 2. Use the command to push your serverless function to Docker Hub: faas-cli push faas-cli push -f appfleet-hello-world.yml The push refers to repository [docker.io/andreipopescu12/appfleet-hello-world] 073c41b18852: Pushed a5c05e98c215: Pushed f749ad113dce: Pushed e4f29400b370: Pushed b7d0eb42e645: Pushed 84fba0eb2756: Pushed cf2a3f2bc398: Pushed 942d3272b7d4: Pushed 037b653b7d4e: Pushed 966655dc62be: Pushed 08d8e0925a73: Pushed 6ce16b164ed0: Pushed d76ecd300100: Pushed 77cae8ab23bf: Pushed latest: digest: sha256:4150d4cf32e7e5ffc8fd15efeed16179bbf166536f1cc7a8c4105d01a4042928 size: 3447 [0] < Pushing appfleet-hello-world [andreipopescu12/appfleet-hello-world:latest] . [0] Worker . done done Deploy Your Function Using the CLI 1. With your serverless function pushed to Docker Hub, log in to your local instance of the OpenFaaS gateway by entering the following command: -n | faas-cli login --username admin --password-stdin echo $PASSWORD 2. Run the command to deploy your serverless function: faas-cli deploy faas-cli deploy -f appfleet-hello-world.yml Deploying: appfleet-hello-world. WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates. Handling connection 8080 Handling connection 8080 Deployed. 202 Accepted. URL: http://127.0.0.1:8080/ /appfleet-hello-world for for function ☞ OpenFaaS provides an auto-scaling mechanism based on the number of requests per second, which is read from Prometheus. For the sake of simplicity, we won't cover auto-scaling in this tutorial. To further your knowledge, you can refer the page. Auto-scaling 3. Use the command to list the functions deployed to your local OpenFaaS gateway: faas-cli list faas-cli list Function Invocations Replicas appfleet-hello-world 0 1 ☞ Note that you can also list the functions deployed to a different gateway by providing the URL of the gateway as follows: faas-cli list --gateway https://<YOUR-GATEWAT-URL>:<YOUR-GATEWAY-PORT> 4. You can use the method to retrieve more details about the function: faas-cli describe appfleet-hello-world faas-cli describe appfleet-hello-world Name: appfleet-hello-world Status: Ready Replicas: 1 Available replicas: 1 Invocations: 1 Image: andreipopescu12/appfleet-hello-world:latest Function process: node index.js URL: http://127.0.0.1:8080/ /appfleet-hello-world Async URL: http://127.0.0.1:8080/async-function/appfleet-hello-world Labels: faas_function : appfleet-hello-world Annotations: prometheus.io.scrape : function false Invoke Your Serverless Function Using the CLI 1. To see your serverless function in action, issue the command, specifying: faas-cli invoke The flag with the name of the YAML file that describes your function ( ) -f appfleet-hello-world.yml The name of your function ( ) appfleet-hello-world faas-cli invoke -f appfleet-hello-world.yml appfleet-hello-world Reading from STDIN - hit (Control + D) to stop. 2. Type . The following example output shows that your serverless function works as expected: CTRL+D appfleet Handling connection 8080 { : } for "status" "done" Update Your Function The function you created, deployed, and then invoked in the previous sections is just an empty shell. In this section, we'll update it to: Read the name of a city from stdin Fetch the weather forecast from the openweathermap.org Print to the console the weather forecast 1. Create an OpenWeatherMap account by following the instructions from the page. Sign Up ☞ Note that we are taking a reference of the OpenWeatherMap here only for reference. You can choose to call any other portal like Business Insider or a blog like Javelynn as per your requirement. 2. Log in to OpenWeatherMap and then select : API KEYS 3. From here, you can either copy the value of the default key or create a new API key, and then copy its value: 4. Now that you have an OpenWeatherMap API key, you must use to install a few dependencies. The following command moves into the directory and then installs the and request packages: npm appfleet-hello-world get-stdin appfleet-hello-world && npm i --save get-stdin request cd 5. Replace the content of the file with: handler.js const getStdin = require( ) const request = require( ); handler = (req) => { request(`http://api.openweathermap.org/data/2.5/weather?q= &?units=metric&APPID=<YOUR-OPENWEATHERMAP-APP-KEY>`, (error, response, body) { console.error( , error) console.log( , response && response.statusCode) console.log( , JSON.stringify(body)) }) }; getStdin(). (val => { handler(val); }).catch(e => { console.error(e.stack); }); module.exports = handler "use strict" 'get-stdin' 'request' let ${req} function 'error:' 'statusCode:' 'body:' then ☞ To try this function, replace with your OpenWeatherMap API KEY. <YOUR-OPENWEATHERMAP-API-KEY> 6. You can use the command to remove the function you've deployed earlier in this tutorial: faas-cli remove faas-cli remove appfleet-hello-world Deleting: appfleet-hello-world. Handling connection 8080 Removing old . for function 7. Now that the old function has been removed, you must rebuild, push, and deploy your modified function. Instead of issuing three separate commands, you can use the command as in the following example: openfaas-cli up faas-cli up -f appfleet-hello-world.yml [0] > Building appfleet-hello-world. Clearing temporary build folder: ./build/appfleet-hello-world/ Preparing: ./appfleet-hello-world/ build/appfleet-hello-world/ Building: andreipopescu12/appfleet-hello-world:latest with node template. Please .. Sending build context to Docker daemon 43.01kB Step 1/24 : FROM openfaas/classic-watchdog:0.18.1 as watchdog ---> 94b5e0bef891 Step 2/24 : FROM node:12.13.0-alpine as ship ---> 69c8cc9212ec Step 3/24 : COPY --from=watchdog /fwatchdog /usr/bin/fwatchdog ---> Using cache ---> ebab4b723c16 Step 4/24 : RUN chmod +x /usr/bin/fwatchdog ---> Using cache ---> 7952724b5872 Step 5/24 : RUN addgroup -S app && adduser app -S -G app ---> Using cache ---> 33c7f04595d2 Step 6/24 : WORKDIR /root/ ---> Using cache ---> 77b9dee16c79 Step 7/24 : ENV NPM_CONFIG_LOGLEVEL warn ---> Using cache ---> a3d3c0bb4480 Step 8/24 : RUN mkdir -p /home/app ---> Using cache ---> 65457e03fcb1 Step 9/24 : WORKDIR /home/app ---> Using cache ---> 50ab672e5660 Step 10/24 : COPY package.json ./ ---> Using cache ---> 6143e79de873 Step 11/24 : RUN npm i --production ---> Using cache ---> a41566487c6e Step 12/24 : COPY index.js ./ ---> Using cache ---> 566633e78d2c Step 13/24 : WORKDIR /home/app/ ---> Using cache ---> 04c9de75f170 Step 14/24 : COPY /*.json ./ ---> Using cache ---> f5765914bd05 Step 15/24 : RUN npm i --production || : ---> Using cache ---> a300be28c096 Step 16/24 : COPY --chown=app:app / . ---> 91cd72d8ad7a Step 17/24 : WORKDIR /home/app/ ---> Running fce50a76475a Removing intermediate container fce50a76475a ---> 0ff17b0a9faf Step 18/24 : RUN chmod +rx -R ./ && chown app:app -R /home/app && chmod 777 /tmp ---> Running 6d0c4c92fac1 Removing intermediate container 6d0c4c92fac1 ---> 1e543bfbf6b0 Step 19/24 : USER app ---> Running 6d33f5ec237d Removing intermediate container 6d33f5ec237d ---> cb7cf5dfab12 Step 20/24 : ENV cgi_headers= ---> Running 972c23374934 Removing intermediate container 972c23374934 ---> 21c6e8198b21 Step 21/24 : ENV fprocess= ---> Running 3be91f9d5228 Removing intermediate container 3be91f9d5228 ---> aafb7a756d38 Step 22/24 : EXPOSE 8080 ---> Running da3183bd88c5 Removing intermediate container da3183bd88c5 ---> 5f6fd7e66a95 Step 23/24 : HEALTHCHECK --interval=3s CMD [ -e /tmp/.lock ] || 1 ---> Running a590c91037ae Removing intermediate container a590c91037ae ---> fbe20c32941f Step 24/24 : CMD [ ] ---> Running 59cd231f0576 Removing intermediate container 59cd231f0576 ---> 88cd8ac65ade Successfully built 88cd8ac65ade Successfully tagged andreipopescu12/appfleet-hello-world:latest Image: andreipopescu12/appfleet-hello-world:latest built. [0] < Building appfleet-hello-world 13.95s. [0] Worker . Total build time: 13.95s [0] > Pushing appfleet-hello-world [andreipopescu12/appfleet-hello-world:latest]. The push refers to repository [docker.io/andreipopescu12/appfleet-hello-world] 04643e0c999f: Pushed db3ccc4403b8: Pushed 24d1d5a62262: Layer already exists adfa28db7666: Layer already exists b7d0eb42e645: Layer already exists 84fba0eb2756: Layer already exists cf2a3f2bc398: Layer already exists 942d3272b7d4: Layer already exists 037b653b7d4e: Layer already exists 966655dc62be: Layer already exists 08d8e0925a73: Layer already exists 6ce16b164ed0: Layer already exists d76ecd300100: Layer already exists 77cae8ab23bf: Layer already exists latest: digest: sha256:818d92b10d276d32bcc459e2918cb537051a14025e694eb59a9b3caa0bb4e41c size: 3456 [0] < Pushing appfleet-hello-world [andreipopescu12/appfleet-hello-world:latest] . [0] Worker . Deploying: appfleet-hello-world. WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates. Handling connection 8080 Handling connection 8080 Deployed. 202 Accepted. URL: http://127.0.0.1:8080/ /appfleet-hello-world function wait function function function in function in in "true" in "node index.js" in in exit in "fwatchdog" in done in done done done for for function ☞ Note that you can skip the push or the deploy steps: The following example command skips the push step: faas-cli up -f appfleet-hello-world.yml --skip-push The following example command skips the deploy step: faas-cli up -f appfleet-hello-world.yml --skip-deploy 8. To verify that the updated serverless function works as expected, invoke it as follows: faas-cli invoke -f appfleet-hello-world.yml appfleet-hello-world Reading from STDIN - hit (Control + D) to stop. Berlin Handling connection 8080 Hello, you are currently Berlin statusCode: 200 body: for in "{\"coord\":{\"lon\":13.41,\"lat\":52.52},\"weather\":[{\"id\":802,\"main\":\"Clouds\",\"description\":\"scattered clouds\",\"icon\":\"03d\"}],\"base\":\"stations\",\"main\":{\"temp\":282.25,\"feels_like\":270.84,\"temp_min\":280.93,\"temp_max\":283.15,\"pressure\":1008,\"humidity\":61},\"visibility\":10000,\"wind\":{\"speed\":13.9,\"deg\":260,\"gust\":19},\"clouds\":{\"all\":40},\"dt\":1584107132,\"sys\":{\"type\":1,\"id\":1275,\"country\":\"DE\",\"sunrise\":1584077086,\"sunset\":1584119213},\"timezone\":3600,\"id\":2950159,\"name\":\"Berlin\",\"cod\":200}" 9. To clean-up, run the command with the name of your serverless function ( as an argument): faas-cli remove appfleet-hello-world faas-cli remove appfleet-hello-world Deleting: appfleet-hello-world. Handling connection 8080 Removing old . for function Deploy Serverless Functions Using the Web Interface OpenFaaS provides a web-based user interface. In this section, you'll learn how you can use it to deploy a serverless function. 1. First, you must use the command to retrieve your password: echo echo $PASSWORD 49IoP28G8247MZcj6a1FWUYUx 2. Open a browser and visit . To log in, use the username and the password you retrieved in the previous step. You will be redirected to the OpenFaaS home page. Select the button: http://localhost:8080 admin DEPLOY NEW FUNCTION 3. A new window will be displayed. Select the tab, and then type: Custom in the input box docker.io/andreipopescu12/appfleet-hello-world Docker Image in the input box appfleet-hello-world Function name 4. Once you've filled in the and input boxes, select the button: Docker image Function name DEPLOY 5. Your new function will be visible in the left navigation bar. Click on it: You'll be redirected to the invoke function page: 6. In the input box, type in the name of the city you want to retrieve the weather forecast for, and then select the button: Request body INVOKE If everything works well, the weather forecast will be displayed in the field: Response Body Monitor Your Serverless Functions with Prometheus and Grafana The OpenFaaS gateway exposes the following metrics: Retrieved from https://docs.openfaas.com/architecture/metrics/ In this section, you will learn how to set up Prometheus and Grafana to track the health of your serverless functions. 1. Use the following command to list your deployments: kubectl get deployments -n openfaas -l "release=openfaas, app=openfaas" NAME READY UP-TO-DATE AVAILABLE AGE alertmanager 1/1 1 1 15m basic-auth-plugin 1/1 1 1 15m faas-idler 1/1 1 1 15m gateway 1/1 1 1 15m nats 1/1 1 1 15m prometheus 1/1 1 1 15m queue-worker 1/1 1 1 15m 2. To expose the deployment, create a service object named : prometheus prometheus-ui kubectl expose deployment prometheus -n openfaas -- =NodePort --name=prometheus-ui type service/prometheus-ui exposed ☞ The flag exposes the service on each of the node's IP addresses. Also, a service is created. You'll use this to connect to the service from outside of the cluster. --type=NodePort prometheus-ui ClusterIP prometheus-ui 3. To inspect the service, enter the following command: prometheus-ui kubectl get svc prometheus-ui -n openfaas NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE prometheus-ui NodePort 10.96.129.204 <none> 9090:31369/TCP 8m1s 4. Forward all requests made to to the pod running the service: http://localhost:9090 prometheus-ui kubectl port-forward -n openfaas svc/prometheus-ui 9090:9090 & 5. Now, you can point your browser to , and you should see a page similar to the following screenshot: http://localhost:9090 6. To deploy Grafana, you'll the image. Run the following command: stefanprodan/faas-grafana:4.6.3 kubectl run grafana -n openfaas --image=stefanprodan/faas-grafana:4.6.3 --port=3000 kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead. deployment.apps/grafana created in 7. Now, you can list your deployments with: kubectl get deployments -n openfaas NAME READY UP-TO-DATE AVAILABLE AGE alertmanager 1/1 1 1 46m basic-auth-plugin 1/1 1 1 46m faas-idler 1/1 1 1 46m gateway 1/1 1 1 46m grafana 1/1 1 1 107s nats 1/1 1 1 46m prometheus 1/1 1 1 46m queue-worker 1/1 1 1 46m 8. Use the following command to create a service object that exposes the deployment: kubectl expose deployment grafana kubectl expose deployment grafana -n openfaas -- =NodePort --name=grafana type service/grafana exposed 9. Retrieve details about your new service with: kubectl get service grafana -n openfaas NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE grafana NodePort 10.96.194.59 <none> 3000:32464/TCP 60s 10. Forward all requests made to to the pod running the service: http://localhost:3030 grafana kubectl port-forward -n openfaas svc/grafana 3000:3000 & [3] 3973 Forwarding from 127.0.0.1:3000 -> 3000 Forwarding from [::1]:3000 -> 3000 11. Now that you set up the port forwarding, you can access Grafana by pointing your browser to : http://localhost:3000 12. Log into Grafana using the username and password . The page will be displayed: admin admin Home Dashboard 13. From the left menu, select : Dashboards --> Import 14. Type in the input box. Then, select the button: https://grafana.com/grafana/dashboards/3434 Grafana.com Dashboard Load 15. In the dialog box, set the Prometheus data source to faas, and then select : Import Dashboard Import An empty dashboard will be displayed: 16. Now, you can invoke your function a couple of times using the command as follows: faas-cli invoke faas-cli invoke -f appfleet-hello-world.yml appfleet-hello-world 17. Switch back to the browser window that opened Grafana. Your dashboard should be automatically updated and look similar to the following screenshot: We hope this tutorial was useful for learning the basics of deploying serverless functions with OpenFaaS. Thanks for reading! Previously published at https://appfleet.com/