serverless / serverless-kubeless

This plugin enables support for Kubeless within the Serverless Framework.
Apache License 2.0
303 stars 81 forks source link

serverless-webpack support? #83

Closed rohit-ravikoti closed 5 years ago

rohit-ravikoti commented 7 years ago

Hi, Is there a way to get this working with serverless-webpack? It would be nice to be able to use babel.

Here's a sample repo of my try at it: https://github.com/rohit-ravikoti/serverless-kubeless-typescript-example

It doesn't work because the serverless-kubeless doesn't pickup the handler.js outputted by serverless-webpack.

EDIT: Added link to my attempt

andresmgot commented 7 years ago

Kubeless 0.2.4 has now support for using Zip files instead of single files. We should now be able to upload the whole .serverless/function.zip file if it is less than 1MB. Would that work for you?

rohit-ravikoti commented 7 years ago

I think so, how would I be able to make that work?

andresmgot commented 7 years ago

It will require changes in the serverless plugin but you can use for the time being the native kubeless client. Once you have a valid zip file (it is usually generated under the .serverless folder) you can deploy it executing:

kubeless function deploy hello --from-file .serverless/hello.zip --dependencies ./package.json --runtime nodejs6 --handler handler.hello --trigger-http

Let me know if the above works for you, we can start working on adding that feature afterwards.

rohit-ravikoti commented 7 years ago

Hmm, I just tried this, but the pod stays stuck in the Initializing state.

rohit-ravikoti commented 7 years ago

As an alternative, I could try to build with Babel and output to a build/ directory? And then change the serverless.yml function handlers to build/handler.capitalize.

I do get a strange error when I try that though. It says that the pod could not be found and retires a few times before crashing.

andresmgot commented 7 years ago

When it is stuck in Initializing state, what does kubectl describe pod <pod_name> output?

Also, how do you generate and deploy the build/ directory? Note that the handler doesn't support characters like /, the files should be in the root folder.

skunkwerk commented 6 years ago

My zip files for a Python app in my .serverless folder are > 10 MB. What do I do?

andresmgot commented 6 years ago

@rohit-ravikoti I have been working on adapting this repository to the Zip feature. I am afraid to say that even using a Zip file webpack is not supported since the format of the handler.js outputted is not recognized in the runtime container.

@skunkwerk You can use the exclude syntax to strip down the size of your Zip and just include code files.

The PR for supporting this file is https://github.com/serverless/serverless-kubeless/pull/102

Sorry both for the late response

remacr commented 5 years ago

@andresmgot, @rohit-ravikoti Any news on this request? I'm running Kubeless version: v1.0.2, with the following yml configuration.

service: my-api

plugins:
  - serverless-dotenv-plugin
  - serverless-webpack
  - serverless-kubeless
  - serverless-kubeless-offline

custom:
  stage: ${opt:stage, self:provider.stage}

  # Load our webpack config
  webpack:
    webpackConfig: ./webpack.config.js
    includeModules: true

provider:
  name: kubeless
  runtime: nodejs8
  stage: dev

functions:
  create-message:
    handler: src/services/v1/message/index.create
    events:
      - http:
          path: api/v1/message/create

The - serverless-kubeless-offline works great and I can hit http://localhost/api/v1/message/create with serverless offline start, but when I deploy with serverless deploy the serverless-kubeless plugin outputs the following error:

Serverless: Invoke webpack:package
Serverless: Packaging service...
Serverless: Unable to find any running pod for create-message. Retrying...
Serverless: Unable to find any running pod for create-message. Retrying...
Serverless: Unable to find any running pod for create-message. Retrying...
Serverless: Unable to find any running pod for create-message. Retrying...
Serverless: Giving up, unable to retrieve the status of the create-message deployment. 
/Users/raulmadrigal/repos/my-api/backend/node_modules/bluebird/js/release/async.js:61
        fn = function () { throw arg; };
                           ^

Error: Unable to retrieve the status of the create-message deployment
    at module.exports.logError (/Users/raulmadrigal/.nvm/versions/node/v8.10.0/lib/node_modules/serverless/lib/classes/Error.js:92:11)
    at process.on (/Users/raulmadrigal/.nvm/versions/node/v8.10.0/lib/node_modules/serverless/bin/serverless:21:3)
    at emitTwo (events.js:126:13)
    at process.emit (events.js:214:7)
    at methodName (/Users/raulmadrigal/repos/my-api/backend/node_modules/bluebird/js/release/debuggability.js:199:33)
    at activeFireEvent (/Users/raulmadrigal/repos/my-api/backend/node_modules/bluebird/js/release/debuggability.js:242:44)
    at fireRejectionEvent (/Users/raulmadrigal/repos/my-api/backend/node_modules/bluebird/js/release/debuggability.js:632:14)
    at Promise._notifyUnhandledRejection (/Users/raulmadrigal/repos/my-api/backend/node_modules/bluebird/js/release/debuggability.js:65:9)
    at Timeout._onTimeout (/Users/raulmadrigal/repos/my-api/backend/node_modules/bluebird/js/release/debuggability.js:44:14)
    at ontimeout (timers.js:482:11)
    at tryOnTimeout (timers.js:317:5)
    at Timer.listOnTimeout (timers.js:277:5)
andresmgot commented 5 years ago

Hi @raul-madrigal,

there is a bit of documentation that you can check in the docs site (look for "for webpack users"): https://kubeless.io/docs/runtimes/

Apart from that I don't have experience with serverless-kubeless-offline but apparently the controller is failing to process the function. What are the logs of the function controller? (You can find it in the kubeless namespace)

remacr commented 5 years ago

Hi @andresmgot, apologies if I didn't explain myself correct, my issue is not with serverless-kubeless-offline is with serverless-kubeless while running serverless deploy.

I followed the link you sent, and now my webpack.config.js looks like this:

const path = require('path')
const slsw = require('serverless-webpack')
const nodeExternals = require('webpack-node-externals')
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
  entry: {
    handlers: './handlers.js',
  },
  node: {
    __filename: true,
    __dirname: true,
  },
  target: 'node',
  mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
  // do not include dependencies in the bundle
  externals: [nodeExternals()],
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.js$/,
        include: __dirname,
        use: 'babel-loader',
        // do not transpile the depedencies
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    // do include the project's `package.json` in the bundle
    new CopyWebpackPlugin([
      {
        from: path.join(__dirname, 'package.json'),
        to: 'package.json',
      },
    ]),
  ],
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    modules: [path.resolve(__dirname, 'src'), 'node_modules', './'],
  },
}

I'm still able to use ES6 thanks to babel, but the same error is showing up. I have the kubeless namespace created with the nginx ingress setup in my local k8s. If I use the kubeless-cli I can deploy functions without issues but cannot make it work with this serverless plugin.

NAME            NAMESPACE       HANDLER                                 RUNTIME DEPENDENCIES            STATUS                        
create-message  default         src/services/v1/message/index.create    nodejs8 ajv: 6.10.0             MISSING: Check controller logs
                                                                                bcryptjs: 2.4.3                                       
                                                                                jsonwebtoken: 8.5.1                                   
                                                                                knex: 0.16.5                        

And the function logs print this:

$ kubeless function logs create-message
FATA[0000] No function pod is running: there is no pod ready

EDIT: I created a handlers.js at root level that imports the functions I have under src/services/v1/. And changed function definition to be:

create-message:
  handler: handlers.createMessage
  events:
    - http:
        path: api/v1/message/create

And now the deploy runs good:

NAME            NAMESPACE       HANDLER                 RUNTIME DEPENDENCIES            STATUS   
create-message  default         handlers.createMessage  nodejs8 ajv: 6.10.0             1/1 READY
                                                                bcryptjs: 2.4.3                  
                                                                jsonwebtoken: 8.5.1              
                                                                knex: 0.16.5                     

The issue I have now is that I cannot hit the function.

$ kubectl get ing -A
NAMESPACE   NAME                HOSTS              ADDRESS     PORTS   AGE
default     udr-residents-api   localhost.nip.io   localhost   80      26m

Is there anything else I'm missing?

andresmgot commented 5 years ago

To discover what can be the error you can check the controller logs:

kubectl logs -n kubeless -l kubeless=controller -c kubeless-function-controller    

Another option, if using the kubeless cli works for the same function, you can create both and compare the resulting YAML of both:

kubectl get function -o yaml <func-name>

That should tell you what's the problem.

remacr commented 5 years ago

@andresmgot should serverless-kubeless be creating the kubeless http triggers?

If I run kubeless trigger http list nothing comes out, not even by setting the -n flag.

I tried this example https://github.com/serverless/serverless-kubeless/tree/master/examples/todo-app/backend as well, and I'm ending in the same spot, the functions cannot be reached and there are no http triggers.

andresmgot commented 5 years ago

Right now it doesn't. It directly creates the Ingress object. There is an open issue for that but we haven't had the time to work on that:

https://github.com/serverless/serverless-kubeless/issues/114

remacr commented 5 years ago

@andresmgot Thanks for that last comment, it pointed me in the direction of the issue I was having. By setting the hostname inside the provider, the ingress object is taking it instead of the default xx.nip.io and now I can reach my functions.

I guess this issue shouldn't be opened anymore, I can confirm that I was able to run the serverless-webpack with serverless-kubeless and deploy the functions to the k8s cluster.

andresmgot commented 5 years ago

I am glad to hear that you finally figured it out! Sorry for all the back and forth, please reopen this issue if you find something else.