This article has participated in the good Article call order activity, click to view:Back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!

Serverless Custom (Container) Runtime Serverless Custom (Container) Runtime Serverless Custom (Container) Runtime Serverless Custom (Container) Runtime

background

We know Serverless can be understood as Serverless = FaaS + BaaS. In Serverless applications, developers implement server-side business logic code in the form of functions, known as FaaS (functions as services). (Serverless related articles can see the team combined with Ali Cloud FC to talk about my understanding of FaaS)

For FaaS platforms from cloud vendors, support for multiple programming languages and versions of the standard runtime environment is limited. Therefore, in order to meet the needs of users for more personalized development language and version of the function implementation, they provide the Custom Runtime service, you can customize the Runtime environment, support users in any programming language written functions.

Taking Aliyun function computing FC as an example, here is a list of the development languages it supports:

Support language Runtime environment
Node.js Node.js 6.10 (Runtime =nodejs6),

Node.js 8.9.0 (Runtime =nodejs8),

Node.js 10.15.3 (Runtime =nodejs10)

Node.js 12.16.1 (Runtime =nodejs12)
Python Python 2.7 (Runtime = python2.7)

Python 3.6 (Runtime = python3)
PHP PHP 7.2.7 (Runtime=php7.2)
Java Java OpenJDK 1.8.0 (Runtime =java8)
C# .net Core 2.1 (runtime= dotNetCore 2.1)
Go Go Custom Runtime
Ruby Ruby Custom Runtime
PowerShell PowerShell Custom Runtime
TypeScript TypeScript Custom Runtime
F# F# Custom Runtime
C++ C++ Custom Runtime
Lua Lua Custom Runtime
Dart Dart Custom Runtime
Other languages Custom Runtime

As can be seen, for us front-end engineers, if we want to use Aliyun FC platform, we cannot use Node.js and TypeScript as we like. Because Node.js only supports four versions of the table, TypeScript, the FC platform itself, does not support any of them. So to use other versions of Node.js and TypeScript, you need to customize the runtime.

What is Custom Runtime?

concept

Runtime refers to any library, code package, framework, or platform on which the function code depends when it is run. Custom Runtime is an environment where functions are completely customized by the user.

The FaaS platform implements custom function runtimes by opening them up, allowing functions to be written in any version of any development language as required.

role

Custom Runtime can be used to implement the following two things:

  • Customize the execution environment in your own languages (e.g., Go, Lua, Ruby) and smaller versions of various languages (e.g., Python 3.7, Node.js 14) to create your own runtime environment.
  • One-click migration of an existing Web application or Web project based on traditional development to a functional computing platform without any modifications.

To implement the Custom Runtime

This article will take Ali cloud FC as an example to implement a Custom Runtime. Other platforms such as Tencent Cloud SCF, the principle and process are roughly the same.

The working principle of

Custom Runtime is essentially an HTTP Server. The code contains a bootstrap file. After that, the HTTP Server takes over all requests from the function computing platform, including event calls and HTTP function calls.

As Typescript becomes more widely used in Node, I’m going to implement a Typescript runtime that can run TS code.

steps

The preparatory work

In order to play with Serverless applications faster and better, you need to install a Fun tool of Aliyun, which is used to support the deployment of Serverless applications. It can help us easily manage function computing, API gateway, log service and other resources. It uses a resource configuration file (template.yml) to help us develop, build, and deploy.

The installation and configuration process is as follows:

(1) Installation:

$NPM install @alicloud/fun -g // Run fun --version to check whether the installation is successful. $fun --version 3.6.21Copy the code

(2) After the installation, run the fun config command to configure the Account information (configuration document), and configure the Account ID, AccessKey ID, AccessKey Secret, and Default Region Name as prompted.

Once the configuration is complete, create a TypeScript project locally called custom-Run-time TypeScript and install the dependencies.

npm i typescript ts-node @types/node
Copy the code

Next, start the Custom Runtime development process and build your own Custom Runtime environment step by step.

1. Set up an HTTP Server with a listening port

  • It is important to note that this service must be listened on0.0.0.0: CAPortor*:CAPortPort, default is 9000. If you are using127.0.0.1: CAPortPort, causing the request to time out

Write an HTTP Server file server. TS as follows:

Note: Before developing the specific logic of the function, it is common to check whether the function being developed is an event function or an HTTP function

import * as http from 'http';

// Create an HTTP Server
const server = http.createServer(function (req: http.IncomingMessage, res: http.ServerResponse) :void {
  var rid = req.headers["x-fc-request-id"];
  console.log(`FC Invoke Start RequestId: ${rid}`);
  
  var rawData = "";
  req.on('data'.function (chunk) {
    rawData += chunk;
  });
  
  req.on('end'.function () {
    // Handle the business logic...
    console.log(rawData);
    
    res.writeHead(200);
    res.end(rawData);
    console.log(`FC Invoke End RequestId: ${rid}`);
  });
});

server.timeout = 0; // never timeout
server.keepAliveTimeout = 0; // kee palive, never timeout

// Start the HTTP service and listen on port 0.0.0.0:9000
server.listen(9000.'0.0.0.0'.function () {
  console.log('FunctionCompute typescript runtime inited.');
});


Copy the code

After writing, you can test whether the service started successfully locally by running the above code using the TS-node command installed in the project:

# Start the HTTP service

$ ./node_modules/.bin/ts-node server.ts
Copy the code

Use the curl command on another terminal to test:

$curl 0.0.0.0: 9000-x post-d"hello world" -H "x-fc-request-id:123" 

hello world
Copy the code

If the service is started properly, it can process the business logic after receiving the HTTP request, and then return the processing results to the FaaS platform in the form of AN HTTP response.

2. Create an executable file bootstrap to start the target Server

The bootstrap file is called to start the Custom HTTP Server by default. The HTTP Server then takes over all requests for the function computation system.

  • Bootstrap is the runtime entry bootstrap file that tells FaaS how to start your custom runtime. When the Custom Runtime function is loaded, the bootstrap file is retrieved and the program is executed to start the Custom Runtime Runtime.
  • Bootstrap must have 777 or 755 executable rights
  • If it’s a shell script, be sure to add it#! /bin/bash

Create the bootstrap file as follows:

#! /bin/bash
./node_modules/.bin/ts-node server.ts
Copy the code

3. Write the resource configuration file template.yaml

Write a resource configuration file template-yaml in the current directory to deploy to function calculations:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  custom-runtime: # Service name
    Type: 'Aliyun::Serverless::Service' 
    Properties:
      Description: 'helloworld'
    custom-runtime-ts: # Function name
      Type: 'Aliyun::Serverless::Function' 
      Properties:
        Handler: index.handler # Handler is meaningless at this point. Fill in any string that satisfies the Handler character set constraint of the function, such as index. Handler
        Runtime: custom # Custom stands for custom runtime
        MemorySize: 512
        CodeUri: '/'
Copy the code

4. Deploy, invoke tests, complete

(1) Deploy all resources of our custom runtime and business logic code to AliYun using the fun deploy-y command.

(2) Use the command to call the deployment function and verify

$ fun invoke -e "hello,my custom runtime"  
Copy the code

When the output is successful, our Custom Runtime is finished! It’s ready to run the TS code that we wrote.

Implement the Custom Container Runtime

Custom Runtime can be used to solve problems with TS Runtime. However, the same method cannot be used to solve problems with some versions of Node that are not supported. Because Node is installed globally, it depends on the system environment.

The FC platform has come up with a solution for this type of problem by giving us the ability to customize the Container Runtime. FaaS platform has this capability because its underlying implementation principle is Docker container. Therefore, it packages our application code and running environment into Docker image by using container technology to maintain environment consistency. Implement a build, run it everywhere.

The working principle of

Custom Container Runtime works the same as Custom Container Runtime:

  • The function computation system acts as a service for this function, obtains a temporary user name and password, and pulls the image before initializing the execution environment instance.
  • After the Command, parameter Args, and port CAPort (9000 by default) are used to start the customized HTTP Server.
  • The HTTP Server then takes over all requests from the function computation system, both from event function calls and HTTP function calls.

Let’s customize a Node V16.1.0 container runtime environment.

steps

1. Customize the HTTP Server

This step is the same as with Custom Runtime. Use Node.js Express to create a Custom Http server.

/ / server. Js file
'use strict';

const express = require('express');

// Constants
const PORT = 9000;
const HOST = '0.0.0.0';

// HTTP function call
const app = express();
app.get('/ *'.(req, res) = > {
  res.send(`Hello FunctionCompute, http function, runtime is : Node ${process.version}\n`);
});

// Event function call
app.post('/invoke'.(req, res) = > {
  res.send(`Hello FunctionCompute, event function,runtime is : Node ${process.version}\n`);
});

// Start the HTTP service and listen on port 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

Copy the code

Start the service and test it locally:

# Start the HTTP service
$ node server.js
Copy the code
Open a new terminal and test it with the curl command$curl http://0.0.0.0:9000 Hello FunctionCompute, HTTP GET, this Runtime is: Node v11.5.0# This is my local Node version, which will output V16.1.0 in the custom container
Copy the code

The verification is successful.

2. Create an image and upload it

Again, two things need to be done first:

  • 1) Install and start Docker

  • 2) Use Aliyun container image service to create namespace and image warehouse to store our custom images

Next, we first write the Dockerfile, then build the image containing our Node specified version runtime environment and application code, and finally upload it to our own image repository.

(Check out this article on how to Docker a Node.js Web application.)

(1) Write Dockerfile:

# Build our own image based on base mirror node:16.1.0- Alpine3.11
FROM node:16.1.0-alpine3.11

Set the working directory of the container
WORKDIR /usr/src/app

# Copy both package.json and package-lock-json to the working directory
COPY package*.json ./

# Install dependencies
RUN npm install

Copy all files from the current directory to the container working directory
COPY.

Expose container port 8080
EXPOSE 8080

# Start the application in the container
ENTRYPOINT [ "node"."server.js" ]

Copy the code

(2) Install and start Docker, log in aliyun image service, build and upload:

# login
$ sudo docker login --username=xxx registry.cn-hangzhou.aliyuncs.com
Copy the code

After successful login, first build the Docker image:

# Specify ACR image address: where my_serverless is your own container namespace; Nodejs for your own image repository name; V16.1.0 indicates the version number of the mirror
$ export IMAGE_NAME="registry.cnhangzhou.aliyuncs.com/my_serverless/nodejs:v16.1.0"
Copy the code

# Build image
# -t tag the image with a name, usually name:tag or name
$ docker build -t $IMAGE_NAME .
Copy the code

To verify that our custom image is running successfully, start the container and open the browser http://localhost:9000/ locally to see if the response is normal:

Start the container: map the container's 9000 port to the host's 9000 port
$ docker run -p 9000:9000 -d $IMAGE_NAME
Copy the code

After the verification is passed, finally upload the image:

# Upload image
$ docker push $IMAGE_NAME  
Copy the code

After the upload is successful, you can see our image in the Ali Cloud image service. You can use it later!

3. Define the template. Yaml

Create a template. Yaml file as follows:

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  CustomContainerRuntime: # Service name
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Policies:
        - AliyunContainerRegistryReadOnlyAccess
      InternetAccess: true
    nodejs-express-http: # Function name
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Description: 'HTTP function powered by nodejs express'
        Runtime: custom-container # represents a custom container
        Timeout: 60
        CAPort: 9000 # note! The listening port used by the Custom Container Runtime must be the same as that used by the HTTP Server. Otherwise, an error may occur
        Handler: not-used
        MemorySize: 1024
        CodeUri: . /   # Root directory for the function or the Dockerfile path
        CustomContainerConfig: Container image configuration
          # Sample image value: registry-vpc.cn-shenzhen.aliyuncs.com/fc-demo/nodejs-express:v0.1 Use VPC image addresses in the same region to speed up
          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']
Copy the code
4. Deploy the test
Deploy to FC using the command
$ fun deploy -y
Copy the code

After successful deployment, we went to the FC platform for testing.

Because the trigger we configured in template-yaml is an HTTP trigger, we clicked on the “Execute” button to debug it. We found that it worked, and the result was Runtime is: Node V16.1.0, indicating that our custom container runtime was implemented successfully!

summary

Custom Runtime breaks the language restrictions of the FaaS platform for us; The Custom Container Runtime enables developers to package application code and Runtime environments into Container images as function deliverables, optimizing the developer experience and improving development and delivery efficiency.

Custom (container) runtimes give us developers more freedom with Serverless, allowing us to migrate our Web applications with one click without code changes.

The resources

what-is-runtime

Build Deno runtime for Aliyun Serverless

The Custom Runtime instructions

Fun tool

Function computing supports container mirroring – accelerated application Serverless processes

Custom Runtime – Breaks the cloud function language restrictions

Recommended reading

Vite features and partial source parsing

How do I use Git at work

15 minutes to Immutable

Open source works

  • Politics in front of tabloids

Open source address www.zoo.team/openweekly/ (there is a wechat group on the homepage of the official website of the tabloid)

, recruiting

ZooTeam (ZooTeam), a young and creative team, belongs to the product RESEARCH and development department of ZooTeam, based in picturesque Hangzhou. The team now has more than 40 front end partners, the average age of 27 years old, nearly 30% are full stack engineers, no problem youth storm team. The membership consists of “old” soldiers from Alibaba and netease, as well as fresh graduates from Zhejiang University, University of Science and Technology of China, Hangzhou Electric And other universities. In addition to the daily business connection, the team also carried out technical exploration and actual practice in the direction of material system, engineering platform, building platform, performance experience, cloud application, data analysis and visualization, promoted and implemented a series of internal technical products, and continued to explore the new boundary of the front-end technology system.

If you want to change the things you’ve been doing, you want to start doing things. If you want to change, you’ve been told you need to think more, but you can’t change; If you want to change, you have the power to achieve that result, but you are not needed; If you want to change what you want to accomplish, you need a team to support you, but there is no place for you to bring people; If you want a change of pace, it’s “3 years of experience in 5 years”; If you want to change the original savvy is good, but there is always a layer of fuzzy window paper… If you believe in the power of belief, that ordinary people can achieve extraordinary things, that you can meet a better version of yourself. If you want to get involved in the growth of a front end team with a deep understanding of the business, a sound technology system, technology that creates value, and spillover impact as the business takes off, I think we should talk about it. Any time, waiting for you to write something, to [email protected]