serverless / serverless-kubeless

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

unable to call or update function #92

Closed skunkwerk closed 6 years ago

skunkwerk commented 6 years ago

I deployed a Python function to a k8s cluster, but cannot call it directly, or update it after making changes.

However, I can call the function just fine from kubeless directly: $ kubeless function call hello --data '{"echo": "echo echo"}' {"body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {\"echo\": \"echo echo\"}}", "statusCode": 200}

Calling from serverless, however, fails:

$ serverless invoke --function hello --data '{"echo": "echo echo"}' ... Serverless: Calling function: hello... Error -------------------------------------------------- Service Unavailable

If I try to re-deploy after a change to the function:

$ serverless deploy function -f hello Serverless: Redeploying hello... Error -------------------------------------------------- Found errors while deploying the given functions: Error: Unable to update the function hello. Received: Code: 422 Message: functions.k8s.io "hello" is invalid: metadata.resourceVersion: Invalid value: 0x0: must be specified for an update

ryuheechul commented 6 years ago

I'm having the same issue, too and I wonder if it's because of that I specified the namespace other than default. In that case, I would like to know how to invoke a function existing in other namespaces.

Currently, I'm just relying on kubeless to invoke the functions which is not ideal.

ngtuna commented 6 years ago

@ryuheechul AFAIK we provided a field in the function manifest to specify the namespace that function will be deployed into. Please look at https://github.com/serverless/serverless-kubeless/blob/master/invoke/kubelessInvoke.js#L66. Can you try again with configuring that field ?

ngtuna commented 6 years ago

For deploy: https://github.com/serverless/serverless-kubeless/blob/master/deploy/kubelessDeploy.js#L133

ngtuna commented 6 years ago

@skunkwerk Have you got the same namespace problem with @ryuheechul ?

ryuheechul commented 6 years ago

@ngtuna I tried many times with different method and it didn't work. After deployed by serverless via sls deploy, I was able to list and call via kubeless with --namespace flags. But I couldn't do that with serverless deploy list [functions] nor serverless invoke

Maybe I didn't provide enough information to the CLI? (I tried putting --namespace flags though)

Tested with kubectl: 1.8.5 kubeless: 0.3.3 serverless: 1.25.0

andresmgot commented 6 years ago

@ryuheechul @skunkwerk I was unable to reproduce the issue even using a different namespace. This plugin is just using the Kubernetes proxy endpoint to access the service. What is the output of the logs? You can retrieve them executing serverless logs -f hello

Also, does it work if you use just curl? You can try it executing:

kubectl proxy

And in a different terminal:

curl 127.0.0.1:8001/api/v1/proxy/namespaces/myns/services/hello:function-port/

(substituting myns with the name of the namespace and hello with the name of the function)

Regarding the problem to update (re-deploy) a function. Can you post the content of the serverless.yaml so we can try to reproduce it?

ryuheechul commented 6 years ago

@andresmgot Thanks for looking in to it. seerverless logs -f funtion-name worked and so did curl. But still serverless invoke emits Service Unavailable and serverless deploy list showing nothing

andresmgot commented 6 years ago

@ryuheechul could you provide us the serverless.yaml that you are trying to use along with the function code (if possible) and any data about the Kubernetes environment you are using to try to reproduce your issue?

Also note that serverless deploy list is not implemented yet in the plugin, that's why it is not showing anything to you. If you want to list functions you can use serverless info.

ryuheechul commented 6 years ago

@andresmgot Sure

# Welcome to Serverless!
#
# For full config options, check the kubeless plugin docs:
#    https://github.com/serverless/serverless-kubeless
#
# For documentation on kubeless itself:
#    http://kubeless.io

# Update the service name below with your own service name
service: service-name

# Please ensure the serverless-kubeless provider plugin is installed globally.
# $ npm install -g serverless-kubeless
#
# ...before installing project dependencies to register this provider.
# $ npm install

provider:
  name: kubeless
  namespace: ${env:K8S_NAMESPACE, 'kubeless'}
  runtime: nodejs8

plugins:
  - serverless-kubeless

functions:
  service-name:
    handler: handler.handle
    events:
    - http:
        path: /
function handle(req, res) {
  const { param1, param2 } = req.body

  someLogic({ param1, param2 })
    .then(() => res.status(200).end('OK'))
    .catch(err => {
      console.warn(err)
      res.status(500).end('Error')
    })
}

module.exports = { handle }

Keep that in mind that I changed function names in yaml file and very simplified js code

Environment:

andresmgot commented 6 years ago

The function yaml and code seems correct. You said that you were able to call the function using kubeless call but not with serverless. How are you calling both commands? Both methods use the same approach so I am thinking that the call with serverless is somehow malformed.

I have tested the following with success:

service: capitalize-function

provider:
  name: kubeless
  namespace: ${env:K8S_NAMESPACE, 'kubeless'}
  runtime: nodejs8

plugins:
  - serverless-kubeless

functions:
  capitalize-function:
    handler: handler.capitalize
    events:
    - http:
        path: /
'use strict';

const _ = require('lodash');

module.exports = {
  capitalize(req, res) {
    const {hello} = req.body
    res.end(_.capitalize(hello));
  },
};
▶ sls deploy -v
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Deploying function capitalize-function...
Serverless: Pods status: {"waiting":{"reason":"PodInitializing"}}
Serverless: Function capitalize-function successfully deployed
Serverless: Skipping ingress rule generation
▶ sls invoke -f capitalize-function -d '{"hello": "hello world"}' -l
Serverless: Calling function: capitalize-function...
--------------------------------------------------------------------
Hello world
ryuheechul commented 6 years ago

@andresmgot I've noticed that my serverless-kubeless npm module's version is 0.1.8 and the most recent version of it is 0.2.4 So mine seems pretty old and I think it was installed by serverless create --template kubeless-nodejs --path new-project. So I just updated it to 0.2.4 and tried again with the same command and it worked, finally. Sorry that I couldn't think about checking the module's version earlier.

ryuheechul commented 6 years ago

So I made a PR to prevent the same thing happens in the future. this PR should fix this issue.

andresmgot commented 6 years ago

oh thank you @ryuheechul for fixing the template! I am glad that you finally fixed your issue.

ryuheechul commented 6 years ago

@andresmgot You are welcome and thank you for your help!

andresmgot commented 6 years ago

I am going to close this since it seemed an issue with the serverless template. Let us know (or reopen this issue) if you still find any issue.