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