Serverless Custom (Container) Runtime

3.编写资源配置文件 template.yaml

在当前目录下编写一份用于部署到函数计算的资源配置文件 template.yaml:

ROSTemplateFormatVersion: ‘2015-09-01’

Transform: ‘Aliyun::Serverless-2018-04-03’

Resources:

custom-runtime: # 服务名称

Type: ‘Aliyun::Serverless::Service’

Properties:

Description: ‘helloworld’

custom-runtime-ts: # 函数名称

Type: ‘Aliyun::Serverless::Function’

Properties:

Handler: index.handler # Handler 在此时没有实质意义,填写任意的一个满足函数计算 Handler 字符集约束的字符串即可, 例如 index.handler

Runtime: custom # custom 代表自定义运行时

MemorySize: 512

CodeUri: ‘./’

4.部署、调用测试、完成

(1)使用 fun deploy -y 命令将我们的自定义运行时和业务逻辑代码所有资源部署到阿里云。

(2)使用命令调用部署函数,验证

$ fun invoke -e “hello,my custom runtime”

看到成功输出,就代表我们的 Custom Runtime 大功告成了!它可以直接运行我们写的 TS 代码了。

实现 Custom Container Runtime


TS 的运行环境问题可以用 Custom Runtime 解决,但是 Node 某些版本平台不支持的问题,就不能用同样的办法了。因为 Node 是全局安装的,依赖系统环境。

FC 平台已经为我们想好了此类问题的解决办法,为我们提供了 Custom Container Runtime(自定义容器运行环境)的能力。FaaS 平台有这种能力,是因为它的底层实现原理是 Docker 容器,所以它通过运用容器技术,把我们的应用代码和运行环境打包为 Docker 镜像,保持环境一致性。实现一次构建,到处运行。

工作原理

Custom Container Runtime 工作原理与 Custom Runtime (https://help.aliyun.com/document_detail/132044.htm#Task-2259898) 基本相同:

  • 函数计算系统初始化执行环境实例前会扮演该函数的服务角色,获得临时用户名和密码并拉取镜像

  • 拉取成功后根据指定的启动命令 Command、参数 Args 及 CAPort 端口(默认 9000)启动自定义的 HTTP Server。

  • 然后这个 HTTP Server 接管了函数计算系统的所有请求,包括来自事件函数调用及 HTTP 函数调用。

下面我们自定义一个 Node V16.1.0 版本的容器运行环境。

操作步骤
1.自定义 HTTP Server

这一步和 Custom Runtime 相同,使用 Node.js Express 自定义一个 Http 服务 server.js,GET 和 POST 方法分别路由至不同的 Handler:

// server.js 文件

‘use strict’;

const express = require(‘express’);

// Constants

const PORT = 9000;

const HOST = ‘0.0.0.0’;

// HTTP 函数调用

const app = express();

app.get(‘/*’, (req, res) => {

res.send(Hello FunctionCompute, http function, runtime is : Node ${process.version}\n);

});

// 事件函数调用

app.post(‘/invoke’, (req, res) => {

res.send(Hello FunctionCompute, event function,runtime is : Node ${process.version}\n);

});

// 启动 HTTP 服务并监听 9000 端口

var server = app.listen(PORT, HOST);

console.log(Running on http://${HOST}:${PORT});

server.timeout = 0; // never timeout

server.keepAliveTimeout = 0; // keepalive, never timeout

启动服务,本地测试一下:

# 启动 HTTP 服务

$ node server.js

# 新开一个终端,通过 curl 命令测试

$ curl http://0.0.0.0:9000

Hello FunctionCompute, http GET, this runtime is : Node v11.5.0     # 这是我本地的 Node 版本,后面在自定义容器中会输出 v16.1.0

验证通过。

2.构建镜像并上传

同样的,需要先做两个准备工作:

  • 1)安装启动 Docker

  • 2)使用阿里云容器镜像服务创建命名空间和镜像仓库 (https://cr.console.aliyun.com/) 存放我们的自定义镜像

接下来,先编写 Dockerfile,再构建包含我们 Node 指定版本运行环境和应用代码的镜像,最后上传到自己的镜像仓库。

(有需要的同学可以先看下这篇文章如何把一个 Node.js web 应用程序给 Docker 化 (https://nodejs.org/zh-cn/docs/guides/nodejs-docker-webapp/) )

(1) 编写 Dockerfile:

# 基于基础镜像 node:16.1.0-alpine3.11 构建我们自己的镜像

FROM node:16.1.0-alpine3.11

# 设置容器工作目录

WORKDIR /usr/src/app

# 将 package.json 和 package-lock.json 都拷贝到工作目录

COPY package*.json ./

# 安装依赖

RUN npm install

# 将当前目录下的所有文件拷贝到容器工作目录中

COPY . .

# 暴露容器 8080 端口

EXPOSE 8080

# 在容器中启动应用程序

ENTRYPOINT [ “node”, “server.js” ]

(2)安装启动 Docker,登录阿里云镜像服务,构建并上传:

# 登录

$ sudo docker login --username=xxx registry.cn-hangzhou.aliyuncs.com

登录成功后,先构建 Docker 镜像:

# 指定 ACR 镜像地址:其中 my_serverless 为你自己的容器命名空间;nodejs 为你自己的镜像仓库名称;v16.1.0 为镜像版本号

$ export IMAGE_NAME=“registry.cnhangzhou.aliyuncs.com/my_serverless/nodejs:v16.1.0”

# 构建镜像

# -t 给镜像取名字打标签,通常 name:tag 或者 name 格式

  d o c k e r   b u i l d   − t    docker build -t   docker build t IMAGE_NAME .

再启动容器,本地打开浏览器 http://localhost:9000/ 看是否可以正常响应,来验证我们的自定义镜像是否可以运行成功:

# 启动容器:将容器的 9000 端口映射到主机的 9000 端口$ docker run -p 9000:9000 -d $IMAGE_NAME

验证通过后,最后上传镜像:

# 上传镜像

  d o c k e r   p u s h    docker push   docker push IMAGE_NAME

上传成功后,可以在阿里云镜像服务中看到我们的镜像。后面就可以使用它啦!

3.定义 template.yaml

创建一个 template.yaml文件如下:

ROSTemplateFormatVersion: ‘2015-09-01’

Transform: ‘Aliyun::Serverless-2018-04-03’

Resources:

CustomContainerRuntime: # 服务名称

Type: ‘Aliyun::Serverless::Service’

Properties:

Policies:

- Al

真题解析、进阶学习笔记、最新讲解视频、实战项目源码、学习路线大纲
详情关注公中号【编程进阶路】

iyunContainerRegistryReadOnlyAccess

InternetAccess: true

nodejs-express-http: # 函数名称

Type: ‘Aliyun::Serverless::Function’

Properties:

Description: ‘HTTP function powered by nodejs express’

Runtime: custom-container # 表示自定义容器

Timeout: 60

CAPort: 9000 # 注意!这里Custom Container Runtime使用的监听端口一定要和HTTP Server监听的端口保持一致,否则会出现错误

Handler: not-used

MemorySize: 1024

CodeUri: ./   # Root directory for the function or the Dockerfile path

CustomContainerConfig: # 容器镜像配置

# Sample image value: registry-vpc.cn-shenzhen.aliyuncs.com/fc-demo/nodejs-express:v0.1  使用同地域的VPC镜像地址加速

Image: ‘registry.cn-hangzhou.aliyuncs.com/my_serverless/nodejs:v16.1.0’

Command: ‘[ “node”]’

Args: ‘[“server.js”]’

Events:

http-trigger-test:

Type: HTTP

Properties:

AuthType: ANONYMOUS

Methods: [‘GET’, ‘POST’, ‘PUT’]

4.部署测试

# 使用命令部署到 FC

$ fun deploy -y

部署成功后,我们去 FC 平台上进行测试。

因为我们在 template.yaml 中配置的触发器是 http 触发器,所以我们点击“执行”按钮进行调试,发现正常运行,返回结果为 runtime is: Node V16.1.0,说明我们的自定义容器运行环境也成功实现了!

小结

Custom Runtime 为我们打破了 FaaS 平台对语言的限制;Custom Container Runtime 让开发者可以将应用代码和运行环境打包成容器镜像作为函数的交付物,优化开发者体验、提升开发和交付效率。

自定义(容器)运行时让我们开发者使用 Serverless 的自由度更高,通过它们可以让我们无需代码改造,一键迁移我们的 Web 应用。

参考资料


what-is-runtime (https://stackoverflow.com/questions/3900549/what-is-runtime)

为阿里云 serverless 打造 Deno 运行时 (https://zhuanlan.zhihu.com/p/137204273)

Custom Runtime 说明 (https://cloud.tencent.com/document/product/583/47274)

fun 工具 (https://help.aliyun.com/document_detail/64204.html)

函数计算支持容器镜像-加速应用 Serverless 进程 (https://developer.aliyun.com/article/772788)

这里分享一份由字节前端面试官整理的「2021大厂前端面试手册」,内容囊括Html、CSS、Javascript、Vue、HTTP、浏览器面试题、数据结构与算法。全部整理在下方文档中,共计111道

HTML

  • HTML5有哪些新特性?

  • Doctype作⽤? 严格模式与混杂模式如何区分?它们有何意义?

  • 如何实现浏览器内多个标签页之间的通信?

  • ⾏内元素有哪些?块级元素有哪些? 空(void)元素有那些?⾏内元 素和块级元素有什么区别?

  • 简述⼀下src与href的区别?

  • cookies,sessionStorage,localStorage 的区别?

  • HTML5 的离线储存的使用和原理?

  • 怎样处理 移动端 1px 被 渲染成 2px 问题?

  • iframe 的优缺点?

  • Canvas 和 SVG 图形的区别是什么?

JavaScript

  • 问:0.1 + 0.2 === 0.3 嘛?为什么?

  • JS 数据类型

  • 写代码:实现函数能够深度克隆基本类型

  • 事件流

  • 事件是如何实现的?

  • new 一个函数发生了什么

  • 什么是作用域?

  • JS 隐式转换,显示转换

  • 了解 this 嘛,bind,call,apply 具体指什么

  • 手写 bind、apply、call

  • setTimeout(fn, 0)多久才执行,Event Loop

  • 手写题:Promise 原理

  • 说一下原型链和原型链的继承吧

  • 数组能够调用的函数有那些?

  • PWA使用过吗?serviceWorker的使用原理是啥?

  • ES6 之前使用 prototype 实现继承

  • 箭头函数和普通函数有啥区别?箭头函数能当构造函数吗?

  • 事件循环机制 (Event Loop)

  • 29
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值