serverless 大环境下出现了 faas,即 function as a service,函数即服务;其意思也非常好理解,就是能将一个函数作为一个服务进行使用,用户只需要编写一个函数功能即可,不需要额外去关心别的东西。https://github.com/openfaas/faas 是其中的一种实现方式。

环境准备

以下环境在 mac 上进行搭建:

首先需要准备 docker 和 kubernetes 的环境,先做 k8s 的环境直接能通过 docker 桌面进行配置,已经算是很方便了。

image-20201019193844247

安装步骤

openfaas-cli

1
curl -sL https://cli.openfaas.com | sh

namespace

1
2
3
git clone https://github.com/openfaas/faas-netes
cd faas-netes
kubectl apply -f namespaces.yml

password

1
2
3
4
5
6
7
8
$ cat passwd.sh
# PASSWORD=$(head -c 12 /dev/urandom | sha1sum |cut -d' ' -f1)
PASSWORD=admin123
echo $PASSWORD > passwd
kubectl -n openfaas create secret generic basic-auth \
--from-literal=basic-auth-user=admin \
--from-literal=basic-auth-password="$PASSWORD"
$ sh ./passwd.sh

部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ kubectl apply -f ./yaml
$ kubectl get pods -n openfaas --watch

➜ ~ kubectl get pods -n openfaas
NAME READY STATUS RESTARTS AGE
alertmanager-7dd959fd86-stslk 1/1 Running 0 3h30m
basic-auth-plugin-85649fd6fc-4xlph 1/1 Running 0 3h30m
faas-idler-f4597f655-6c4nb 1/1 Running 2 3h30m
gateway-7c579bc859-cpm6g 2/2 Running 1 3h30m
nats-8455bfbb58-gq2vh 1/1 Running 0 3h30m
prometheus-86f7fdf9b5-jtb6q 1/1 Running 0 3h30m
queue-worker-c6d788779-xl6d2 1/1 Running 0 3h30m

# 当全部启动时则正常部署成功

访问

1
2
http://127.0.0.1:31112
admin/admin123

使用

openfaas 默认带有一些可以部署的 function

nodeinfo

image-20201019194703907

image-20201019194738010

点击 deploy 之后等待状态 ready 之后就可以进行使用了,点击 invoke 进行调用,这个 function 是用来获取主机信息的。

ocr

image-20201019194944708

这个 function 是用来做图像识别的

还有其他很多自带的 function 都可以试试,这里不再列举了

qrcode

其实很多 function 的实现是非常简单的,如这个生成二维码的 function,使用 go 实现,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import (
"encoding/binary"
"io/ioutil"
"log"
"os"

qrcode "github.com/skip2/go-qrcode"
)

func main() {
input, err := ioutil.ReadAll(os.Stdin)
if err != nil {
log.Fatalf("Unable to read standard input: %s", err.Error())
}
png, err := qrcode.Encode(string(input), qrcode.Medium, 256)
if err != nil {
log.Fatalf("Unable to read standard input: %s", err.Error())
}
binary.Write(os.Stdout, binary.LittleEndian, png)
}

其实就是调用了一个三方的库,在 main 函数中从 std 读如参数,然后将结果输出到 stdout 中就可以了,就其实和我们普通写的函数一模一样。

实现function

那么如何自己实现一个 function 并注册使用呢?其实也很简单,现在 faas-cli 工具已经提供了相关的功能,这里说明使用 golang 来时进实现的方式,其他语言也是类似的。

初始化

创建一个空目录,在空目录下使用 faas-cli 命令进行初始化

1
faas-cli new hellofaas --lang go

这样你就能得到一个基础的功能目录

hellofaas 文件夹中包含一个 go 文件,这个文件就是你需要自己实现的 function,里面是一个 http 请求的 handle,接受一个参数,返回一个字符串,函数中你可以实现你自己的逻辑功能。

1
2
3
4
5
6
7
8
9
10
package function

import (
"fmt"
)

// Handle a serverless request
func Handle(req []byte) string {
return fmt.Sprintf("Hello, Go. You said: %s", string(req))
}

配置镜像参数

hellofaas.yml 文件是用来部署和上传镜像的

1
2
3
4
5
6
7
8
9
version: 1.0
provider:
name: openfaas
gateway: http://127.0.0.1:31112
functions:
hellofaas:
lang: go
handler: ./hellofaas
image: linkinstar/hellofaas:latest

其中需要修改的是 gateway 为你自己的 faas 部署地址

然后就是 images 是你 docker hub 的地址,如果需要推送到私有仓库需要你手动进行登录操作

构建、推送、部署

剩下就很简单了,三个命令,构建时间可能会长一些,拉取镜像比较缓慢

1
2
3
faas-cli build -f hellofaas.yml
faas-cli push -f hellofaas.yml
faas-cli deploy -f hello.yml --gateway http://127.0.0.1:31112

如果没有问题,那么在页面上你就可以看到你自己的 function 了

image-20201019204020609

当然你也可以这样调用:

echo test | faas-cli invoke hellofaas --gateway http://127.0.0.1:31112

总结

其实对于 faas 的使用还算简单,并没有想象中的那么复杂,它的实现方式也比较符合我的想法,作为一个镜像进行打包进行输出进行使用,而且支持各种语言进行实现,也不失为一种比较好的实现策略吧。

我觉得更多的是 function 的这样的思想,让我们要意识到,什么样类型的功能能被抽离为一个 function ,并且这个的 function 是否应该有业务属性,以及它作为一个 service 的定义是什么,这我觉得是我们应该考虑的。因为它很轻,轻的东西就容易多,多的东西就不好管控,所以控制方面也应该做考虑。

总之要认清它的目标和使用场景还是一个比较难得事情。

参考文档

https://www.lanqiao.cn/library/kubernetes-handbook/usecases/openfaas-quick-start/

https://cloud.tencent.com/developer/article/1681551

http://www.liangxiaolei.fun/2020/06/11/k8s%E7%AC%94%E8%AE%B0-serverless-openfaas%E4%BD%93%E9%AA%8C/

https://linux.cn/article-9078-1.html