惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园 - 司徒正美
Security Archives - TechRepublic
Security Archives - TechRepublic
P
Palo Alto Networks Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cyberwarzone
Cyberwarzone
小众软件
小众软件
T
Threatpost
Latest news
Latest news
J
Java Code Geeks
博客园 - Franky
博客园 - 三生石上(FineUI控件)
Project Zero
Project Zero
P
Privacy & Cybersecurity Law Blog
T
Tenable Blog
L
Lohrmann on Cybersecurity
大猫的无限游戏
大猫的无限游戏
WordPress大学
WordPress大学
Apple Machine Learning Research
Apple Machine Learning Research
Scott Helme
Scott Helme
Simon Willison's Weblog
Simon Willison's Weblog
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
人人都是产品经理
人人都是产品经理
S
Schneier on Security
T
The Blog of Author Tim Ferriss
V
V2EX
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
罗磊的独立博客
IT之家
IT之家
雷峰网
雷峰网
H
Help Net Security
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tor Project blog
C
Cybersecurity and Infrastructure Security Agency CISA
I
InfoQ
GbyAI
GbyAI
博客园 - 叶小钗
PCI Perspectives
PCI Perspectives
The GitHub Blog
The GitHub Blog
Martin Fowler
Martin Fowler
H
Heimdal Security Blog
Spread Privacy
Spread Privacy
博客园_首页
A
About on SuperTechFans
T
Tailwind CSS Blog
The Register - Security
The Register - Security

Martin Heinz's Blog

A Guide to Python's Weak References Using weakref Module Recent Docker BuildKit Features You're Missing Out On Modern Git Commands and Features You Should Be Using Everything You Can Do with Python's textwrap Module Monitoring Indoor Air Quality with Prometheus, Grafana and a CO2 Sensor Everything You Can Do with Python's bisect Module You Don't Need a Dedicated Cache Service - PostgreSQL as a Cache A Collection of Docker Images To Solve All Your Debugging Needs Weird Python "Features" That Might Catch You By Surprise Lessons Learned From Writing 100 Articles Debugging Crashes and Deadlocks in Python using PyStack Goodbye etcd, Hello PostgreSQL: Running Kubernetes with an SQL Database Remote Interactive Debugging of Python Applications Running in Kubernetes The Right Way to Run Shell Commands From Python Real Multithreading is Coming to Python - Learn How You Can Use It Now Python's Missing Batteries: Essential Libraries You're Missing Out On Kubernetes-Native Synthetic Monitoring with Kuberhealthy Make Your CLI Demos a Breeze with Zero Stress and Zero Mistakes Reduce - The Power of a Single Python Function Why I Will Never Use Alpine Linux Ever Again Cgroups - Deep Dive into Resource Management in Kubernetes Dictionary Dispatch Pattern in Python Boost Your Python Application Performance using Continuous Profiling Lazy Evaluation Using Recursive Python Generators Python Magic Methods You Haven't Heard About Getting Started with Mastodon API in Python Backup-and-Restore of Containers with Kubernetes Checkpointing API Getting Started with Google APIs in Python Python CLI Tricks That Don't Require Any Code Whatsoever All The Ways To Introspect Python Objects at Runtime What is Python's "self" Argument, Anyway? Python List Comprehensions Are More Powerful Than You Might Think You Should Be Using Python's Walrus Operator - Here's Why Recipes and Tricks for Effective Structural Pattern Matching in Python It's Time to Say Goodbye to These Obsolete Python Libraries Advanced Features of Kubernetes' Horizontal Pod Autoscaler Data and System Visualization Tools That Will Boost Your Productivity Stop Messing with Kubernetes Finalizers Automate All the Boring Kubernetes Operations with Python End-to-End Monitoring with Grafana Cloud with Minimal Effort Bitly | bit.ly/3JLmSgA Bitly | bit.ly/3uETfbi Bitly | bit.ly/3MI4Iz0 Bitly | bit.ly/3M30D82 Bitly | bit.ly/3oMJ6qR Bitly | bit.ly/3IRD7IK Bitly | bit.ly/3A3B69t Bitly | bit.ly/31lKCYA Bitly | bit.ly/30uviIM Bitly | bit.ly/3E1X2mw Bitly | bit.ly/3Dv7JxP Bitly | bit.ly/3GG1BEz Bitly | bit.ly/3lLavs4 Bitly | bit.ly/39TqP3m Bitly | bit.ly/3A5Mpx8 Bitly | bit.ly/3kGwPl4 Bitly | bit.ly/3iHtulU Bitly | bit.ly/3xGjtKS Bitly | bit.ly/3h8DZg0 Bitly | bit.ly/2RQn1dG Bitly | bit.ly/3p2B5wW The Easiest Way to Debug Kubernetes Workloads Bitly | bit.ly/2PHVudx Cloud Native CI/CD with Tekton - Building Custom Tasks Bitly | bit.ly/3dg3QR9 Bitly | bit.ly/3qHtSkZ Deep Dive into Docker Internals - Union Filesystem Bitly | bit.ly/3qlRAUN Bitly | bit.ly/3pCUJ26 Bitly | bit.ly/3ifZxYr Bitly | bit.ly/34ZhIMt Bitly | bit.ly/3qSO7h0 Bitly | bit.ly/3muGLOk Bitly | bit.ly/35xN79v Bitly | bit.ly/3mLGshK Bitly | bit.ly/2IvkGQl Bitly | bit.ly/2Sk1KFK Bitly | bit.ly/3iCNIL6 Bitly | bit.ly/3beQPpy Saving Your Linux Machine from Certain Death New Features in Python 3.9 You Should Know About Deploy Any Python Project to Kubernetes Analyzing Docker Image Security Recursive SQL Queries with PostgreSQL Automating Every Aspect of Your Python Project Tour of Python Itertools Implementing 2D Physics in Javascript Ultimate Setup for Your Next Python Project Making Python Programs Blazingly Fast Security and Cryptography Mistakes You Are Probably Doing All The Time Going Serverless with OpenFaaS and Golang - Building Optimized Templates Setting Up Swagger Docs for Golang API Building RESTful APIs in Golang Pytest Features, That You Need in Your (Testing) Life Setting up GitHub Package Registry with Docker and Golang Ultimate Setup for Your Next Golang Project Python Tips and Trick, You Haven't Already Seen, Part 2. Tricks for Postgres and Docker that will make your life easier Getting The Most Out of Reading Books - Reading The "Professional Way" Python Tips and Trick, You Haven't Already Seen
Going Serverless with OpenFaaS and Golang - The Ultimate Setup and Workflow
Martin · 2019-11-16 · via Martin Heinz's Blog

Serverless applications have been cool and hype for a while now and some interesting and useful platforms/tools/frameworks are emerging now. One of them is OpenFaaS which is open source Function as a Service tool for developing cloud-native serverless applications.

In this blog post, I want to show you how to setup (IMHO) the ideal project and workflow for developing OpenFaaS functions, as well as creating your first function using Golang.

Note: Full source code for this post can be found here: https://github.com/MartinHeinz/openfaas-functions

header

Why OpenFaaS

You might be asking, why - out of all the frameworks like AWS Lambda, Google Cloud Run, OpenWhisk etc. - would I choose OpenFaaS? Well, there are quite few reasons for me:

  • No Vendor-Lock - One big reason for me to choose OpenFaaS over other alternatives, is the fact, that I'm not gonna get vendor locked. Why does it matter so much, though? It matters, because at some point, you might decide, that you want to move to other platform or even completely move away from serverless, which you can't really do with tools like AWS Lambda that forces you to use AWS.
  • Cloud Native - Next advantage is that it runs in cloud environments like Kubernetes, OpenShift or k3s (used in this tutorial). I consider this an advantage because spinning up small Kubernetes cluster is pretty cheap, fast and simple nowadays and deploying OpenFaaS in it is simple too, as you will see below.
  • Any Language - OpenFaaS is able to use any runtime, thanks to the fact that all the functions run in Docker containers. You can even build your own templates from which you build your functions.
  • Performance - Another nice thing about OpenFaaS, is its performance, more specifically - zero-scale or in other words - ability to scale pods to zero when idle, and HTTP-based (beta) templates with lower latency, caching and persistent connections (you will see that in next blog post).

Setting Up

To start building some cool functions, we first need to install few tools. Here's list of them with instructions:

  • k3s - To run the functions we need a cloud environment and considering that we will be using local machine, we should probably choose the most lightweight option possible, here I will use Ranchers k3s (alternatively you could also use KinD): To install use following commands:
    
        curl -SLsf https://get.k3sup.dev/ | sudo sh
        
  • OpenFaaS - As mentioned previously, OpenFaaS is a Cloud Native platform, so we need to put it into our Cloud environment (k3s):
    
        k3sup app install openfaas
        
  • faas-cli - To be able to interact with the deployed OpenFaaS we also need its CLI:
    
       curl -sL https://cli.openfaas.com | sudo sh
       faas-cli --version
        
  • Taskfile - Lastly, our setup uses Taskfile - replacement for Make - to automate common tasks. To install it, you need to run:
    
        cd ~
        curl -sL https://taskfile.dev/install.sh | sh
        task --version
        

First Function

Now that we have all our tools ready, let's build our first OpenFaaS function. Before we actually do any coding, we need to pull templates on top of which we will build the functions:


~ $ faas-cli template pull  # Pull from default store
~ $ faas-cli template store list  # Check what we have available
NAME                     SOURCE             DESCRIPTION
...
go                       openfaas           Classic Golang template
...

Above, we can see the one template we are interested in - the go template. Let's create function from it:


~ $ faas-cli new --lang go first-func --prefix=martinheinz
...
Function created in folder: first-func
Stack file written: first-func.yml
...

From the output, we can see which files were created - handler.go and first-func.yml. First of them contains function responsible for handling incoming requests, other one is YAML stack file, that describes the function - it contains information like image name, path to handler, language etc. There are also more values that can be specified, those you can find here. You probably noticed that we also specified prefix flag - we need that, to be able to push image of our built function to remote repository, which is in this case Docker Hub and the prefix is Docker Hub username. OpenFaaS will then use this image from remote registry, when we deploy the function.

I will leave fiddling with code and implementing cool features to you and I will just build, push and deploy the Hello World function as is:


faas-cli build -f first-func.yml
faas-cli push -f first-func.yml
faas-cli deploy -f first-func.yml

And just like that, we have our function running in OpenFaaS on k3s. We can view it both in UI and commandline. For UI view, you can navigate to OPENFAAS_URL (which should be http://127.0.0.1:31112) and for shell you can run following commands to display and invoke the function:


~ $ echo "Martin" | faas-cli invoke first-func
Hello, Go. You said: Martin

I think, this was quite simple and we can build upon this. In the next blog post, we will explore how to make use of newer (beta) of-watchdog templates as well as how to build our own template store including our optimized templates using Go modules. You can have a sneak peak in my template repository here.

Unit Tests

It might seem like we're done here, but there's one thing we are missing - Unit Test(s).

To write our unit test we simply create handler_test.go file alongside handler.go and put this test in there:


package function

import (
	"testing"
)

func TestHandleReturnsCorrectResponse(t *testing.T) {
	expected := "Hello, Go. You said: First Test!"
	response := Handle([]byte("First Test!"))

	if response != expected {
		t.Fatalf("Expected: %v, Got: %v", expected, response)
	}
}

You might have actually noticed, that the go test command was ran during Docker build, so all we need to run tests is build the function like before:


faas-cli build -f first-func.yml
...
RUN CGO_ENABLED=${CGO_ENABLED} GOOS=linux \
    go build --ldflags "-s -w" -a -installsuffix cgo -o handler . && \
    go test $(go list ./... | grep -v /vendor/) -cover
 ---> Running in fc879c8559f8
?   	handler	[no test files]
ok  	handler/function	0.002s	coverage: 100.0% of statements
...

You might think that it is redundant to test little pieces of code like these kinds of serverless functions, but you should not neglect testing just because the code is simple or short, everything should be tested if possible.

Made simple with Taskfile

In the beginning of the post, I asked you to install Taskfile, but we haven't actually used it yet, so let's change that and make the workflow simpler and create, build, deploy or debug the function with Taskfile targets that I already created for you:

First step - create the function with specified name, using some template:


    task create TPL=go FUNC=first-func
    

in the background this task downloads templates for you, creates the function and then adds the files to git staging area.

Next, let's build it:


  task build FUNC=first-func
    

Nothing fancy, it just builds the function, but you can also go ahead and build, push and deploy the function in one command:


  task run FUNC=first-func
    

Now, to check if everything works as expected, let's check logs:


  task logs FUNC=first-func
    

This will give description of kubernetes deployment object as well as function logs that should look like this:


2019/11/12 19:33:47 Version: 0.18.1	SHA: b46be5a4d9d9d55da9c4b1e50d86346e0afccf2d
2019/11/12 19:33:47 Timeouts: read: 5s, write: 5s hard: 0s.
2019/11/12 19:33:47 Listening on port: 8080
2019/11/12 19:33:47 Writing lock-file to: /tmp/.lock
2019/11/12 19:33:47 Metrics listening on port: 8081

And if logs aren't enough, you can debug the function with:


  task debug FUNC=first-func
    

This will run the function locally in Docker and attach terminal to the to watchdog process logs. Now, that the function is running on your machine, you can use cURL to invoke it:


  curl -vvv --header "Content-Type: application/json" \
            --request POST \
            --data '{"key":"value"}' \
            127.0.0.1:8081
    

To see what's happening inside the Taskfile.yml or to check out little more detailed documentation, please check out Taskfile.yml in my repository here and README.md here.

The Simplest CI/CD

The final thing we need to setup is CI/CD pipeline and we can do that with one last Taskfile target that I omitted in previous section - task verify - this command downloads faas-cli, if not present on the machine and builds each function in the repository using YAMLs stored in functions directory:


...
install:
  - curl -sL https://taskfile.dev/install.sh | sh

before_install:

script:
  - ./bin/task verify
...

For a full code listing, please see files in repository, specifically .travis.yml here and verify.sh here.

Conclusion

As you can see from this article, it can be really easy to start developing serverless applications and I hope you will give it a shot, considering that serverless is not just hype anymore and these technologies are quite mature. If you want to see more details and complete source code from this post please see my repository here and in case you have some suggestions/improvements/issues feel free to submit issue or just star it. 🙂 As mentioned earlier - in the next blog post, we will look at how to set up own template store, create custom templates and use it to create better functions.