You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2019/03/29 05:53:25 UTC

[GitHub] [incubator-openwhisk] chetanmeh opened a new pull request #4412: Execute OpenWhisk action via AWS Lambda

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:
users@infra.apache.org


With regards,
Apache Git Services