chetanmeh opened a new pull request #4412: Execute OpenWhisk action via AWS 
Lambda
URL: https://github.com/apache/incubator-openwhisk/pull/4412
 
 
   This is a proof of concept to execute OpenWhisk actions via AWS Lambda. 
   
   Sometime back AWS Lambda introduced support for [layers][1] and [custom 
runtimes][2]. @michaelmarth suggested that we can leverage that to deploy 
OpenWhisk runtimes on top of Lambda and thus do the actual execution via 
Lambda. At this point this POC enables support for executing NodeJS actions
   
   ## Objective
   
   Some of the key aspects here are
   
   1. Supports most of OpenWhisk features
   2. Developers use std OpenWhisk tooling to create functions
   3. Invoker can delegate execution to Lambda based on some policy
   4. Execution via Lambda is an implementation detail not surfaced to end 
developers
   
   Some potential benefits of this are 
   
   1. Tap into cloud provider platforms for scaling out
   2. Bring compute near to content
   
   ## Design
   
   ### Custom Runtime
   
   A custom runtime is implemented based on [LambCI][4] project. The changes 
done can be seen [here][5]. It basically enabled invoking the runner.js 
(similar to one present in OpenWhisk nodejs runtime) from the bootstrap.js 
which in turn is the entrypoint.
   
   #### Lambda - Runtime Protocol
   
   Lambda uses a [pull based protocol][6]. All calls are made to an endpoint 
passed via env `AWS_LAMBDA_RUNTIME_API`
   
   ##### Init
   
   1. As part of startup Lambda system would execute `bootstrap`
   2. `bootstrap` would load the function code. If it get any error then it 
makes a POST call to `/runtime/init/error`
   
   ##### Execute
   
   Once initialized the runtime would then constantly poll for invocations 
   
   1. Make call to `/runtime/invocation/next`
   2. Process the invocation json payload
       - If success submit the response to 
`/runtime/invocation/<AwsRequestId>/response`
       - If error submit the error to 
`/runtime/invocation/<AwsRequestId>/error`        
   
   This polling would continue until the process gets terminated
   
   #### Lambda OpenWhisk bridge
   
   Compared to Lambda OpenWhisk has a push based protocol described [here][7] 
where runtime would
   
   1. Start a server on port 8080
   2. Invoker would perform `/init`
   3. Invoker would execute by invoking the `/run` endpoint
   
   To create a bridge the [custom runtime][5] for now mimics the flow which 
happens within `/run` call by invoking `runner.js` and takes care of init as 
part of Lambda runtime init lifecycle. Due to this mode the Lambda functions 
need to be created as part of creation itself and runtime cannot be seeded with 
function code at time of execution. (See Lambda Builder)
   
   #### Lambda OpenWhisk Generic Bridge :question:
   
   Going forward we may implement some of action loop variant which implements 
the bridge part and instead of having a server interface just implements the 
poll loop and translate the call to OpenWhisk runtimes
   
   ### Lambda Builder
   
   Given the way Lambda functions work we need to create Lambda function at 
time of creation. To enable this a new `LambdaBuilder` service is implemented 
which (for now) listens to changes in `whisks` collection in CosmosDB via 
[changefeed][8] and upon any change it create/update/delete a Lambda function 
based on Action code.
   
   Currently this service only does this transformation for those runtimes 
which are supported (like nodejs)
   
   ### Lambda Container Factory
   
   For actual execution a `LambdaContainerFactory` is implemented. Upon 
receiving any activation it checks if the backing action can be a Lambda then 
it routes the call to Lambda system otherwise it delegates the activation 
processing to system default implementation (like Docker/Mesos/K8s)
   
   ## Usage
   
   To try out the POC following steps would be required
   
   ### 1. Deploy the custom runtime layer
   
   You need to have [aws cli][11] installed with required credentials 
configured.
   
   1. Checkout the [branch][9]
   2. Execute `make build` via [Makefile][10]. This would generate a 
`layer.zip` in that directory
   3. Publish the layer via `make publish`
   
   You should then get a ARN for the layer object which would be of format like 
`arn:aws:lambda:us-east-1:xxx:layer:customnodejs10:1`. Here `customnodejs10` is 
the layer name
   
   ### 2. Deploy the Lambda Builder
   
   For this you need a CosmosDB based deployed. The service need to have access 
to manage Lambda functions
   
   ### 3. Configure the container factory
   
   ```
   whisk {
     spi {
       ContainerFactoryProvider = 
org.apache.openwhisk.core.containerpool.lambda.LambdaContainerFactoryProvider
     }
     aws {
       lambda {
         secondary-factory-provider = 
org.apache.openwhisk.core.mesos.MesosContainerFactoryProvider
       }
     }
     aws {
       lambda {
         layer-mappings {
           "nodejs:10" : "arn:aws:lambda:us-east-1:xxx:layer:customnodejs10:1"
         }
         account-id = "xxx"
         common-role-name = "arn:aws:iam::xxx:role/owl-generic-role"
       }
     }
   }
   ```
   
   Here we define
   
   1. Mapping between OpenWhisk `kind` and Lambda custom layer ARN
   2. An AWS Role which allows the Lambda function to write to CloudWatch logs
   
   ## Future
   
   For now this is meant to be a POC to see how far one can go with such a 
model. In future some parts to be implemented
   
   0. Complete the lots of TODO left in current imple
   1. Integrate with CloudWatch to enable pulling the logs
   2. Generic action loop like implementation to support any supported 
OpenWhisk runtime
   3. Optimize the processing flow - Say by doing invocation from Controller 
itself
   
   [1]: https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html
   [2]: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html
   [3]: 
https://aws.amazon.com/blogs/aws/new-for-aws-lambda-use-any-programming-language-and-share-common-components/
   [4]: https://github.com/lambci/node-custom-lambda
   [5]: 
https://github.com/chetanmeh/node-custom-lambda/compare/master...chetanmeh:openwhisk
   [6]: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html
   [7]: 
https://github.com/apache/incubator-openwhisk/blob/master/docs/actions-new.md#action-interface
   [8]: https://docs.microsoft.com/en-us/azure/cosmos-db/change-feed
   [9]: https://github.com/chetanmeh/node-custom-lambda/tree/openwhisk
   [10]: 
https://github.com/chetanmeh/node-custom-lambda/blob/openwhisk/v10.x/Makefile
   [11]: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to