时间: 2020-09-03 00:08:26 人气: 2285 评论: 0
本文作者Alex将带我们了解了OpenFaaS的最新改进,也就是对无状态微服务的完整支持,并给出了一个用Ruby和Sinatra编写的留言簿示例。
目前,我们已经在OpenFaaS 0.9.0中合并并发布了对无状态微服务的支持。这意味着工程师现在可以利用OpenFaaS中简单而强大的开发人员体验,打造出管理你所有FaaS函数和微服务的单一平台。整套体验的内容从CLI到Prometheus度量,再到内置的自动扩展都包括在内。甚至缩放到零都得到了支持。本文中,我将引领大家部署一个用Ruby和Sinatra编写的留言簿示例,这个留言簿由MySQL支持,使用Kubernetes部署到OpenFaaS上。
现代的云原生微服务和FaaS函数之间有很多重叠部分,我将在下一部分中具体说明。OpenFaaS一直支持在Windows上运行任何容器或进程,无论是FaaS函数、AWS CLI、ImageMagick甚至是PowerShell都可以。社区在短时间内提出了两个要求,这两个要求成为了我们的故事进一步发展的催化剂。
我们在Wireline.io的一位新用户提出了一项功能请求,希望增强函数的HTTP路由功能。Wireline希望编写出无需任何额外更改,就可以同时运行在AWS Lambda和OpenFaaS上的函数。大约在同一时间,GitLab的首席执行官Sid Sijbrandi联系了我们,希望了解更多关于无服务器的信息,并想知道如何在GitLab上利用它。Sid问我,OpenFaaS能否同时用来管理FaaS函数,和他的团队更熟悉的一些微服务(例如Sinatra应用)。他对在空闲时缩放到零的能力表现出了特别的兴趣。
在开始研究示例,展示如何将Sid的请求付诸实践之前,我们先来看一些背景知识。
在了解什么是“无状态微服务”之前,我们先来看"FaaS函数"的定义。我在2017年1月发表的博客文章:函数即服务(FaaS)中给出了具体定义。
函数往往会:
从第一篇文章发表以来,我拓展了自己最初的观察,将函数的定义重写为一系列属性。
函数是:
函数是无状态的,因为它们不依赖内部存储器、状态机、存储的文件或挂载的卷。根据外部服务,对函数的每次调用应导致相同的最终结果。函数不必严格幂等,但在严格幂等时更易管理。
函数是短暂的,因为在任何时候都可以用相同的副本替换它们,而不会影响行为。这一属性意味着我们可以用相同的方式管理所有函数——检查函数的运行状况、查看它们的生命周期、日志记录,乃至监控工作等都可以用同一种方法来处理。
函数能自动从最小副本数扩展到最大副本数,甚至自动降到零并再次扩展上来,以匹配需求或节省资源。
函数是单一用途的,但必须以常识为准。我们用不着每次在代码中编写 function x() {} 或 def x: 时都创建一个新的FaaS函数。函数的单一用途可能是“一条员工记录的CRUD”“格式化此IBAN”或“使用机器学习模型识别此图像的内容”。
只要你编写了至少一个无服务器函数,那么你就会意识到入口点往往已经从你那里抽象出来了。你只需编写一个处理程序——然后所有依赖项都以一种通用格式表示,例如Node.js的package.json或Python的requirements.txt文件。
下面是一个Node.js函数的示例:
"use strict" module.exports = (context, callback) => { callback(undefined, {status: "done"}); }
作为开发人员,你用不着了解用于引导处理程序的机制——这是无聊的重复性细节,你可以让FaaS框架或工具包来操心这些事情。 我们看到了类似的抽象模式,也看到了诸如Sinatra、Django和Express.js之类的微服务框架中隐藏无聊细节的现象。一种尺寸很少能满足所有需求,因此每种语言或运行时都有多种选择。
无状态微服务是一种微服务,它可以像FaaS函数一样进行部署,并可以通过FaaS框架或OpenFaaS这样的平台来管理。因此,在OpenFaaS CLI、Gateway API或UI中不需要特殊的路由(route)、标志(flag)或过滤器(filter)。
就OpenFaaS组件而言,函数可以用任何语言编写并打包在Docker映像中。它必须通过8080端口上的HTTP提供内容,并将锁定文件写入/tmp/.lock。如果你的函数或服务检测出自身的异常,那么你可以删除锁定文件,OpenFaaS将重新启动/重新安排你的函数。
OpenFaaS有一个Ruby语言模板,可用于创建Ruby FaaS函数。Ruby无状态微服务是使用https://rubyonrails.org/](https://rubyonrails.org/">Ruby on Rails(、Sinatra或其他Ruby微服务框架创建的Ruby微服务。其中的主要区别在于,与FaaS函数相比你要做的工作更多了。现在,你必须管理自己的Dockerfile、状况检查和路由。
Sinatra是Ruby的DSL或框架,用于快速构建微服务。
下面是官方网站上的hello-world示例:
require 'sinatra' get '/frank-says' do 'Put this in your pipe & smoke it!' end
如果我们将该文件另存为main.rb并运行gem install sinatra,然后运行ruby main.rb,则将在默认端口5678上启动一个Web服务器,然后可以跳转至URL:http://127.0.0.1:5678/frank-says上。
OpenFaaS CLI可以模板化、构建和部署这个微服务。然后,OpenFaaS平台将跟踪这个微服务的调用指标,并将其自动放大、缩小甚至降为零并再次放大。
下面我们来使用Sinatra创建一个无状态微服务。
你首先需要准备一些工具:
首先创建一个新文件夹并生成一个dockerfile函数。其中dockerfile模板会告诉OpenFaaS CLI,在不应用其他任何脚手架或模板的情况下运行Docker构建,你必须提供自己的Dockerfile。
$ mkdir -p sinatra-for-openfaas/ \ && cd sinatra-for-openfaas/ $ faas-cli new --prefix=alexellis2 --lang dockerfile frank-says
用你的Docker Hub帐户或另一个Docker仓库替换alexellis2。一个Docker映像将被推送到这里,这是build/faas-cli up命令的一部分。
这将创建两个文件,就像你用faas-cli new上列出的一种语言创建函数时一样:
./frank-says/Dockerfile ./frank-says.yml
创建一个Gemfile和main.rb文件: ./frank-says/main.rb:
require 'sinatra' set :port, 8080 set :bind, '0.0.0.0' open('/tmp/.lock', 'w') { |f| f.puts "Service started" } get '/' do 'Frank has entered the building' end get '/logout' do 'Frank has left the building' end
有关OpenFaaS负载的注意事项:
./frank-says/Gemfile:
source 'https://rubygems.org' gem "sinatra"
可以在此文件中添加任意gems列表。 现在将./frank-says/Dockerfile替换为:
FROM ruby:2.4-alpine3.6 WORKDIR /home/app COPY . . RUN bundle install RUN addgroup -S app \ && adduser app -S -G app RUN chown app:app -R /home/app WORKDIR /home/app HEALTHCHECK --interval=5s CMD [ -e /tmp/.lock ] || exit 1 USER app CMD ["ruby", "main.rb"]
Dockerfile执行以下操作:
现在你已经做好了准备,可以使用OpenFaaS CLI构建和部署示例了。
$ docker login
$ faas-cli up --yaml frank-says.yml Deploying: frank-says. Deployed. 200 OK. URL: http://127.0.0.1:8080/function/frank-says
使用curl调用你的微服务,或在Web浏览器中查看它:
$ curl http://127.0.0.1:8080/function/frank-says/ Frank has entered the building.
你也可以尝试自定义路径:
$ curl http://127.0.0.1:8080/function/frank-says/logout Frank has left the building.
你可以尝试更新消息或添加其他路由,然后再次运行faas-cli以重新部署微服务。 现在检查faas-cli list,能看到每次访问微服务时调用计数会随之增加。
$ faas-cli list Function Invocations Replicas frank-says 5 1
现在,我们可以使用简单的bash for循环来触发自动扩展:
$ for i in {1..10000} do sleep 0.01 \ && curl http://127.0.0.1:8080/function/frank-says \ && echo done
在另一个窗口中输入:watch faas-cli list或者定期运行faas-cli list 。自动扩展生效后,你应该能看到Invocations的值增加,并且Replicas值也会增加。
Function Invocations Replicas frank-says 702 4
当bash for循环完成或使用Ctrl + C取消它时,你会看到副本数减少到1。 你也可以在以下网址使用OpenFaaS UI监视和调用微服务:http://127.0.0.1:8080
阅读有关自动扩展的更多信息,包括如何配置最小、最大和零副本缩放参数
$ git clone https://github.com/openfaas-incubator/openfaas-sinatra-guestbook \ && cd openfaas-sinatra-guestbook
在./sql.yml中配置你的MySQL数据库细节。如果你还没有MySQL,那么只需花几分钟使用Kubernetes上的helm或docker run,以及官方Docker映像就能部署完毕。
$ cp sql.example.yml sql.yml
最后部署留言簿:
$ faas-cli up http://127.0.0.1:8080/function/guestbook
使用上面命令提供的URL来访问微服务。 在UI中登录留言簿,完成后,你可以随时发布到/function/guestbook/reset来重置MySQL表。
留言簿代码的状态存储在MySQL表单中,这意味着它可以随时重新启动而不会丢失数据。这是FaaS函数和无状态微服务的一个关键属性。如果OpenFaaS添加了我们代码的其他副本——每个副本都将具有相同的环境视图,因为它依赖于外部数据库来获取其数据。
要启用缩放到零的功能,只需按照文档说明启用faas-idler。
然后在你的stack.yml文件中添加一个标签,以告知OpenFaaS你的函数可以进行零缩放:
labels: com.openfaas.scale.zero: true
最后,通过faas-cli up重新部署留言簿。一旦检测到空闲状态,faas-idler现在会将你的函数缩放到零副本。默认的空闲时间设置为5分钟,可以在部署时配置。 回到Sid最初的问题,我们已经部署了一个用Ruby编写的无状态微服务,该服务将在空闲时缩放到零,还能及时扩展以服务流量。管理它的方式与我们现有的FaaS函数完全相同,这意味着你可以专注于构建重要的内容,而不必操心Kubernetes或Docker Swarm的内部细节。
现在,我们已经使用MySQL、ebs视图、Bootstrap和Sinatra部署了一个简单的hello-world Sinatra服务和一个更完整的留言簿示例。接下来你就可以开始使用OpenFaaS简化开发人员工作流程了——你可以使用FaaS函数,或者简化微服务的管理工作。
作者介绍: Alex Ellis(alex@openfaas.com)是@openfaas的创始人。
-深蓝源码网-www.69shenlan.com