基于Fn构建我们自己的Serverless

基于Fn构建我们自己的Serverless

无服务器计算 是云计算最突出的趋势之一。 基本操作原则是基础设施不是 DevOps 关心的,而是服务提供商关心的。 资源缩放会根据负载自动调整,并且变化率较高。

另一个常见特征是倾向于最小化和集中代码,这就是无服务器计算有时被称为功能即服务 (FaaS) 的原因。

从历史上看,第一家使用 AWS Lambda 提供 FaaS 的云提供商是 Amazon,因此得名。 其他云服务提供商也提供类似的服务:

  • 来自 Google 的云功能
  • Microsoft 的 Azure 函数

所有这些公司都提供无服务器计算、自动扩展,并且只为您实际使用的内容付费,但他们将客户锁定在他们的专有产品中。 然而,无服务器计算有免费和开源的替代方案。 值得注意的是:

  • 平台 Apache OpenWhisk,在 IBM 的孵化器中开发,
  • Spring 云函数,作为相当丰富的 Spring Framework 生态系统的一部分,也可以用作 AWS Lambda、Azure Functions 和 OpenWhisk 的外观,
  • 项目 Fn,由 Oracle 支持。

所有这些都完全独立于云,也就是说,它们可以安装在任何云中,包括您自己的云、公共云或私有云,当然还有 Exoscale。

Fn 项目如何运作

Fn 完全基于 Docker,由两个主要组件组成:

  • CLI程序旨在管理Fn基础设施的各个方面,并与Fn服务器交互,
  • Fn 服务器本身是打包在 Docker 容器中的常规应用程序。

Fn 中部署的函数也在单独的容器中执行,这使您可以支持很多编程语言,例如...... Clojure!

函数参数传递到标准输入 (STDIN),结果写入标准输出 (STDOUT)。 如果参数或返回值不是简单值(例如 JSON 对象),则可以使用 Fn 本身以函数开发工具包(FDK)形式提供的抽象层进行转换。

为了方便起见,提供了内置的模板集,以方便在广泛的不同语言及其版本(Go、不同版本的 Java、Python 等)中部署 FaaS。

按照下图创建 FaaS 很容易:

  • 使用Fn CLI部署功能:根据所选模板创建Fn的应用程序配置文件。
  • 我们再次使用 CLI Fn 推出我们自己的功能:将容器映像放置在某个存储库中,然后通知服务器该映像的存在和放置。

基于Fn构建我们自己的Serverless
向Fn传递功能的原理

Serverless功能的本地安装和测试

让我们开始在本地计算机上安装 Fn。 首先,按照 Fn 的要求安装 Docker。 假设我们使用 Debian/Ubuntu:

$ sudo apt-get update
$ sudo apt-get install docker.io

或者根据您的系统使用包管理器/Docker 构建。 然后您可以直接安装 Fn CLI。 例如,使用卷曲:

$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh

如果您使用的是安装了 Homebrew 的 OSX,则可以采用其他方法:

$ brew install fn

==> Downloading https://homebrew.bintray.com/bottles/fn-0.5.8.high_sierra.bottle.tar.gz
==> Downloading from https://akamai.bintray.com/b1/b1767fb00e2e69fd9da73427d0926b1d1d0003622f7ddc0dd3a899b2894781ff?__gda__=exp=1538038849~hmac=c702c9335e7785fcbacad1f29afa61244d02f2eebb
######################################################################## 100.0%
==> Pouring fn-0.5.8.high_sierra.bottle.tar.gz
  /usr/local/Cellar/fn/0.5.8: 5 files, 16.7MB

现在我们已准备好使用 CLI 来初步部署我们的函数。 为简单起见,我们将使用内置的启动环境,例如 Node:

$ fn init --runtime node --trigger http hellonode

Creating function at: /hellonode
Function boilerplate generated.
func.yaml created.

将创建一个新目录 hellonode 使用一些基本配置文件进一步开发我们的 Fn 功能。 在新创建的目录中,您可以按照所选语言或运行时的标准创建应用程序:

# Каталог с node выглядит так:

   hellonode
   ├── func.js
   ├── func.yaml
   └── package.json

# Свежеустановленное окружение Java11 такое:

   hellojava11
   ├── func.yaml
   ├── pom.xml
   └── src
       ├── main
       │   └── java
       │       └── com
       │           └── example
       │               └── fn
       │                   └── HelloFunction.java
       └── test
           └── java
               └── com
                   └── example
                       └── fn
                           └── HelloFunctionTest.java

Fn 创建初始项目结构,创建文件 func.yaml,包含 Fn 的必要设置,并以您选择的语言设置代码模板。

对于 Node 运行时,这意味着:

$ cat hellonode/func.js

const fdk=require('@fnproject/fdk');

fdk.handle(function(input){
  let name = 'World';
  if (input.name) {
    name = input.name;
  }
  return {'message': 'Hello ' + name}
})

现在我们将在本地快速测试我们的函数,看看一切是如何工作的。

首先,我们将启动 Fn 服务器。 前面已经提到,Fn 服务器是一个 Docker 容器,因此启动后,它会从 Docker 注册表中获取镜像。

$ fn start -d                    # запускаем локальный сервер в фоне

Unable to find image 'fnproject/fnserver:latest' locally
latest: Pulling from fnproject/fnserver
ff3a5c916c92: Pull complete
1a649ea86bca: Pull complete
ce35f4d5f86a: Pull complete

...

Status: Downloaded newer image for fnproject/fnserver:latest
668ce9ac0ed8d7cd59da49228bda62464e01bff2c0c60079542d24ac6070f8e5

要运行我们的功能,必须“推出”它。 这需要 имя приложения:在Fn中,所有应用程序都必须指定为相关函数的命名空间。

Fn CLI 将搜索该文件 func.yaml 在将用于配置该功能的当前目录中。 所以首先你需要进入我们的目录 hellonode.

$ cd hellonode
$ fn deploy --app fnexo --local  # выкатываем функцию локально, имя приложения - fnexo.
                                 # параметр local не заливает образ в удаленный реестр,
                                 # запуская его напрямую

Deploying hellonode to app: fnexo
Bumped to version 0.0.2
Building image nfrankel/hellonode:0.0.3 .
Updating function hellonode using image nfrankel/hellonode:0.0.3...
Successfully created app:  fnexo
Successfully created function: hellonode with nfrankel/hellonode:0.0.3
Successfully created trigger: hellonode-trigger

从命令输出中可以看到,创建了一个新的 Docker 容器映像,其中包含我们的函数。 该函数已准备好被调用,我们有两种方法可以调用:

  • 使用 Fn 命令 invoke
  • 直接通过调用 http

通话 invoke 通过 Fn 它只是模拟通过 HTTP 进行测试的工作,这方便快速测试:

$ fn invoke fnexo hellonode      # вызываем функцию hellonode приложения fnexo

{"message":"Hello World"}

为了直接调用函数,您需要知道完整的 URL:

$ curl http://localhost:8080/t/fnexo/hellonode-trigger

{"message":"Hello World"}

Fn 服务器在端口 8080 上公开其函数,并且函数 URL 似乎与模式匹配 t/app/function,但不完全。 通过 HTTP,函数不是直接调用的,而是通过所谓的触发器来调用,根据其名称,触发器“启动”函数调用。 触发器定义在 `func.yml 项目:

schema_version: 20180708
name: hellonode
version: 0.0.3
runtime: node
entrypoint: node func.js
format: json
triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode-trigger    # URL триггера

我们可以更改触发器名称以匹配函数名称,这将简化一切:

triggers:
- name: hellonode-trigger
  type: http
  source: /hellonode    # совпадает с именем функции

然后我们再次运行函数传递并从新的触发器中调用它:

$ fn deploy --app fnexo hellonode --local
$ curl http://localhost:8080/t/fnexo/hellonode

{"message":"Hello World"}

一切正常! 是时候进行全面实验并在服务器上发布我们的 FaaS 了!

在您自己的基础设施上安装无服务器功能服务

让我们使用 Exoscale CLI 快速安装虚拟机。 如果您还没有设置,您可以使用 我们的快速入门指南。 这是一个很酷的工具,可以进一步提高您的工作效率。 不要忘记,您需要在安全组中配置一条规则来打开8080端口! 以下命令将启动一个干净的虚拟机,准备好托管我们的功能:

$ exo firewall create fn-securitygroup
$ exo firewall add fn-securitygroup ssh --my-ip
$ exo firewall add fn-securitygroup -p tcp -P 8080-8080 -c 0.0.0.0/0
$ exo vm create fn-server -s fn-securitygroup

然后你可以 ssh 进入虚拟机并安装远程 Fn 服务器:

$ exo ssh fn-server

The authenticity of host '185.19.30.175 (185.19.30.175)' can't be established.
ECDSA key fingerprint is SHA256:uaCKRYeX4cvim+Gr8StdPvIQ7eQgPuOKdnj5WI3gI9Q.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '185.19.30.175' (ECDSA) to the list of known hosts.
Welcome to Ubuntu 18.04 LTS (GNU/Linux 4.15.0-20-generic x86_64)

然后按照与本地计算机上相同的方式安装 Docker 和 Fn 服务器,启动服务器:

$ sudo apt-get update
$ sudo apt-get install docker.io
$ sudo systemctl start docker
$ curl -LSs https://raw.githubusercontent.com/fnproject/cli/master/install | sh
$ sudo fn start

...

    ______
   / ____/___
  / /_  / __ 
 / __/ / / / /
/_/   /_/ /_/
    v0.3.643

Fn 已准备好接收函数! 为了有针对性地将功能传输到远程服务器,我们将使用以下命令 deploy 通过省略标志从本地计算机 --local.

此外,Fn 要求您指定 Fn 服务器和 Docker 注册表的位置。 这些选项可以通过环境变量设置 FN_API_URL и FN_REGISTRY 分别,而且还提供了一种更方便的方法来轻松管理部署配置的创建和管理。

用 Fn 术语来说,部署的配置称为 context。 以下命令将创建上下文:

$ fn create context exoscale --provider default --api-url http://185.19.30.175:8080 --registry nfrankel

您可以像这样查看可用的上下文:

$ fn list contexts

CURRENT NAME      PROVIDER      API URL                      REGISTRY
    default       default       http://localhost:8080/
    exoscale      default       http://185.19.30.175:8080    nfrankel

并切换到刚刚创建的上下文,如下所示:

 $ fn use context exoscale

 Now using context: exoscale

从这里开始,Fn 功能交付将使用选定的 DockerHub 帐户下载 Docker 映像(在我的例子中 - nfrankel),然后通知远程服务器(在本例中 - http://185.19.30.175:8080)有关包含您的函数的最新映像的位置和版本。

$ fn deploy --app fnexo .   # выполняется на локальной машине из каталога hellonode

Deploying function at: /.
Deploying hellonode to app: fnexo
Bumped to version 0.0.5
Building image nfrankel/hellonode:0.0.5 .

最后:

$ curl http://185.19.30.175:8080/t/fnexo/hellonode

{"message":"Hello World"}

基于Fn构建我们自己的Serverless
基于 Fn 的无服务器计算中的函数生命周期

根据自己的能力进行无服务器计算的优势

无服务器计算是一种方便的解决方案,可快速实现与更复杂的应用程序或微服务交互的应用程序的独立部分。

这通常是由于锁定所选供应商的隐性成本造成的,根据具体的用例和数量,这可能会导致未来更高的成本和更低的灵活性。

在这种情况下,多云和混合云架构也会受到影响,因为您很容易发现自己想要使用无服务器计算,但由于公司政策的原因,这可能是不可能的。

Fn 非常易于使用,可以提供几乎相同的 FaaS 接口,开销很小。 它消除了任何供应商锁定,可以在本地安装或在您选择的任何方便的云解决方案提供商中安装。 选择编程语言也有自由。

本文仅介绍 Fn 的基础知识,但创建自己的运行时非常简单,并且可以使用 Fn 负载均衡器或通过将 Fn 放置在代理后面进行保护来更广泛地部署整体架构。

来源: habr.com

添加评论