AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

如何将 AWS Node.js Lambda 函数迁移至 OpenFaaS?

  • 2019-10-24
  • 本文字数:4100 字

    阅读完需:约 13 分钟

如何将AWS Node.js Lambda函数迁移至OpenFaaS?

本篇教程,我们将共同了解如何将AWS Lambda函数(Node.js)迁移至 OpenFaaS。

为什么要迁移至 OpenFaas?

云函数服务确实优点很多,不仅成本低廉,而且适合大部分用例的实际需求。但在另一方面,OpenFaaS 相较于云函数服务也拥有不少独特优势。


下面,我先聊聊自己在使用 OpenFaaS 中的具体感受:


  • 可以在自有基础设施上托管函数以满足本地化标准。

  • 确保函数托管在符合用例特性的资源之上(包括 CPU、内存以及 GPU 密集型任务)。

  • 可以使用现有 Kubernetes 或者 Docker Swarm 集群部署 OpenFaaS。

  • 对 TTL 没有任何限制,可以长期保持函数运行。

  • 确保用户不致锁定于特定云服务供应商处。

  • 拥有一整套函数库以及为其提供贡献的活跃社区,能够为项目提供巨大助益。

  • 默认提供自动规模伸缩功能。

  • 支持一系列编程语言选项,甚至能够使用 bash 脚本,极大提升使用体验!

  • 极易学习,而且使用感受也非常友好。

  • Cli 客户端与 faas-cil 的存在又让 OpenFaaS 的使用难度进一步降低。

  • Grafana、Prometheus 以及 ALertManager 可在框架中开箱即用,允许大家轻松查看函数指标并设置警报机制。


根据实际体验,我之前已经建立起一套 Docker Swarm 集群,其中的资源由云服务供应商管理,同时拥有监控、高可用性以及自我修复机制。


现在,我可以在这套集群设置之上使用 OpenFaaS,而且完美匹配实际用例。

架构

终极目标是将 AWS Lambda Function 迁移至 OpenFaaS:


应用程序

我们在AWS中的无服务器应用程序包含 API 网关、DynamoDB 以及 Lambda(Node.js)。


在示例中,我会尽量控制应用程序的复杂度,因此其功能非常简单:当我在 API 网关资源上发出 GET 请求时,在 DynamoDB 表上执行 GetItem。


在这种情况下,我将哈希键值硬编码至 ruan.bekker 中。


整个流程如下所示:


-> API: /dev/person,-> Lambda calls DynamoDB: {"id": "ruan.bekker"},-> Response: {"id": "ruan.bekker", "name": "ruan", ...}
复制代码

AWS 设置

为了完全透明,我将使用无服务器方式设置整个 AWS 栈:


$ mkdir -p ~/dev/aws-node-get-dynamodb \&& cd ~/dev/aws-node-get-dynamodb$ npm install -g serverless$ serverless create --template aws-nodejs 
复制代码


创建 Lambda 函数:


$ mkdir function/handler.js$ cat function/handler.js'use strict';const AWS = require('aws-sdk');const dynamoDb = new AWS.DynamoDB.DocumentClient();module.exports.identity = (event, context, callback) => {const params = {TableName: process.env.DYNAMODB_TABLE,Key: {     id: 'ruan.bekker',   }, };dynamoDb.get(params, (error, result) => {    if (error) {     console.error(error);      callback(null, {        statusCode: error.statusCode || 501,       headers: { 'Content-Type': 'text/plain' },       body: 'GetItem Failed',      });      return;    }    const response = {      statusCode: 200,      body: JSON.stringify(result.Item),    };    callback(null, response);  });};
复制代码


无服务器定义文件:


$ cat serverless.ymlservice: aws-node-get-dynamodbframeworkVersion: ">=1.1.0 <2.0.0"provider:  name: aws  runtime: nodejs10.x  environment:    DYNAMODB_TABLE: my-dynamodb-table  iamRoleStatements:    - Effect: Allow      Action:        - dynamodb:GetItem      Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"functions:  get:    handler: functions/handler.identity    events:      - http:          path: person          method: get          cors: trueresources:  Resources:    TodosDynamoDbTable:      Type: 'AWS::DynamoDB::Table'      DeletionPolicy: Retain      Properties:        AttributeDefinitions:          -            AttributeName: id            AttributeType: S        KeySchema:          -            AttributeName: id            KeyType: HASH        ProvisionedThroughput:          ReadCapacityUnits: 1          WriteCapacityUnits: 1        TableName: ${self:provider.environment.DYNAMODB_TABLE}
复制代码


部署该栈:


$ serverless deploy --region eu-west-1Serverless: Packaging service...Serverless: Excluding development dependencies...Serverless: Uploading CloudFormation file to S3...Serverless: Uploading artifacts...Serverless: Uploading service aws-node-get-dynamodb.zip file to S3 (7.38 MB)...Serverless: Validating template...Serverless: Updating Stack...Serverless: Checking Stack update progress.................Serverless: Stack update finished...Service Informationservice: aws-node-get-dynamodbstage: devregion: eu-west-1stack: aws-node-get-dynamodb-devresources: 12api keys:  Noneendpoints:  GET - https://xx.execute-api.eu-west-1.amazonaws.com/dev/personfunctions:  get: aws-node-get-dynamodb-dev-getlayers:  NoneServerless: Run the "serverless" command to setup monitoring, troubleshooting and testing.
复制代码


现在我们的技术栈已经部署完成,接下来就是向 DynamoDB 中写入一个条目。


由于本文的重点在于迁移,因此我将哈希键硬编码至 ruan.bekker 当中,下面在 DynamoDB 中创建该条目:


$ aws dynamodb put-item \  --table-name my-dynamodb-table --item \'{    "id": {"S": "ruan.bekker"},    "name": {"S": "ruan"},    "surname": {"S": "bekker"},    "country": {"S": "south africa"},    "age": {"N": "32"}}
复制代码


发送一条指向该 API 网关 URL 的 GET 请求:


$ curl https://xx.execute-api.eu-west-1.amazonaws.com/dev/person{"id":"ruan.bekker","surname":"bekker","name":"ruan","country":"south africa","age":32}
复制代码


可以看到,现在我们已经能够在 DynamoDB 中检索到该条目。

设置 OpenFaaZS 函数

创建一个新的 Node.js OpenFaaS 函数(请注意,设置当中使用了镜像前缀与网关 url,如下所示):


$ mkdir -p ~/dev/lambda-to-openfaas-migration \  && cd ~/dev/lambda-to-openfaas-migration$ faas-cli new \  --lang node person \  --prefix=ruanbekker \  --gateway https://openfaas.ruan.dev$ mv person.yml stack.yml
复制代码


在本示例中,我会将 AWS Access Keys 与 Secret Keys 创建为 OpenFaaS secrets:


$ faas-cli secret create my-aws-secret-key --from-literal="your-access-key"$ faas-cli secret create my-aws-access-key --from-literal="your-secret-key"
复制代码


在我们的 package.json 当中提供 aws-sdk 依赖项,并借此与 AWS 进行交互:


$ cat person/package.json{  "name": "function",  "version": "1.0.0",  "description": "",  "main": "handler.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"  },  "keywords": [],  "author": "",  "license": "ISC",  "dependencies": {    "aws-sdk": "latest"  }}
复制代码


我们的栈定义:


$ cat stack.ymlprovider:  name: openfaas  gateway: https://openfaas.ruan.devfunctions:  person:    lang: node    handler: ./person    image: ruanbekker/person:latest    environment:      content_type: application/json      DYNAMODB_TABLE: my-dynamodb-table      AWS_REGION: eu-west-1    secrets:      - my-aws-access-key      - my-aws-secret-key
复制代码


我们的初始设置中仍包含 AWS Lambda 函数代码,但到这里的栈已经设置完成,而且无需任何本地复本。


下面,我们需要下载 Lambda 部署软件包:


$ mkdir aws-lambda \  && cd aws-lambda$ lambda_url=$(aws lambda get-function --function-name serverless-rest-api-with-dynamodb-dev-get  | jq -r .Code.Location)$ curl -o deployment_package.zip "${lambda_url}"
复制代码


提取该部署软件包并利用由此得到的 OpenFaaS 处理程序替换原 Lambda 函数处理程序:


$ unzip deployment_package.zip$ cd ..$ mv aws-lambda/function/handler.js person/handler.js
复制代码


接下来,我们需要修改处理程序以纳入各 secrets 与环境变量:


$ cat person/handler.js'use strict';const fs = require('fs');const secretAK = "/var/openfaas/secrets/my-aws-access-key";const secretSK = "/var/openfaas/secrets/my-aws-secret-key";const accessKey = fs.readFileSync(secretAK, "utf-8");const secretKey = fs.readFileSync(secretSK, "utf-8");const AWS = require('aws-sdk');AWS.config.update({  credentials: new AWS.Credentials ({    region: process.env.AWS_REGION,    accessKeyId: accessKey,    secretAccessKey: secretKey  })})const dynamoDb = new AWS.DynamoDB.DocumentClient();module.exports = (context, callback) => {  const params = {    TableName: process.env.DYNAMODB_TABLE,    Key: {      id: 'ruan.bekker',    },  };  dynamoDb.get(params, (error, result) => {    if (error) {      console.error(error);      callback(null, {        statusCode: error.statusCode || 501,        headers: { 'Content-Type': 'text/plain' },        body: 'GetItem Failed',      });      return;    }    const response = result.Item;    callback(null, response);  });};
复制代码


部署 OpenFaaS 函数:


$ export OPENFAAS_URL=https://openfaas.ruan.dev$ faas-cli upDeploying: person.Deployed. 202 Accepted.URL: https://openfaas.ruan.dev/function/person
复制代码


现在,我们需要在 OpenFaaS API 网关 URL 上通过 GET 请求测试新创建的函数:


$ curl https://openfaas.ruan.dev/function/person{"id":"ruan.bekker","surname":"bekker","name":"ruan","country":"south africa","age":32}
复制代码


搞定,现在我们已经将 AWS Lambda Function 迁移至 OpenFaaS。


原文链接:


https://sysadmins.co.za/migrate-your-aws-node-js-lambda-function-to-openfaas/


2019-10-24 14:571614
用户头像
赵钰莹 极客邦科技 总编辑

发布了 894 篇内容, 共 671.3 次阅读, 收获喜欢 2694 次。

关注

评论

发布
暂无评论
发现更多内容

火山引擎DataTester智能发布:助力产品降低功能迭代风险

字节跳动数据平台

大数据 A/B 测试 对比实验 数字化增长 企业号10月PK榜

火山引擎DataLeap一站式数据治理解决方案及平台架构

字节跳动数据平台

大数据 数据中台 数据安全 数据研发 企业号10月PK榜

3D孪生场景搭建:参数化模型

3D建模设计

模型 数字孪生 参数化模型

3D孪生场景搭建:3D漫游

3D建模设计

数字孪生 3D编辑器 3D漫游

零售业:别让数据安全成为业务的绊脚石!

极盾科技

数据安全 零售行业

Embedding技术与应用 (2) :神经网络的发展及现代Embedding方法简介

Baihai IDP

人工智能 神经网络 AI 嵌入 白海科技

解读亚马逊云服务器 EC2 预留实例与按需实例的区别,及其在成本节约的优势

亚马逊云科技 (Amazon Web Services)

sdk 云服务器 Amazon EC2

要体验 AI 编程助手吗?

亚马逊云科技 (Amazon Web Services)

亚马逊云科技 AIGC

像win一样使用Mac的鼠标右键:MouseBoost Pro

展初云

Mac软件 鼠标扩展

Mac电脑数据转换 EasyDataTransform激活最新

胖墩儿不胖y

数据处理 Mac软件 数据处理工具 编辑数据

EMQ 云边协同的 IIoT 解决方案架构,亮相 2023 工博会

新消费日报

OWASP Top 10漏洞解析(3)- A3:Injection 注入攻击

华为云PaaS服务小智

云计算 软件开发 华为云

3D孪生场景搭建:模型区域摆放

3D建模设计

数字孪生 3D场景编辑器

位移贴图和法线贴图的区别

3D建模设计

材质修改 纹理贴图

透明度和透明贴图制作玻璃水杯

3D建模设计

3D模型 材质修改 纹理贴图

3D孪生场景搭建:模拟仿真

3D建模设计

数字孪生 3D应用场景 3D编辑器

多数据源管理:掌握@DS注解的威力 | 京东云技术团队

京东科技开发者

mybatis Mybatis Plus 企业号10月PK榜 DS注解

DeFi 的兴起:与加密货币交易所应用程序开发的协同作用

区块链软件开发推广运营

交易所开发 dapp开发 区块链开发 链游开发 NFT开发

用户案例合集 | 物联网平台的时序数据处理难点与优化实践

TDengine

时序数据库 ​TDengine 国产时序数据库

操作系统迁移难?Alibaba Cloud Linux 支持跨版本升级 | 龙蜥技术

OpenAnolis小助手

开源 操作系统 迁移 阿里云服务器 龙蜥社区

电力行业首个自主可控的大模型发布了!百度飞桨、文心大模型提供支持

飞桨PaddlePaddle

飞桨 大模型 文心大模型

小白修图必备Topaz Photo AI for Mac图像智能处理工具

展初云

图像处理 Mac 软件 修图软件

苹果Mac视频编辑软件 Final Cut Pro

展初云

Mac软件 视频编辑工具 FCPX软件 fcpx

体验华为云CodeArts Check IDE插件国际化展示效果

华为云PaaS服务小智

软件开发 代码质量 华为云 代码检查

socks5代理怎么帮助广告投放?

巨量HTTP

http代理

从 Greenplum 到 YMatrix,某头部动力电池厂商核心业务数据的迁移实践

YMatrix 超融合数据库

greenplum 迁移数据 超融合数据库 YMatrix 电池厂商

3D孪生场景SDK:Viwer 孪生世界

3D建模设计

数字孪生

【AI模型】首个Joy 模型诞生!!!全民生成Joy大片 | 京东云技术团队

京东科技开发者

AI模型 企业号10月PK榜 京东joy

如何将AWS Node.js Lambda函数迁移至OpenFaaS?_语言 & 开发_Ruan_InfoQ精选文章