PolarSPARC |
Getting Started with Serverless using OpenFaaS (ARM Edition)
Bhaskar S | 02/22/2019 |
Overview
There has been quite a buzz around Serverless for a while now, which all started with the introduction of AWS Lambda, followed by Google Functions and Microsoft Azure Functions. So what is Serverless ???
Serverless is a software design pattern, in which, one builds and runs applications as individual and autonomous functions, without worrying about the infrastructure (hardware and software) administration and management.
In other words, application developers focus on building business applications, while the Serverless platform provider(s) focus on automatic provisioning, scaling, and managing of the backend infrastructure components (compute, database, network, storage, etc).
Serverless does not mean there is no server (compute, network, storage, software), but is fully outsourced, administered, and managed by the cloud provider, which is highly-resilient and fault-tolerant. This way the developers can focus primarily on the business applications, processes, and procedures for application upgrades.
Serverless is the combination of *BOTH* the business logic deployed as independent, autonomous functions often referred to as Function as a Service (FaaS for short) *AS WELL AS* the fully managed backend infrastructure components that is often referred to as Backend as a Service (BaaS for short).
OpenFaaS is an open-source framework for building and running Serverless functions either on-premise (using container orchestration platforms, such as, Docker Swarm, Kubernetes, etc) or in any of the cloud providers (AWS, Azure, GCE, etc), using Docker containers, without worrying about any kind of vendor lock-in.
Functions in OpenFaaS can be implemented in any of the popular languages, such as, C#, Go, Java, Node, Python, Ruby, etc.
In this article, we will demonstrate how to setup, deploy, and test OpenFaaS on-premise using Docker Swarm, running on a 5-node ARM cluster.
The following Figure-1 illustrates the high-level architectural overview of OpenFaaS running deployed on Docker Swarm cluster:
The core components of the OpenFaaS stack are as follows:
API Gateway :: is a REST based microservice running in a container (called func_gateway) that acts as the entry-point for the user-defined functions as well as the control functions deployed in OpenFaaS
Handler :: is the generic wrapper for a function defined in OpenFaaS. This is where one implements the business logic for the Serverless function
Watchdog :: is a lightweight HTTP server that forks a process to execute the Serverless function, passing in the request data via STDIN. The STDOUT from the Serverless function is returned back to the caller as the HTTP response
Prometheus :: is the monitoring agent running in a container (called func_prometheus) that collects metrics on the usage of the deployed Serverless functions in OpenFaaS
Alert Manager :: is the component running in a container (called func_alertmanager) that works in conjunction with the monitoring agent to auto-scale the number of instance(s) of the deployed Serverless functions to handle demand in OpenFaaS
Installation and Setup
The installation will be on a 5-node ODroid XU4 Cluster running Linux.
For this tutorial, let us assume the 5-nodes in the cluster to have the following host names and ip addresses:
Host name | IP Address |
---|---|
my-xu4-1 | 192.168.1.31 |
my-xu4-2 | 192.168.1.32 |
my-xu4-3 | 192.168.1.33 |
my-xu4-4 | 192.168.1.34 |
my-xu4-5 | 192.168.1.35 |
Open a Terminal window and open a tab for each of the 5 nodes my-xu4-1 thru my-xu4-5. In each of the Terminal tabs, ssh into the corresponding node.
First we need to install Docker on each of the nodes my-xu4-<N>, where <N> ranges from 1 thru 5. The current version as of this article is 18.06. Execute the following commands:
$ sudo apt-get update
$ sudo apt-get install -y docker.io
$ sudo usermod -aG docker $USER
$ sudo reboot now
Once reboot completes, open a Terminal window, open a tab for each of the 5 nodes my-xu4-1 thru my-xu4-5, and ssh into each of the nodes.
To verify Docker installation, execute the following command on the master node my-xu4-1:
$ docker info
The following would be a typical output:
Containers: 5 Running: 0 Paused: 0 Stopped: 5 Images: 19 Server Version: 18.06.1-ce Storage Driver: overlay2 Backing Filesystem: extfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog Swarm: active NodeID: knqpusrw3u3fcbi5dv8p4q4g9 Is Manager: true ClusterID: uoo4ekrlqnyx0oer97y48ohrv Managers: 1 Nodes: 5 Orchestration: Task History Retention Limit: 5 Raft: Snapshot Interval: 10000 Number of Old Snapshots to Retain: 0 Heartbeat Tick: 1 Election Tick: 10 Dispatcher: Heartbeat Period: 5 seconds CA Configuration: Expiry Duration: 3 months Force Rotate: 0 Autolock Managers: false Root Rotation In Progress: false Node Address: 192.168.1.31 Manager Addresses: 192.168.1.31:2377 Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: (expected: 468a545b9edcd5932818eb9de8e72413e616e86e) runc version: N/A (expected: 69663f0bd4b60df09991c08812a60108003fa340) init version: v0.18.0 (expected: fec3683b971d9c3ef73f284f176672c44b448662) Security Options: seccomp Profile: default Kernel Version: 4.14.94-odroidxu4 Operating System: Ubuntu 18.04.2 LTS OSType: linux Architecture: armv7l CPUs: 8 Total Memory: 1.95GiB Name: my-xu4-1 ID: ADJ5:ZABT:S7RF:UAZH:5U5R:F7F4:BE4U:TXIW:FCMZ:6TXN:ONLH:VG6L Docker Root Dir: /var/lib/docker Debug Mode (client): false Debug Mode (server): false Username: bswamina Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Live Restore Enabled: false
We will be using golang to write a simple Serverless functions using OpenFaaS. So, we need to install golang on each of the nodes my-xu4-<N>, where <N> ranges from 1 thru 5. The current version as of this article is 1.10.4. Execute the following command:
$ sudo apt install -y golang
To verify golang installation, execute the following command on the master node my-xu4-1:
$ go version
The following would be a typical output:
go version go1.10.4 linux/arm
The node my-xu4-1 will be the master node in our Docker Swarm cluster.
On the master node my-xu4-1, execute the following command:
$ docker swarm init
The following would be a typical output:
Swarm initialized: current node (abcd12345efgh67890ijklmo1) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-3l12aaabbb23bbbbbcccccc45dddd67eeeeeee89ffffffffff-0gggggg1hhhhhh2jjjjjjj3kk 192.168.1.31:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
On the master node my-xu4-1, execute the following command:
$ docker node ls
The following would be a typical output:
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION abcd12345efgh67890ijklmo1 * my-xu4-1 Ready Active Leader 18.06.1-ce
On the worker nodes my-xu4-2 thru my-xu4-5, execute the following command:
$ docker swarm join --token SWMTKN-1-3l12aaabbb23bbbbbcccccc45dddd67eeeeeee89ffffffffff-0gggggg1hhhhhh2jjjjjjj3kk 192.168.1.31:2377
The following would be a typical output:
This node joined a swarm as a worker.
On the master node my-xu4-1, execute the following command:
$ docker node ls
The following would be a typical output:
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION abcd12345efgh67890ijklmo1 * my-xu4-1 Ready Active Leader 18.06.1-ce n5rspb60lgux2g4cna2rr79gj my-xu4-2 Ready Active 18.06.1-ce a73k8zolxxij3tajv7geje1o7 my-xu4-3 Ready Active 18.06.1-ce c09m70194x72ffb2j858gshe7 my-xu4-4 Ready Active 18.06.1-ce oz1jz0prf2r0wb2j5os7xbcbx my-xu4-5 Ready Active 18.06.1-ce
On the master node my-xu4-1, execute the following command:
$ docker service ls
The following would be a typical output:
ID NAME MODE REPLICAS IMAGE PORTS
As can be inferred from Output.7 above, there are no services running yet.
Now we want to download and deploy OpenFaaS on our Docker Swarm cluster.
On the master node my-xu4-1, execute the following commands:
$ cd $HOME/Downloads
$ git clone https://github.com/alexellis/faas/
The following would be a typical output:
Cloning into 'faas'... remote: Enumerating objects: 11, done. remote: Counting objects: 100% (11/11), done. remote: Compressing objects: 100% (10/10), done. remote: Total 18141 (delta 1), reused 3 (delta 1), pack-reused 18130 Receiving objects: 100% (18141/18141), 22.47 MiB | 11.13 MiB/s, done. Resolving deltas: 100% (7590/7590), done.
To deploy the OpenFaaS stack in our Docker Swarm cluster, execute the following commands on the master node my-xu4-1:
$ cd $HOME/Downloads/faas
$ ./deploy_stack.sh
The following would be a typical output:
Attempting to create credentials for gateway.. rf8sjlfez8r4erqf7op378e71 4x09nxubnam53ukxshzzkdna0 [Credentials] username: admin password: 111111aaaaaa222222bbbbbb333333cccccc444444dddddd555555eeeeee6f7g echo -n 111111aaaaaa222222bbbbbb333333cccccc444444dddddd555555eeeeee6f7g | faas-cli login --username=admin --password-stdin Enabling basic authentication for gateway.. Deploying OpenFaaS core services for ARM Creating network func_functions Creating config func_alertmanager_config Creating config func_prometheus_config Creating config func_prometheus_rules Creating service func_faas-swarm Creating service func_nats Creating service func_queue-worker Creating service func_prometheus Creating service func_alertmanager Creating service func_gateway
OpenFaaS expects basic-auth credentials in all communications with it.
From the Output.9 above, we see the default user is admin and the password 111111aaaaaa222222bbbbbb333333cccccc444444dddddd555555eeeeee6f7g.
On the master node my-xu4-1, execute the following command:
$ docker service ls
The following would be a typical output:
ID NAME MODE REPLICAS IMAGE PORTS 1fi7v6wqu251 func_alertmanager replicated 1/1 functions/alertmanager:0.15.0-armhf bn718v0e17j6 func_faas-swarm replicated 1/1 openfaas/faas-swarm:0.6.1-armhf ta5l78be3sd7 func_gateway replicated 1/1 openfaas/gateway:0.11.0-armhf *:8080->8080/tcp s0rzg4g9frs3 func_nats replicated 1/1 nats-streaming:0.11.2 u3924uaou0dx func_prometheus replicated 1/1 functions/prometheus:2.7.0-armhf *:9090->9090/tcp wud849pyaqym func_queue-worker replicated 1/1 openfaas/queue-worker:0.6.0-armhf
As is evident from the Output.10 above, we have successfully deployed the components of OpenFaaS stack in our Docker Swarm cluster.
One important point to note from the Output.10 above - we have an API gateway running at the endpoint http://192.168.1.31:8080.
Open a browser and enter the API gateway URL running at http://192.168.1.31:8080.
The following Figure-2 illustrates the view of the API gateway in the browser:
In order to manage the lifecycle (create, build, deploy, delete) of Serverless functions in OpenFaaS, we need to install a CLI utility called faas-cli. To do that, execute the following command on the master node my-xu4-1:
$ curl -sSL cli.openfaas.com | sudo sh
The following would be a typical output:
armv7l Downloading package https://github.com/openfaas/faas-cli/releases/download/0.8.3/faas-cli-armhf as /tmp/faas-cli-armhf Download complete. Running as root - Attempting to move faas-cli to /usr/local/bin New version of faas-cli installed to /usr/local/bin Creating alias 'faas' for 'faas-cli'. ___ _____ ____ / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \ | |_| | |_) | __/ | | | _| (_| | (_| |___) | \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/ |_| CLI: commit: a141dedf94ffeed84412365fd591bdc8999c5a1b version: 0.8.3
To verify if the CLI utility faas-cli has been installed properly, execute the following command on the master node my-xu4-1:
$ faas-cli
The following would be a typical output:
___ _____ ____ / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \ | |_| | |_) | __/ | | | _| (_| | (_| |___) | \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/ |_| Manage your OpenFaaS functions from the command line Usage: faas-cli [flags] faas-cli [command] Available Commands: build Builds OpenFaaS function containers cloud OpenFaaS Cloud commands deploy Deploy OpenFaaS functions describe Describe an OpenFaaS function generate Generate Kubernetes CRD YAML file help Help about any command invoke Invoke an OpenFaaS function list List OpenFaaS functions login Log in to OpenFaaS gateway logout Log out from OpenFaaS gateway new Create a new template in the current folder with the name given as name push Push OpenFaaS functions to remote registry (Docker Hub) remove Remove deployed OpenFaaS functions secret OpenFaaS secret commands store OpenFaaS store commands template OpenFaaS template store and pull commands up Builds, pushes and deploys OpenFaaS function containers version Display the clients version information Flags: --filter string Wildcard to match with function names in YAML file -h, --help help for faas-cli --regex string Regex to match with function names in YAML file -f, --yaml string Path to YAML file describing function(s) Use "faas-cli [command] --help" for more information about a command.
Thats it !!! This completes the installation and setup process.
Hands-on with OpenFaaS
We want to quickly demonstrate a Serverless function using golang running on OpenFaaS.
First we need to setup a structure for our golang project. To do that, execute the following commands on my-xu4-1:
$ mkdir -p $HOME/Projects/go
$ export GOPATH=$HOME/Projects/go
$ cd $GOPATH
$ mkdir -p src/functions
$ cd src/functions
To create a new Serverless function, with the API gateway running at http://192.168.1.31:8080, execute the following commands on the master node my-xu4-1:
$ mkdir goecho
$ cd goecho
$ faas-cli new --lang go-armhf goecho --gateway http://192.168.1.31:8080
The following would be a typical output:
2019/02/18 15:15:48 No templates found in current directory. 2019/02/18 15:15:48 Attempting to expand templates from https://github.com/openfaas/templates.git 2019/02/18 15:15:48 Fetched 15 template(s) : [csharp csharp-armhf dockerfile go go-armhf java8 node node-arm64 node-armhf php7 python python-armhf python3 python3-armhf ruby] from https://github.com/openfaas/templates.git Folder: goecho created. ___ _____ ____ / _ \ _ __ ___ _ __ | ___|_ _ __ _/ ___| | | | | '_ \ / _ \ '_ \| |_ / _` |/ _` \___ \ | |_| | |_) | __/ | | | _| (_| | (_| |___) | \___/| .__/ \___|_| |_|_| \__,_|\__,_|____/ |_| Function created in folder: goecho Stack file written: goecho.yml
Ensure the value for the option --lang is *go-armhf*. Else later will encounter the following error:
standard_init_linux.go:190: exec user process caused "exec format error"
On the master node my-xu4-1, execute the following command:
$ ls -l
The following would be a typical output:
total 12 drwx------ 2 xu4 xu4 4096 Feb 18 13:54 goecho -rw------- 1 xu4 xu4 137 Feb 18 13:54 goecho.yml drwxrwxr-x 17 xu4 xu4 4096 Feb 18 13:54 template
The OpenFaaS function creation process creates a sub-directory by the name goecho which will contain the function wrapper file called handler.go as shown below:
It is the above function wrapper that gets executed when the Serverless function is invoked.
Since we will be running the OpenFaaS build process to package our simple Serverless function as a Docker image locally on the master node my-xu4-1, we need to push the Docker image to either a private Docker registry or the public Docker hub. This way the Docker image will be accessible to the other nodes in the Docker Swarm cluster.
For this exercise, will be pushing the Docker image to my registered public Docker hub repository. Ensure you have registered and created your own repository at Docker Hub site.
In order to push the Docker image to a registered public Docker hub repository, modify the line image: in the file goecho.yml to point to your repository in the format: user-id/image-name:latest (bswamina/goecho:latest for my case), as shown below:
To build the newly created Serverless function, execute the following command on the master node my-xu4-1:
$ faas-cli build -f goecho.yml
The following would be a typical output:
[0] > Building goecho. Clearing temporary build folder: ./build/goecho/ Preparing ./goecho/ ./build/goecho/function Building: bswamina/goecho:latest with go-armhf template. Please wait.. Sending build context to Docker daemon 6.656kB Step 1/18 : FROM golang:1.10.4-alpine3.8 as builder 1.10.4-alpine3.8: Pulling from library/golang 905674ea9d94: Already exists d91fe322e169: Already exists 539e55f19a97: Pull complete 709c5449f2ce: Pull complete bc40f6a203c9: Pull complete b311e7c16063: Pull complete Digest: sha256:55ff778715a4f37ef0f2f7568752c696906f55602be0e052cbe147becb65dca3 Status: Downloaded newer image for golang:1.10.4-alpine3.8 ---> e9cd6992c34f Step 2/18 : RUN apk --no-cache add curl && echo "Pulling watchdog binary from Github." && curl -sSL https://github.com/openfaas/faas/releases/download/0.9.14/fwatchdog-armhf > /usr/bin/fwatchdog && chmod +x /usr/bin/fwatchdog && apk del curl --no-cache ---> Running in 5a94c235b4b2 fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/armhf/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/armhf/APKINDEX.tar.gz (1/4) Installing nghttp2-libs (1.32.0-r0) (2/4) Installing libssh2 (1.8.0-r3) (3/4) Installing libcurl (7.61.1-r1) (4/4) Installing curl (7.61.1-r1) Executing busybox-1.28.4-r1.trigger OK: 5 MiB in 18 packages Pulling watchdog binary from Github. fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/armhf/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/armhf/APKINDEX.tar.gz (1/4) Purging curl (7.61.1-r1) (2/4) Purging libcurl (7.61.1-r1) (3/4) Purging nghttp2-libs (1.32.0-r0) (4/4) Purging libssh2 (1.8.0-r3) Executing busybox-1.28.4-r1.trigger OK: 4 MiB in 14 packages Removing intermediate container 5a94c235b4b2 ---> a5f3507a4acc Step 3/18 : WORKDIR /go/src/handler ---> Running in 7a824ec36182 Removing intermediate container 7a824ec36182 ---> 174da2669536 Step 4/18 : COPY . . ---> fcf1c1e290c1 Step 5/18 : RUN test -z "$(gofmt -l $(find . -type f -name '*.go' -not -path "./vendor/*" -not -path "./function/vendor/*"))" || { echo "Run \"gofmt -s -w\" on your Golang code"; exit 1; } ---> Running in e8181f03983d Removing intermediate container e8181f03983d ---> 1018979bc626 Step 6/18 : RUN CGO_ENABLED=0 GOOS=linux go build --ldflags "-s -w" -a -installsuffix cgo -o handler . && go test ./... -cover ---> Running in 7f71e2530cb5 ? handler [no test files] ? handler/function [no test files] Removing intermediate container 7f71e2530cb5 ---> 1eb4a39a95de Step 7/18 : FROM alpine:3.8 3.8: Pulling from library/alpine 5b678b67777f: Pull complete d9f0b2b885d9: Pull complete Digest: sha256:dad671370a148e9d9573e3e10a9f8cc26ce937bea78f3da80b570c2442364406 Status: Downloaded newer image for alpine:3.8 ---> d2696274f894 Step 8/18 : RUN apk --no-cache add ca-certificates ---> Running in e0b8d5e08e28 fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/armhf/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/armhf/APKINDEX.tar.gz (1/1) Installing ca-certificates (20171114-r3) Executing busybox-1.28.4-r2.trigger Executing ca-certificates-20171114-r3.trigger OK: 4 MiB in 14 packages Removing intermediate container e0b8d5e08e28 ---> e74f07dd1e11 Step 9/18 : RUN addgroup -S app && adduser -S -g app app ---> Running in d2339abaa87f Removing intermediate container d2339abaa87f ---> 51abcebb1738 Step 10/18 : RUN mkdir -p /home/app ---> Running in f235f97e381e Removing intermediate container f235f97e381e ---> 4623d0af0926 Step 11/18 : RUN chown app /home/app ---> Running in f8adab6db4c2 Removing intermediate container f8adab6db4c2 ---> 24c51ba52440 Step 12/18 : WORKDIR /home/app ---> Running in 586d354913de Removing intermediate container 586d354913de ---> 59b1ced9399f Step 13/18 : COPY --from=builder /go/src/handler/handler . ---> 45e369824609 Step 14/18 : COPY --from=builder /usr/bin/fwatchdog . ---> 4688e2f1e6f4 Step 15/18 : USER app ---> Running in 8471863762a4 Removing intermediate container 8471863762a4 ---> 577e2ea75659 Step 16/18 : ENV fprocess="./handler" ---> Running in e249eb4c0d06 Removing intermediate container e249eb4c0d06 ---> 6654ca56a089 Step 17/18 : EXPOSE 8080 ---> Running in 25e522029405 Removing intermediate container 25e522029405 ---> 2bccc4e3964f Step 18/18 : CMD ["./fwatchdog"] ---> Running in 1dbba351c064 Removing intermediate container 1dbba351c064 ---> 864958423067 Successfully built 864958423067 Successfully tagged bswamina/goecho:latest Image: bswamina/goecho:latest built. [0] < Building goecho done. [0] worker done.
To push the locally build Docker image to the registered public Docker hub repository, execute the following command on the master node my-xu4-1:
$ faas-cli push -f goecho.yml
The following would be a typical output:
The push refers to repository [docker.io/bswamina/goecho] b044b70d3985: Preparing f9f02de17ab9: Preparing 1795e4fc8c3d: Preparing 0b82126cfc0d: Preparing 153b2ef38418: Preparing 169699648f59: Waiting 4d6f2b7ff2f4: Waiting e093aa48fce2: Waiting denied: requested access to the resource is denied 2019/02/18 14:14:14 ERROR - Could not execute command: [docker push bswamina/goecho:latest]
OOPS !!! What happened here ???
In order to push a Docker image to the registered public Docker hub repository, we need to first login with our registered credentials.
To login to our registered public Docker hub repository, execute the following command on the master node my-xu4-1:
$ docker login
We will be prompted for our user-id and password. Once we enter those, the following would be a typical output:
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: bswamina Password: WARNING! Your password will be stored unencrypted in /home/xu4/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded
Now, retry to push the just built Docker image by executing the following command on the master node my-xu4-1:
$ faas-cli push -f goecho.yml
The following would be a typical output:
[0] > Pushing goecho [bswamina/goecho:latest]. The push refers to repository [docker.io/bswamina/goecho] d376bd085999: Pushed 15e64d94e801: Pushed dea44b3f24ed: Pushed 93012c148c7b: Pushed a58ab9e53859: Pushed 4d6f2b7ff2f4: Mounted from library/alpine e093aa48fce2: Mounted from library/alpine latest: digest: sha256:af0afb00ba26881c665ca0160d79f846f66d0a7ca4c2f1e11a1facbed913b3f6 size: 1781 [0] < Pushing goecho [bswamina/goecho:latest] done. [0] worker done.
BINGO !!! success this time.
Now comes the interesting part. To deploy our Serverless function packaged in a Docker image called bswamina/goecho:latest (with the API gateway running at http://192.168.1.31:8080), execute the following command on the master node my-xu4-1:
$ faas-cli deploy -f goecho.yml --gateway http://192.168.1.31:8080
The following would be a typical output:
Deploying: goecho. unauthorized access, run "faas-cli login" to setup authentication for this server
WHAT ???
Remember OpenFaaS uses basic-auth protection. Hence, we first need to authenticate with the API gateway http://192.168.1.31:8080 using the basic-auth credentials.
To authenticate with the API gateway at http://192.168.1.31:8080, execute the following command on the master node my-xu4-1:
$ echo -n 111111aaaaaa222222bbbbbb333333cccccc444444dddddd555555eeeeee6f7g | faas-cli login --username=admin --password-stdin --gateway http://192.168.1.31:8080
The following would be a typical output:
Calling the OpenFaaS server to validate the credentials... WARNING! Communication is not secure, please consider using HTTPS. Letsencrypt.org offers free SSL/TLS certificates. credentials saved for admin http://192.168.1.31:8080
Now, we will re-try the command to deploy our Serverless function by executing the following command on the master node my-xu4-1:
$ faas-cli deploy -f goecho.yml --gateway http://192.168.1.31:8080
The following would be a typical output:
Deploying: goecho. Deployed. 202 Accepted. URL: http://192.168.1.31:8080/function/goecho
To verify deployment of our Serverless function, execute the following command on the master node my-xu4-1:
$ docker service ls
The following would be a typical output:
ID NAME MODE REPLICAS IMAGE PORTS 1fi7v6wqu251 func_alertmanager replicated 1/1 functions/alertmanager:0.15.0-armhf bn718v0e17j6 func_faas-swarm replicated 1/1 openfaas/faas-swarm:0.6.1-armhf ta5l78be3sd7 func_gateway replicated 1/1 openfaas/gateway:0.11.0-armhf *:8080->8080/tcp s0rzg4g9frs3 func_nats replicated 1/1 nats-streaming:0.11.2 u3924uaou0dx func_prometheus replicated 1/1 functions/prometheus:2.7.0-armhf *:9090->9090/tcp wud849pyaqym func_queue-worker replicated 1/1 openfaas/queue-worker:0.6.0-armhf 1nkewwozf2g0 goecho replicated 1/1 bswamina/goecho:latest
BINGO !!! As is evident from the Output.22 above, we see that we have successfully deployed our first Serverless function to our Docker Swarm cluster.
Now comes the *FUN* part. To test our deployed Serverless function called goecho (with the API gateway running at http://192.168.1.31:8080), execute the following command on the master node my-xu4-1:
$ echo "Howdy" | faas-cli invoke goecho --gateway http://192.168.1.31:8080
The following would be a typical output:
Hello, Go. You said: Howdy
YIPEE !!! As is evident from the Output.23 above, we have a successful response from our first Serverless function.
One can also invoke the deployed Serverless function via a web-browser through the API gateway URL located at http://192.168.1.31:8080.
The following Figure-3 illustrates the view of the Serverless function invocation via the API gateway in the browser:
To delete our deployed Serverless function called goecho (with the API gateway running at http://192.168.1.31:8080), execute the following command on the master node my-xu4-1:
$ faas-cli remove goecho --gateway http://192.168.1.31:8080
The following would be a typical output:
Deleting: goecho. Removing old function.
With this, we conclude the basic exercises we performed on our Docker Swarm cluster running OpenFaaS.
References