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/07/12 13:38:59 UTC

[GitHub] [incubator-openwhisk] chetanmeh opened a new pull request #4556: Execute OpenWhisk action via Ignite and Firecracker VM

chetanmeh opened a new pull request #4556: Execute OpenWhisk action via Ignite and Firecracker VM
URL: https://github.com/apache/incubator-openwhisk/pull/4556
 
 
   This is a proof of concept to execute OpenWhisk actions via [Weave Ignite][1] which uses [Firecracker MicroVMs][2]
   
   Recently [Weave works announced Ignite][3] project which supports running compatible docker images as [Firecracker MicroVMs][4]. Such an execution can provide better security compared to simple container based execution. 
   
   ## Objective
   
   Some of the key aspects here are
   
   1. Rebuild OpenWhisk runtime as Ignote compatible docker image
   2. Execute action via vm build from those images
   
   ## Usage
   
   ### 1. Install Ignite
   
   Follow the [Ignite installation steps][6] and ensure that required [dependencies][7] are met. OpenWhisk would check for `ignite` cli  at `/usr/local/bin/ignite`
   
   ### 2. Build a Ignite compatible docker image for nodejs. 
   
   Currently a docker file is provided for nodejs 12 [here][5]
   
   ```bash
   $ cd tools/ignite/nodejs
   $ docker build -t whisk/ignite-nodejs-v12:latest  .
   ```
   
   ### 3. Build the standalone OpenWhisk
   
   ```bash
   $ ./gradlew :core:standalone:build
   ```
   
   ### 4. Start the server
   
   Start the server passing a custom runtime manifest which refers to new nodejs docker image build in previous steps
   
   ```
   $ sudo java -Dwhisk.spi.ContainerFactoryProvider=org.apache.openwhisk.core.containerpool.ignite.IgniteContainerFactoryProvider \
         -jar bin/openwhisk-standalone.jar \
         -m tools/ignite/ignite-runtimes.json 
   ```
   
   Note that this is run with `sudo` as `ignite` needs root access to run. Once started it would launch 2 pre warm containers (vms!)
   
   In startup logs you can see the vm being created
   
   ```
   [2019-07-12T18:12:07.811Z] [INFO] [#tid_sid_unknown] [IgniteClient] Detected ignite client version Ignite version: version.Info{Major:"0", Minor:"4", GitVersion:"v0.4.0", GitCommit:"e0e7e8c50cd3c6532486625393dff4d415081829", GitTreeState:"clean", BuildDate:"2019-07-10T12:30:11Z", GoVersion:"go1.12.1", Compiler:"gc", Platform:"linux/amd64"}
   Firecracker version: v0.17.0
   [2019-07-12T18:12:08.080Z] [INFO] [#tid_sid_invokerWarmup] [IgniteClient] running /usr/local/bin/ignite -q image import whisk/ignite-nodejs-v12:latest (timeout: 10 minutes) [marker:invoker_ignite.image_start:1384]
   [2019-07-12T18:12:08.101Z] [INFO] [#tid_sid_invokerWarmup] [IgniteClient] running /usr/local/bin/ignite -q run whisk/ignite-nodejs-v12:latest --cpus 1 --memory 256m --size 1GB --name wsk0_1_prewarm_nodejs12 (timeout: 5 minutes) [marker:invoker_ignite.run_start:1406]
   ```
   
   Checking running vms
   
   ```
   # ignite vm ps 
   VM ID                   IMAGE                           KERNEL                                  CREATED SIZE            CPUS    MEMORY          STATE   IPS             PORTS       NAME
   296c4f2fd75bf834        whisk/ignite-nodejs-v12:latest  weaveworks/ignite-kernel:4.19.47        17s ago 1024.0 MB       1       256.0 MB        Running 172.17.0.10        wsk0_1_prewarm_nodejs12
   e9c77eb3f95e7d7c        whisk/ignite-nodejs-v12:latest  weaveworks/ignite-kernel:4.19.47        17s ago 1024.0 MB       1       256.0 MB        Running 172.17.0.11        wsk0_2_prewarm_nodejs12
   ```
   
   There would also be 2 "proxy" docker container for these 2 vm
   
   ```
   # docker ps
   CONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS              PORTS                                                                                                 NAMES
   f94d7c15ed90        weaveworks/ignite:v0.4.0              "/usr/local/bin/igni…"   28 seconds ago      Up 24 seconds                                                                                                             ignite-e9c77eb3f95e7d7c
   be939a1e2d5a        weaveworks/ignite:v0.4.0              "/usr/local/bin/igni…"   29 seconds ago      Up 25 seconds    
   ```
   
   Now you can invoke js action
   
   ```json
   {
       "namespace": "guest",
       "name": "hello",
       "version": "0.0.1",
       "subject": "guest",
       "activationId": "1b86c507e4df4b6286c507e4df3b62ea",
       "start": 1562937307810,
       "end": 1562937323341,
       "duration": 15531,
       "statusCode": 0,
       "response": {
           "status": "success",
           "statusCode": 0,
           "success": true,
           "result": {
               "LANG": "en_US.UTF-8",
               "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
               "__OW_ACTION_NAME": "/guest/hello",
               "__OW_ACTIVATION_ID": "1b86c507e4df4b6286c507e4df3b62ea",
               "__OW_DEADLINE": "1562937383336",
               "__OW_NAMESPACE": "guest",
               "payload": "hello, world"
           }
       },
       "logs": [],
       "annotations": [
           {
               "key": "path",
               "value": "guest/hello"
           },
           {
               "key": "waitTime",
               "value": 100
           },
           {
               "key": "kind",
               "value": "nodejs:12"
           },
           {
               "key": "timeout",
               "value": false
           },
           {
               "key": "limits",
               "value": {
                   "concurrency": 1,
                   "logs": 10,
                   "memory": 256,
                   "timeout": 60000
               }
           },
           {
               "key": "initTime",
               "value": 15526
           }
       ],
       "publish": false
   }
   ```
   
   ## Design
   
   This PR adds a new `IgniteContainerFactory` which internally launches the vm and route calls to it. See [Getting started with Ignite][8] to get a quick overview of how ignite works
   
   Upon first launch it would
   
   1. Import the image via `ignite image import whisk/ignite-nodejs-v12:latest`. This would implicitly pull the image if not present
   2. Create and run the vm `ignite run whisk/ignite-nodejs-v12:latest --cpus 1 --memory 256m --size 1GB --name wsk0_1_prewarm_nodejs12`
   3. Connect to the 8080 port of launched vm for actual execution
   
   `IgniteContainer` would also figure out the matching docker container running for given vm and use that to make calls as being done with standard Docker implementation. 
   
   ### Docker Image
   
   For any docker image to be usable with `ignite` it must have init system present. For this it provides some [base images][10]. This PR uses there centos image to build a custom nodejs action runtime image
   
   ```
   FROM openwhisk/action-nodejs-v12:1.14.0-incubating AS ownode
   
   FROM weaveworks/ignite-centos
   
   RUN curl -sL https://rpm.nodesource.com/setup_10.x | bash -
   RUN sudo yum -y install nodejs
   
   COPY --from=ownode /nodejsAction /nodejsAction
   COPY --from=ownode /node_modules /node_modules
   COPY ./action.service /etc/systemd/system/
   
   RUN chmod 664 /etc/systemd/system/action.service \
       && systemctl enable action.service
   ```
   
   ### Service Startup
   
   Despite `ignite` use of OCI Image the end result is a vm being launched. So for our action runtime to be launches this docker image also adds a [systemd][10] service
   
   ```
   [Unit]
   Description=OpenWhisk Nodejs action server
   Wants=network-online.target
   After=network-online.target
   
   [Service]
   WorkingDirectory=/nodejsAction
   ExecStart=/usr/bin/node --expose-gc app.js
   
   [Install]
   WantedBy=multi-user.target
   ```
   
   So upon startup of vm the node server would be launched and it would bind to 8080 port.
   
   ### Logging
   
   Currently `logs` support does not work. For that we need to figure out how to route nodejs logs to vm logs. These logs are then routed to docker logging sub system so we can then fetch it via standard docker log access. 
   
   ### Things to note
   
   Currently the cold start takes long time as for some reason even if vm launches quickly the nodejs server does not respond for some time post start. This aspect would need to be investigated
   
   
   [1]: https://github.com/weaveworks/ignite
   [2]: https://firecracker-microvm.github.io/
   [3]: https://www.weave.works/blog/fire-up-your-vms-with-weave-ignite
   [4]: https://aws.amazon.com/about-aws/whats-new/2018/11/firecracker-lightweight-virtualization-for-serverless-computing/
   [5]: https://github.com/chetanmeh/incubator-openwhisk/tree/ignite/tools/ignite/nodejs
   [6]: https://github.com/weaveworks/ignite/blob/master/docs/installation.md
   [7]: https://github.com/weaveworks/ignite/blob/master/docs/dependencies.md
   [8]: https://github.com/weaveworks/ignite/blob/master/docs/usage.md
   [9]: https://github.com/weaveworks/ignite#base-images
   [10]: https://www.freedesktop.org/software/systemd/man/systemd.service.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