100 Days of Learning: Day 2 – Deploying my first Python based function

Photo by James Harrison on Unsplash

Here is my Log book

faas-cli warmup

For a warm up today in learning more about OpenFaaS and faasd I will first deploy the NodeInfo function using faas-cli.

To get the list of available functions from the store

$ faas-cli store list

FUNCTION                                 DESCRIPTION
NodeInfo                                 Get info about the machine that you'r...
alpine                                   An Alpine Linux shell, set the "fproc...
env                                      Print the environment variables prese...
sleep                                    Simulate a 2s duration or pass an X-S...
shasum                                   Generate a shasum for the given input
Figlet                                   Generate ASCII logos with the figlet CLI
curl                                     Use curl for network diagnostics, pas...

Learning action point: **How do I add more functions to the store? Can I host my own private functions and have the listed in the store? EDIT: There is a --url parameter and this is the way to private stores or other hosted stores.

How do I install a new FaaS?

$ faas-cli store help
...
Available Commands:
  deploy      Deploy OpenFaaS functions from a store
  describe    Show details of OpenFaaS function from a store
  list        List available OpenFaaS functions in a store
...

Lets try deploy

$ faas-cli store deploy NodeInfo

Is OpenFaaS deployed? Do you need to specify the --gateway flag?
Put "http://127.0.0.1:8080/system/functions": dial tcp 127.0.0.1:8080: connect: connection refused

Function 'nodeinfo' failed to deploy with status code: 500

Aah! I bet it is because the OPENFAAS_URL is not set since I closed yesterday’s terminal session. Guess it is time I add this environment variable to my .zshrc. In my case it is actually "~/.ajzsh/extras/zshrc.ajzsh" because I have my own zsh setup called ajzsh

Relaunch the terminal and verify

$ echo $OPENFAAS_URL
http://192.168.64.4:8080

Profit!

$ faas-cli store deploy NodeInfo
WARNING! You are not using an encrypted connection to the gateway, consider using HTTPS.

Deployed. 200 OK.
URL: http://192.168.64.4:8080/function/nodeinfo

$ echo "" | faas-cli invoke nodeinfo
Hostname: localhost

Arch: x64
CPUs: 2
Total mem: 1988MB
Platform: linux
Uptime: 16999

Learning action point: How do I setup TLS on the faasd gateway?

Helpful faas-cli commands

  • Get more information about a function from the store before installing it.
$ faas-cli store describe NAME_OF_FUNCTION -v
  • Get more information about a deployed function.
$ faas-cli describe nodeinfo
Name:                nodeinfo
Status:              Ready
Replicas:            1
Available replicas:  1
Invocations:         2
Image:
Function process:    node index.js
URL:                 http://192.168.64.4:8080/function/nodeinfo
Async URL:           http://192.168.64.4:8080/async-function/nodeinfo
Labels:Annotations:%

Note that the store name was "NodeInfo" but the function to invoke is "nodeinfo". You will get an error if you tried to invoke using the "NodeInfo" name.

Also to note the Invocations number is how many times the function has been called.

  • Delete a function
$ faas-cli remove NAME_OF_FUNCTION

Accessing the OpenFaaS gateway as a REST API

I learned about this useful cli tool name jq from Serverless for Everyone Else (the book and workshop I am following at the moment for learning about OpenFaaS etc.)

Install jq

$ brew info jq
jq: stable 1.6 (bottled), HEAD
Lightweight and flexible command-line JSON processor
https://stedolan.github.io/jq/

$ brew install jq

$ echo '{ "name" : "Andre" }' | jq
{
  "name": "Andre"
}

Get info about a deployed function as JSON response (note: jq is here just used to prettify the output)

export PASSWORD="Insert the value you got earlier for faasd admin user"
export HOST="192.168.64.4:8080"
curl -s http://admin:$PASSWORD@$HOST/system/function/nodeinfo | jq

Building my first OpenFaaS function

To get a list of templates to start from

$ faas-cli template store list
...
python3                  openfaas           Classic Python 3.6 template
python3-http             openfaas           Python 3.7 with Flask and HTTP
...
swift                    affix              Swift 4.2 Template
...

To get more information about a template

$ faas-cli template store describe python3

Name:              python3
Platform:          x86_64
Language:          Python
Source:            openfaas
Description:       Classic Python 3.6 template
Repository:        https://github.com/openfaas/templates
Official Template: true

I will be deploying my function container to Docker Hub (turns out I already had an account on there). Set the Docker Hub prefix to use.

export OPENFAAS_PREFIX=DOCKER_USER_NAME

Create the new function from the python3 template

╭ ~/Learning/faasd/helloworld                                                            [20:23:45]
╰ $ faas-cli new --lang python3 helloworld

Inside the directory where helloworld.yml lives I will try and build the docker image.

╭ ~/Learning/faasd/helloworld                                                            [20:33:56]
╰ $ faas-cli up -f helloworld.yml
...
Errors received during build:
- [helloworld] received non-zero exit code from build, error: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Error, mmkay. I do have docker installed (Docker Desktop on Mac)

Alex mentions in his book that you will need to setup docker login

$ docker login
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: [redacted]
Password:
Login Succeeded

Try again, same error. Aah ok I should maybe just actually read the error message. Turns out I forgot to start Docker.

$ faas-cli up -f helloworld.yml
...
lots of bleep bloop
...
Deployed. 200 OK.
URL: http://192.168.64.4:8080/function/helloworld.openfaas-fn

This worked indeed! I also checked Docker Hub and a new image is under my account.

Check the function is deployed and what the calling name is.

$ faas-cli list
Function                      	Invocations    	Replicas
cows                          	2              	1
helloworld                    	0              	1
nodeinfo                      	4              	1

Invoke it (note: the python3 template just echoes back what it is given as input)

$ echo "Hello World! (said the echo in the void)" | faas-cli invoke helloworld
Hello World! (said the echo in the void)

Super profit for today!