« 上一篇下一篇 »

一文浅谈无服务器架构FaaS函数即服务的部署及体验

     无服务器Serverless架构和函数即服务Functions-as-a-Service(FaaS)已经成为云计算领域非常流行的概念。本文从云计算演变角度讨论无服务器架构的内在逻辑关系。

从IaaS、PaaS、SaaS到CaaS,再到火热的微服务架构,人们孜孜不倦的追求着将硬件资源抽象化,从虚拟机到容器,
再到现在的无服务器架构,FaaS是Functions as a Service的简称,代表业务方视角,而Serverless更多是
从部署的视角,其实描述的是类似的事情。

目前AWS的Lambda是无服务架构的代表,你可以很轻易的尝试,目前每个月的前100万次的请求是免费的,快去体验吧。

服务器架构并不严格指定我们的函数在技术上必须是什么。它只是一个工作单元。函数能被以很多方式触发。它也可以是一个定期运行的计时器,也可以是一些相关HTTP请求或服务中的事件。
Serverless Architectures
一文中,Mike Roberts提出了functions-as-a-service六个特点:
1. 从根本上说,FaaS无需管理你自己服务器系统和服务器应用就可以运行后端代码。
2. FaaS无需使用框架和库包,FaaS函数就是带有语言和环境的正常应用。
3. 既然我们没有服务器应用需要运行,部署就非常不同于传统的系统,我们上传代码的FAAS供应商,它就做剩余的事情。
4. 水平扩展是完全自动的,弹性的,并由供应商管理。
5. FaaS是由供应商定义的事件类型触发的函数。
6.大多数供应商也允许函数对HTTP请求触发相对应的响应,通常以某种API网关形式实现。
Adrian Cockroft在其Tweet定义“无服务器”概念是:
如果你的PaaS可以在20ms内启动实例,并运行半秒,那么它就可以称为无服务器。

1.当前流行的faas开源组件
有好多,你去github搜一下,今天需要学习的是目前star数最多的OpenFaas,话说这个组件的作者,各个场合都在不遗余力的宣传,希望大家去标星它。废话不多说了,开始部署。先附上这个项目的地址:openfaas。

2.准备环境
Build a cluster
它可以部署在swarm集群或者k8s集群上,所以前提是你要有一个K8s集群,关于k8s集群的搭建,请参照 kubernetes 1.9.6 集群搭建。如果是用把k8s的各个组件,一个个作为服务去部署的化,你可能会踩无数的坑,但是对你理解k8s会有很大帮助。省事的话就用kubeadm。but!这里需要提醒的是,OpenFaas因为在编译镜像时使用了,多阶段构建的特性,因此docker版本要求必须是,17.05 or higher。
Deploy OpenFaaS
在master节点上执行:
git clone https://github.com/openfaas/faas-netes
faas-nets是一个将faas组件部署在k8s集群的项目,内含一些yaml文件的定义。
3.权限、网关、prometheus等。
cd faas-netes && \
kubectl apply -f ./namespaces.yml,./yaml
这里会创建出2个命名空间:openfaas 和openfaas-fn
4.还有其他和faas有关的pod出来。


这里写图片描述
Use OpenFaaS
使用CLI,这里需要访问aws的存储主机,所以国内的话还是被墙,没办法正常下载部分github上的release包。
curl -sL https://cli.openfaas.com | sudo sh
这里(可能)会失败,需要你去看下这个脚本,单独的下载下来(这个文件在你可以在我这里下载),然后阅读这个很简单的脚本。

手工复制到/usr/local/bin目录下
加个执行权限
创建个软链接
Deploy a function
准备一个函数吧,python的:

1.mkdir -p ~/functions && \
2.cd ~/functions
3.faas-cli new --lang python hello-python
这会生成

1.hello-python.yml
2.hello-python文件夹
改下hello-python/handler.py:

def handle(req):
    print("Hello! You said: " + req)

以及hello-python.yml:

provider:
  name: faas
  gateway: http://clusterIp:31112

functions:
  hello-python:
    lang: python
    handler: ./hello-python
    image: yourName/hello-python(这个地址是dockerhub地址)

在这里记得先docker login一下。否则分发时会提示你没有权限push。
名词解释:

gateway- here we can specify a remote gateway if we need to, what the programming language is and where our handler is located within the filesystem.(即是你的网管地址:xx:31112)
functions - this block defines the functions in our stack(描述函数信息)
lang: python - even though Docker is used behind the scenes to package your function. You don’t have to write your own Dockerfile unless you want to.(语言)
handler - this is the folder / path to your handler.py file and any other source code you need(函数内容)
image - this is the Docker image name. If you are going to push to the Docker Hub change the prefix from hello-python to include your Docker Hub account (例如lmxia/hello-python)
faas-cli build -f ./hello-python.yml
这里可能会报错,如果下载失败,或者超时,你又要科学上网了,或者从写我七牛云上的一个长久有效的地址:http://oikou4x2o.bkt.clouddn.com/faas-clihttp://oikou4x2o.bkt.clouddn.com/fwatchdog 在你的模板目录下,将你的函数对应的模板里Dockerfile里出现的fwathdog全部替换成刚才的链接。
find . -type f | xargs grep "/fwatchdog" 找到所有的fwatchdog地址部分,然后替换掉。

验证
以上步骤成功后
docker images | grep hello-python
能看到本地的docker images,这个就是所谓你的函数运行的image了,所以无服务器架构还是有服务器的。只不过你认为它是透明的就好了。
然后分发到docker.hub上
faas-cli push -f ./hello-python.yml
这样你的node节点,就可以有地方下载了,当然如果你有私有镜像仓库,就传到私有镜像仓库。我这里使用的是docker.hub。

接下来部署

faas-cli deploy -f ./hello-python.yml
curl 127.0.0.1:31112/function/hello-python -d “hello, world!”
这个时候你会发现,k8s神奇的给我们在node节点上部署了一个pod,这个pod镜像正是我们刚刚产生的镜像。

更复杂的用法
比如你的python包还有其他依赖包,比如第三方包等,这块先不写了。