使用 Fn Project 搭建 ServerLess 无服务器平台
Fn 项目是一个开源容器原生无服务器平台,您可以在任何地方运行——任何云或本地。它易于使用,支持每种编程语言,并且具有可扩展性和高性能。
介绍
随着云的发展 从 IaaS(基础设施即服务) PaaS(平台即服务) BaaS(后端即服务) 再到 FaaS(函数即服务) ,上云的成本越来越低,我们应该随着时代的进步而进步,根据自身需要而学习新的、可靠、方便的技术。
先了解一下基础概念:
函数计算(Function Compute): 函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。
Fun: Fun 是一个go语言编写的用于支持 Serverless 应用部署工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个资源配置文件(template.yml),协助您进行开发、构建、部署操作。
Serverless(无服务器):Serverless 强调的是一种架构思想和服务模型,让开发者无需关心基础设施(服务器等),而是专注到应用程序业务逻辑上。
ServerLess具有以下特征:
- 免运维:不需要用户管理服务器主机或者服务器进程。
- 弹性伸缩:根据负载进行自动规模伸缩与自动配置。
- 按需付费:根据使用情况而决定实际成本。
- 高可用:具备隐含的高可用性。
搭建
使用ServerLess要么购买共有云的服务,或者自己搭建。市面上很多云服务厂商都已经支持FaaS云服务,比如腾讯云阿里云等,华为云的FaaS服务也在内测中相信过不久就会上架。
私有部署则有很多开源的方案,目前流行的是OpenFaas库,它基于K8s服务,搭建比较复杂。
所以我们选择FnProject项目,只需要安装Docker即可使用。官网:https://fnproject.io/
fnproject支持在多平台上安装使用,比如Mac、Linux、Windows,这里我们在Linux平台上安装。
我使用的环境Centos7.6,2核4G内存。
安装Docker
# 配置docker yum源
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 安装Docker
sudo yum install docker-ce docker-ce-cli containerd.io -y
# 启动Docker,设置docker开机自启
sudo systemctl start docker
sudo systemctl enable docker
安装FnProject
# 法1:使用FnProject安装
curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
# 法2:去 git仓库Releases界面下载二进制软件
# https://github.com/fnproject/fn/releases
生成ServerLess应用
FnProject提供GO、Java、Node.js、Python、Ruby,C#语言支持:https://fnproject.io/tutorials/。
这里只演示Python
启动Fn服务器
# 启动fn服务器,此模式会在前台运行,结束程序会停止服务运行
# 注:Fn服务默认使用8080端口
fn start
# 注意: Fn 服务器将其元数据存储在~/.fn/data目录中。如果您在更新 Fn 服务器后遇到错误,您可能需要删除该data目录的内容并重新启动 Fn 服务器。
# 如果使用不同端口,请使用--port 或 -p 参数
FN_API_URL
使用非默认端口时,您必须使用环境变量将 Fn CLI 指向新端口:
export FN_API_URL=http://127.0.0.1:8081
配置Context
在我们开始使用 Fn 之前,我们需要将 Fn 配置为指向适当的 Docker 注册表(docker镜像仓库),以便它知道将您的函数图像推送到哪里。通常 Fn 通过指定您的 Docker Hub 用户名指向您的 Docker Hub 帐户。但是,对于纯本地开发,我们可以简单地使用任意值配置 Fn,例如“fndemouser”。
我们将注册表值存储在 Fn 上下文中。Fn 上下文代表我们当前的部署环境,如果我们要部署到多台服务器,我们可以拥有多个环境。
# 获取可用上下文列表
fn list contexts
会有这样的输出:
选择上下文:
fn use context default
如果是用于本地开发则设置为任意值
fn update context registry fndemouser
创建一个python环境的函数
该fn init
命令创建了一个带有一些样板的简单函数来帮助您入门。该--runtime
选项用于指示我们将要开发的函数将使用 Python 编写。还支持许多其他运行时。Fn 在目录中创建简单函数以及几个支持文件/pythonfn
。
# 创建一个python的函数
fn init --runtime python pythonfn
# 进入到pythonfn文件夹
cd pythonfn
进入到pythonfn文件夹后可以看到“func.py func.yaml requirements.txt”三个文件
# func.py 文件
import io
import json
from fdk import response
def handler(ctx, data: io.BytesIO=None):
name = "World"
try:
body = json.loads(data.getvalue())
name = body.get("name")
except (Exception, ValueError) as ex:
print(str(ex))
return response.Response(
ctx, response_data=json.dumps(
{"message": "Hello {0}".format(name)}),
headers={"Content-Type": "application/json"}
)
# func.yaml 文件
# 标识此函数文件的架构版本。本质上,它决定了哪些字段存在于func.yaml.
schema_version: 20180708
# 函数的名称。匹配目录名称。
name: pythonfn
# 版本 0.0.1
version: 0.0.1
# 运行时/语言的名称,基于创建时的--runtime 参数
runtime: python
# 调用函数时要调用的可执行文件的名称,在本例中为/python/bin/fdk
entrypoint: /python/bin/fdk /function/func.py handler
# 函数的最大内存大小,以兆字节为单位。
memory: 256
requirements.txt 文件中存放python函数的所有依赖项
检查contexts
上下文在本地演示中并不重要,默认不需要配置,在生产环境中请参考安装说明。
创建应用程序
fn create app pythonapp
成功则返回以下结果:
Successfully created app: pythonapp
部署应用程序
如果您之前使用过 Docker,那么输出fn --verbose deploy
应该看起来很熟悉——它看起来就像您在docker build
使用 Dockerfile 运行时看到的输出。当然,这正是正在发生的事情!当你部署这样的函数时,Fn 会为你的函数动态生成一个 Dockerfile,构建一个容器,然后加载它以供执行。
# 部署函数
# --verbose 查看函数部署期间发生的情况的详细信息
# --app pythonapp将函数放入应用程序中pythonapp。
# 指定 --local会部署到本地服务器,但不会将函数映像推送到 Docker 注册表——如果我们要部署到远程 Fn 服务器,这将是必要的。
fn --verbose deploy --app pythonapp --local
# 第一次构建特定语言的函数时,Fn 下载必要的 Docker 映像需要更长的时间。该--verbose选项允许您查看此过程。
# 输出消息Updating function pythonfn using image fndemouser/pythonfn:0.0.2...让我们知道该函数已打包在 image 中fndemouser/pythonfn:0.0.2。
# 请注意,包含文件夹名称pythonfn用作生成的 Docker 容器的名称,并用作容器绑定到的函数的名称。
查看部署的函数
fn CLI 提供了几个命令来让我们查看我们部署的内容。
fn list apps
正常应输出:
fn 列表函数命令列出了与 app 相关的所有功能。
fn list functions pythonapp
正常应输出:
调用函数
使用CLI调用函数
fn invoke pythonapp pythonfn
当您调用“pythonapp pythonfn”时,fn 服务器会查找“pythonapp”应用程序,然后查找绑定到“pythonfn”函数的 Docker 容器映像并执行代码。Fninvoke
直接且独立地调用您的函数。
您还可以将数据传递给调用命令。请注意,您为传递的数据设置了内容类型。例如:
echo -n '{"name":"Bob"}' | fn invoke pythonapp pythonfn --content-type application/json
正常输出:
通过URL调用函数
除了使用 Fn 调用命令外,我们还可以通过 URL 调用函数。为此,我们必须获取函数的调用端点。使用命令“fn inspect function <appname> <function-name>”。要列出 nodefn 函数的调用端点,我们可以键入:
fn inspect function pythonapp pythonfn
正常输出:
根据输出我们可知调用端点为:http://localhost:8080/invoke/01DJRP8FT8NG8G00GZJ00000
使用curl测试函数:
curl -X "POST" -H "Content-Type: application/json" http://localhost:8080/invoke/01DJRP8FT8NG8G00GZJ0000002
正常输出:
还可以将json数据传给函数:
curl -X "POST" -H "Content-Type: application/json" -d '{"name":"Bob"}' http://localhost:8080/invoke/01DJRP8FT8NG8G00GZJ0000002
正常输出:
- 点赞
- 收藏
- 关注作者
评论(0)