Giter Site home page Giter Site logo

serverless-kubeless's Introduction

Kubeless Serverless Plugin

This plugin brings Kubeless support within the Serverless Framework.

Kubeless is a Kubernetes-native Serverless solution.

Pre requisites

Make sure you have a kubernetes endpoint running and kubeless installed. You can find the installation intructions here.

Once you have Kubeless running in your cluster you can install serverless

$ npm install serverless -g

Try out the example

Clone this repo and check the example function

$ git clone https://github.com/serverless/serverless-kubeless
$ cd serverless-kubeless/examples/get-python
$ cat serverless.yml
service: hello

provider:
  name: kubeless
  runtime: python2.7

plugins:
  - serverless-kubeless

functions:
  hello:
    description: 'Hello function'
    handler: handler.hello

Download dependencies

$ npm install

Deploy function.

$ serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Deploying function hello...
Serverless: Function hello successfully deployed

The function will be deployed to k8s via kubeless.

$ kubectl get function
NAME      AGE
hello     50s

$ kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
hello-1815473417-1ttt7   1/1       Running   0          1m

Now you will be able to call the function:

$ serverless invoke -f hello -l
Serverless: Calling function: hello...
--------------------------------------------------------------------
hello world

You can also check the logs for the function:

$ serverless logs -f hello
172.17.0.1 - - [12/Jul/2017:09:47:18 +0000] "GET /healthz HTTP/1.1" 200 2 "" "Go-http-client/1.1" 0/118
172.17.0.1 - - [12/Jul/2017:09:47:21 +0000] "GET /healthz HTTP/1.1" 200 2 "" "Go-http-client/1.1" 0/93
172.17.0.1 - - [12/Jul/2017:09:47:24 +0000] "GET /healthz HTTP/1.1" 200 2 "" "Go-http-client/1.1" 0/108
172.17.0.1 - - [12/Jul/2017:09:47:25 +0000] "GET / HTTP/1.1" 200 11 "" "" 0/316

Or you can obtain the function information:

$ serverless info
Service Information "hello"
Cluster IP:  10.0.0.51
Type:  ClusterIP
Ports:
  Name:  http-function-port
  Protocol:  TCP
  Port:  8080
  Target Port:  8080
Function Info
Description: Hello function
Handler:  handler.hello
Runtime:  python2.7
Trigger: HTTP
Dependencies:

You can access the function through its HTTP interface as well using kubectl proxy and accessing:

$ curl http://127.0.0.1:8001/api/v1/namespaces/default/services/hello/proxy/
hello world

If you have a change in your function and you want to redeploy it you can run:

$ serverless deploy function -f hello
Serverless: Redeploying hello...
Serverless: Function hello successfully deployed

Finally you can remove the function.

$ serverless remove
Serverless: Removing function: hello...
Serverless: Function hello successfully deleted

Kubernetes secrets

Kubernetes secret objects let you store and manage sensitive information, such as passwords, OAuth tokens, and ssh keys. Putting this information in a secret is safer and more flexible than putting it verbatim in a Pod definition or in a container image. To use secrets follow the next steps:

  1. Create a K8s secret: kubectl create secret generic secret-file --from-file=secret.txt -n namespace-name

  2. Add the secret key into the provider definition in the serverless.yml file below the secrets key. You can specify an array of secrets and they will be mounted at root level in the pod file system using the path /<secret-name>:

...
functions:
  my-handler:
    secrets:
      - secret-file
    ...
  1. Now inside your pod, you will be able to access the route /secret-file/secret.txt.

serverless-kubeless's People

Contributors

afinch7 avatar alexander-alvarez avatar andresmgot avatar arditdine avatar bradleybluebean avatar brandonros avatar ccll avatar d0x2f avatar ddoowa avatar dependabot[bot] avatar dimagoldin avatar donhui avatar faxioman avatar gimlet2 avatar janthoe avatar jbianquetti-nami avatar julianpistorius avatar kainlite avatar lorenzo-ange avatar mpalumbo7 avatar mpratley avatar nea avatar ngtuna avatar pstreule avatar remacr avatar sebgoa avatar sepetrov avatar someoneweird avatar vishweshwarp avatar vognev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serverless-kubeless's Issues

Error 404 -while trying to access read-all function of todo backend app

I have deployed todo-app/backend/ app in GKE. while trying to access I am getting error 404.

To me it looks like an issue with ingress setup. I can see two ingress entries when I run below command:

kubectl get ingress
NAME            HOSTS                  ADDRESS       PORTS     AGE
basic-ingress   *                      35.190.11.9   80        12d
todos           35.185.19.186.xip.io                 80        16h

and the configuration todo yml file is:

 # Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
  creationTimestamp: 2018-04-24T11:43:58Z
  generation: 3
  name: todos
  namespace: default
  resourceVersion: "2514019"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/todos
  uid: c63bd143-47b4-11e8-8366-42010a8e0105
spec:
  rules:
  - host: 35.185.19.186.xip.io
    http:
      paths:
      - backend:
          serviceName: create
          servicePort: 8080
        path: /create
      - backend:
          serviceName: read-all
          servicePort: 8080
        path: /read-all
      - backend:
          serviceName: read-one
          servicePort: 8080
        path: /read
      - backend:
          serviceName: update
          servicePort: 8080
        path: /update
      - backend:
          serviceName: delete
          servicePort: 8080
        path: /delete
status:
  loadBalancer: {}

Configuration of basic-ingress is :

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/backends: '{"k8s-be-31459--852d88a6b447d59d":"HEALTHY"}'
    ingress.kubernetes.io/forwarding-rule: k8s-fw-default-basic-ingress--852d88a6b447d59d
    ingress.kubernetes.io/target-proxy: k8s-tp-default-basic-ingress--852d88a6b447d59d
    ingress.kubernetes.io/url-map: k8s-um-default-basic-ingress--852d88a6b447d59d
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"basic-ingress","namespace":"default"},"spec":{"backend":{"serviceName":"todos","servicePort":80}}}
  creationTimestamp: 2018-04-12T10:58:38Z
  generation: 3
  name: basic-ingress
  namespace: default
  resourceVersion: "2512980"
  selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/basic-ingress
  uid: 748163de-3e40-11e8-8366-42010a8e0105
spec:
  backend:
    serviceName: todos
    servicePort: 80
status:
  loadBalancer:
    ingress:
    - ip: 35.190.11.9

I am not very sure of this configuration of ingress, can someone help pls?

All my todos functions been deployed successfully:

D:\serverless\serverless-kubeless\examples\todo-app\backend>kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
create       ClusterIP   10.15.241.200   <none>        8080/TCP          2h
delete       ClusterIP   10.15.254.8     <none>        8080/TCP          2h
hello        ClusterIP   10.15.245.239   <none>        8080/TCP          18d
kubernetes   ClusterIP   10.15.240.1     <none>        443/TCP           21d
mongodb      NodePort    10.15.245.199   <none>        27017:30505/TCP   2h
read-all     ClusterIP   10.15.243.242   <none>        8080/TCP          2h
read-one     ClusterIP   10.15.248.185   <none>        8080/TCP          2h
update       ClusterIP   10.15.253.150   <none>        8080/TCP          2h

Feature Request: Provide configuration support for ingress annotations

Provide configuration support for ingress rules.

provider:
  name: kubeless
  runtime: nodejs8

plugins:
  - serverless-kubeless

functions:
  capitalize:
    handler: handler.capitalize
    events:
      - http:
          path: /cap

Plugin defines nginx by default: https://github.com/serverless/serverless-kubeless/blob/master/lib/ingress.js

annotations: { 'kubernetes.io/ingress.class': 'nginx', 'nginx.ingress.kubernetes.io/rewrite-target': '/', },

Aftrer function deployment, it's possible to re-configure the ingress rule to use traefik ingress.class:

"annotations": { "kubernetes.io/ingress.class": "traefik", "traefik.frontend.rule.type": "PathPrefixStrip" }

The we can invoke the function through traefik.

$ curl -H "Content-Type: application/json" -X POST -d 'xyz' http://localhost:31907/cap

Xyz

Could be possible to add annotations to the configuration?

Thanks!

Is it possible to get error logging?

I didn't trust the deployment so I intentionally broke it to see what would happen
below is what showed up in the console

~/dev/serverless$ serverless deploy 
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Unable to find any running pod for capitalize. Retrying...
Serverless: Unable to find any running pod for capitalize. Retrying...
Serverless: Unable to find any running pod for capitalize. Retrying...
Serverless: Unable to find any running pod for capitalize. Retrying...
Serverless: Giving up, unable to retrieve the status of the capitalize deployment. 

Which isn't very helpful for debugging purposes. Through searching I found #85 which led me to this command:

kubectl logs -n kubeless $(kubectl get pods -n kubeless -l kubeless=controller -o=name)

Which showed me exactly why my function is broken

time="2018-06-04T20:25:05Z" level=info msg="Processing change to Function default/capitalize" pkg=function-controller
time="2018-06-04T20:25:05Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2018-06-04T20:25:05Z" level=error msg="Error processing default/capitalize (giving up): failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller

I'm curious if this is something we could bubble up to stderr?

unable to call or update function

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

Ingress rule in multi-function case

When deploying the todo example in GKE, several ingress rule get created.

Each one gets a public IP, that means that the frontend would need to use different targets, not a single one. So that's a bug :)

In the multi-function case we need a single ingress to be created with multiple rules in it.

deploying multiple Python modules

How do I deploy non-trivial Python code, which has multiple Python modules?
Example:
the function is in handler.py
but handler.py imports from models.py

Currently, the deploy fails because it doesn't include models.py.

How do I tell it to include the models.py file?

python requirements.txt

How do I pass the requirements.txt via serverless to kubeless?
Can I install Python modules with native dependencies, like psycopg2?

auto ingress / loadbalancer

The serverless plugin should auto-create an ingress route for each function, so that the expected behavior is the same compared to other serverless cloud environments like AWS lambda, and you get in the output the HTTPS endpoint after deploying.

Otherwise this becomes very tedious and developers have to manually figure out things like API gateways, firewall rules, etc.

Unable to verify the first certificate error when attempting to connect to Docker CE for Windows (Edge) Kubernetes

Using Docker CE for Windows (Edge) with Kubernetes enabled and Kubeless v0.5.0 installed, I receive the following error when executing serverless info on the example project:

Error --------------------------------------------------

Error: unable to verify the first certificate

Docker has setup my .kube/config with a https url and insecure-skip-tls-verify: true.

Looking into lib/crd.js of 0.4.0 I can see request being called with connectionOptions, but helper.getConnectionOptions does not include the strictSSL option, which would prevent request from rejecting an invalid connection.

Adding connectionOptions.strictSSL = false; after connectionOptions.insecureSkipTlsVerify = true; on line 139 of lib/helpers.js should resolve this, assuming I've understood the issue correctly.

Function Pod doesn't come up when requirements.txt is used for dependencies

If we use requirements.txt with dependencies defined in it, 'serverless deploy' gets stuck with pod at Init state.

Dependency mentioned in requirements.txt is not even used in my handler.py. And if I just delete requirements.txt file from service folder, everything starts working, function gets deployed without any issues.

mongo-connect-7dfb4868f-crt96 0/1 Init:CrashLoopBackOff 4 5m

handler.py

def mongoConnect():
    return 'Connected to MongoDB'

requirements.txt

pymongo==2.7

serverless.yml

service: mongo-utils

provider:
  name: kubeless
  runtime: python2.7

plugins:
  - serverless-python-requirements
  - serverless-kubeless
functions:
  mongo-connect:
    handler: handler.mongoConnect

custom:
  pythonRequirements:
    pythonBin: C:\Python27\python.exe
    invalidateCaches: true

Serverless Commands:

C:\Users\myusername\workspace\devopsinsight\functions\mongo-utils>sls deploy
Serverless: Installing required Python packages with C:\Python27\python.exe...
Serverless: Linking required Python packages...
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Unlinking required Python packages...
Serverless: Deploying function mongo-connect...

Pod logs:

C:\>kubectl logs mongo-connect-7dfb4868f-crt96
Error from server (BadRequest): container "mongo-connect" in pod "mongo-connect-7dfb4868f-crt96" is waiting to start: PodInitializing

Function pod describe:

C:\>kubectl describe po mongo-connect-7dfb4868f-crt96
Name:           mongo-connect-7dfb4868f-crt96
Namespace:      default
Node:           cmbu-devops-services-kube-node2/10.197.10.228
Start Time:     Thu, 28 Dec 2017 21:38:38 +0530
Labels:         function=mongo-connect
                pod-template-hash=389604249
Annotations:    kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"ReplicaSet","namespace":"default","name":"mongo-connect-7dfb4868f","uid":"96ba80eb-ebe9-11e7-b07f-005056ac...
                prometheus.io/path=/metrics
                prometheus.io/port=8080
                prometheus.io/scrape=true
Status:         Pending
IP:             10.42.0.9
Created By:     ReplicaSet/mongo-connect-7dfb4868f
Controlled By:  ReplicaSet/mongo-connect-7dfb4868f
Init Containers:
  prepare:
    Container ID:  docker://947ac94729615804397bc6bd0d707262e9d166a799be6c78dfe424bd56dd8950
    Image:         kubeless/unzip@sha256:f162c062973cca05459834de6ed14c039d45df8cdb76097f50b028a1621b3697
    Image ID:      docker-pullable://kubeless/unzip@sha256:f162c062973cca05459834de6ed14c039d45df8cdb76097f50b028a1621b3697
    Port:          <none>
    Command:
      sh
      -c
    Args:
      cp /src/handler.py /kubeless/handler.py && cp /src/requirements.txt /kubeless
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Thu, 28 Dec 2017 21:38:39 +0530
      Finished:     Thu, 28 Dec 2017 21:38:39 +0530
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /kubeless from mongo-connect (rw)
      /src from mongo-connect-deps (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-qkfws (ro)
  install:
    Container ID:  docker://6f70b3837f8ae4379c8ce7bc63f2f0590759dc038818d56e595d25a61d18bd11
    Image:         tuna/python-pillow:2.7.11-alpine
    Image ID:      docker-pullable://tuna/python-pillow@sha256:6e39c3a1382e0666eac1e435b8dd78e202d1cf791166ba2a77ad52a6584e04ac
    Port:          <none>
    Command:
      sh
      -c
    Args:
      pip install --prefix=/kubeless -r /kubeless/requirements.txt
    State:          Running
      Started:      Thu, 28 Dec 2017 21:42:27 +0530
    Last State:     Terminated
      Reason:       Error
      Exit Code:    1
      Started:      Thu, 28 Dec 2017 21:40:56 +0530
      Finished:     Thu, 28 Dec 2017 21:42:01 +0530
    Ready:          False
    Restart Count:  3
    Environment:
      FUNC_HANDLER:  mongoConnect
      MOD_NAME:      handler
      FUNC_TIMEOUT:  180
      TOPIC_NAME:
    Mounts:
      /kubeless from mongo-connect (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-qkfws (ro)
Containers:
  mongo-connect:
    Container ID:
    Image:          kubeless/python@sha256:ba948a6783b93d75037b7b1806a3925d441401ae6fba18282f712a1b1a786899
    Image ID:
    Port:           8080/TCP
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
    Restart Count:  0
    Liveness:       http-get http://:8080/healthz delay=3s timeout=1s period=30s #success=1 #failure=3
    Environment:
      FUNC_HANDLER:  mongoConnect
      MOD_NAME:      handler
      FUNC_TIMEOUT:  180
      TOPIC_NAME:
      PYTHONPATH:    /kubeless/lib/python2.7/site-packages
    Mounts:
      /kubeless from mongo-connect (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-qkfws (ro)
Conditions:
  Type           Status
  Initialized    False
  Ready          False
  PodScheduled   True
Volumes:
  mongo-connect:
    Type:    EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
  mongo-connect-deps:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      mongo-connect
    Optional:  false
  default-token-qkfws:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-qkfws
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.alpha.kubernetes.io/notReady:NoExecute for 300s
                 node.alpha.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason                 Age                     From                                      Message
  ----     ------                 ----                    ----                                      -------
  Normal   SuccessfulMountVolume  3m                      kubelet, cmbu-devops-services-kube-node2  MountVolume.SetUp succeeded for volume "mongo-connect"
  Normal   SuccessfulMountVolume  3m                      kubelet, cmbu-devops-services-kube-node2  MountVolume.SetUp succeeded for volume "mongo-connect-deps"
  Normal   SuccessfulMountVolume  3m                      kubelet, cmbu-devops-services-kube-node2  MountVolume.SetUp succeeded for volume "default-token-qkfws"
  Normal   Pulled                 3m                      kubelet, cmbu-devops-services-kube-node2  Container image "kubeless/unzip@sha256:f162c062973cca05459834de6ed14c039d45df8cdb76097f50b028a1621b3697" already present on machine
  Normal   Created                3m                      kubelet, cmbu-devops-services-kube-node2  Created container
  Normal   Started                3m                      kubelet, cmbu-devops-services-kube-node2  Started container
  Normal   Scheduled              2m                      default-scheduler                         Successfully assigned mongo-connect-7dfb4868f-crt96 to cmbu-devops-services-kube-node2
  Warning  BackOff                6s (x3 over 1m)         kubelet, cmbu-devops-services-kube-node2  Back-off restarting failed container
  Warning  FailedSync             6s (x3 over 1m)         kubelet, cmbu-devops-services-kube-node2  Error syncing pod
  Normal   Pulled                 <invalid> (x4 over 3m)  kubelet, cmbu-devops-services-kube-node2  Container image "tuna/python-pillow:2.7.11-alpine" already present on machine
  Normal   Created                <invalid> (x4 over 3m)  kubelet, cmbu-devops-services-kube-node2  Created container
  Normal   Started                <invalid> (x4 over 3m)  kubelet, cmbu-devops-services-kube-node2  Started container


Add support for custom runtime image

This is a ALPHA feature in kubeless, but I need it now for several reasons:

  1. I'd like to use python3.6 which is not officially supported right now.
  2. My function have dozens of dependencies, where the deployment speed is drastically slowed down by the pod init container. And this is particularly bad if later I decided to start using HPA to auto-scale my pods.

After browsing the code I didn't found this feature, and I think may be I could give it a try.
I compared two 'function.k8s.io' objects, one created with official runtime and another with a custom runtime, the only difference to me is that the former one fills the property spec.runtime while the later fills spec.template.spec.containers.image.

So I guess the steps to implement this feature is as simple as:

  1. add a new optional property like service.provider.image to the serverless.yaml, the save level as the runtime property.
  2. parse the new property and fill it in the returned function.k8s.io object of getFunctionDescription in file lib/deploy.js.
  3. then the function object get posted to the server by lib/functions.js.

Please feel free to give me some directions.

deploy fails with "Unauthorized" error, probably due to RBAC.

Running serverless deploy in any project folder results in the following:

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Skipping deployment of chained_seq since it doesn't have a handler
Unable to find required information for authenticating against the cluster
Unable to find required information for authenticating against the cluster
Unable to find required information for authenticating against the cluster
Unable to find required information for authenticating against the cluster
Unable to find required information for authenticating against the cluster
Unable to find required information for authenticating against the cluster
undefined:1
Unauthorized
^

SyntaxError: Unexpected token U in JSON at position 0
    at JSON.parse (<anonymous>)
    at Request.request.get.on.on.on (/Users/****/Source/serverless-kubeless/examples/node-chaining-functions/node_modules/serverless-kubeless/lib/functions.js:47:27)

I'm running on a cluster with RBAC, and am using the RBAC-enabled version of Kubeless, so I expect that's what's causing this.

Figure out which key to use for namespace

since we can launch functions in non default namespaces, we need to figure out which key in the servereless schema we can use to specify the namespace for deployment.

create function template

serverless provides a command to create function template

$ serverless create --template aws-python --path my-service

We should also have

$ serverless create --template kubeless-python --path my-service

Or kubernetes-python ?

Review integration tests

We need to:

  • Upgrade Minikube version to 0.25 to test agains Kubernetes 1.9
  • Use RBAC for testing examples
  • Use Minikube Ingress addon that is more updated that the current manifest
  • Re-enable events test: It is now flaky due to errors while trying to publish a message
  • Ruby-get test depends on the Github API, returning errors if the max quota is reached.

[WIP] Nodejs provider-level environment variables aren't propagated

WIP while I work to fix the issue, but noting it here in case it's already in-progress somewhere else.

Versions
serverless-kubeless: 0.4.2
kubeless: 1.0.0-alpha.3

Runtime
minikube: 0.27.0

Expected: environment variables specified at either the provider or function level are available to the deployed function at runtime.

Actual: only environment variables specified at the function level are available to the deployed function at runtime.

For example...

TEST_FUNCTION_VARIABLE will be available to the deployed function at runtime.
TEST_PROVIDER_VARIABLE will not be available to the deployed function at runtime.

service: gql

plugins:
  - serverless-kubeless

provider:
  name: kubeless
  runtime: nodejs8
  environment:
    TEST_PROVIDER_VARIABLE: "bluto"

functions:
  example:
    handler: handlers.example
    timeout: 300
    events:
      - http:
          path: example
    environment:
      TEST_FUNCTION_VARIABLE: "popeye"

Error "Not Found" during "invoke" verb? error invoking at least Ruby or Python

I'm trying to get this working and I seem to have hit a bug in the serverless client, or kubeless plugin to it.

$ serverless invoke -f hello -l
Serverless: Calling function: hello...

  Error --------------------------------------------------

  Not Found

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           10.4.1
     Serverless Version:     1.27.3

$ kubeless function call hello
v1.0.0-alpha.6

So it looks like my "hello" function is installed correctly. I can call it directly with the 'kubeless' function call verb. I started with the example from serverless-ruby repo which is meant for AWS and simplified it to use the serverless-ruby plugin instead, but I wound up swapping almost everything out for the version.rb contents in the ruby-get example here, in this project.

These are my repo contents:

serverless.yml

service: index

provider:
  name: kubeless
  runtime: ruby2.4

plugins:
  - serverless-kubeless

functions:
  hello:
    handler: index.hello

package.json

{
  "name": "hello",
  "version": "1.0.0",
  "description": "Example function for serverless kubeless",
  "dependencies": {
    "serverless-kubeless": "^0.4.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": ""
}

index.rb

def hello(event, context)
  require "net/https"
  require "uri"
  require "json"

  # Fetch release info
  uri = URI.parse("https://api.github.com/repos/bitnami/kubeless/releases")
  http = Net::HTTP.new(uri.host, uri.port)
  request = Net::HTTP::Get.new(uri.request_uri)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
  response = http.request(request)

  # Follow redirects if needed
  if response.code == "301"
    response = Net::HTTP.get_response(URI.parse(response.header['location']))
  end

  # Parse response
  output = JSON.parse(response.body)
  puts output
  # Create a Hash for output
  output_hash = { :version => output[0]['tag_name'] }

  return output_hash[:version]
end

The examples are the same if I try with the serverless-kubeless examples/get-ruby itself.

I can invoke the functions through the kubeless client but not the serverless invoker. At first I thought it was actually the fact that I was missing kubeless client itself, but now I have it and I still have the issue with serverless invoke as below:

~/projects/serverless-kubeless/examples/get-ruby (master u=)$ serverless invoke -f version
Serverless: Calling function: version...

  Error --------------------------------------------------

  Not Found

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           10.4.1
     Serverless Version:     1.27.3

~/projects/serverless-kubeless/examples/get-ruby (master u=)$ kubeless function call version
v1.0.0-alpha.6

I think "Not Found" must be coming from somewhere, in case the stack trace is helpful here it is from SLS_DEBUG=*

kbarret8@kbarret8-mbp:~/projects/serverless-kubeless/examples/get-ruby (master u=)$ export SLS_DEBUG='*'
kbarret8@kbarret8-mbp:~/projects/serverless-kubeless/examples/get-ruby (master u=)$ serverless invoke -f version
Serverless: Load command run
Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command create
Serverless: Load command install
Serverless: Load command package
Serverless: Load command deploy
Serverless: Load command deploy:function
Serverless: Load command deploy:list
Serverless: Load command deploy:list:functions
Serverless: Load command invoke
Serverless: Load command invoke:local
Serverless: Load command info
Serverless: Load command logs
Serverless: Load command login
Serverless: Load command logout
Serverless: Load command metrics
Serverless: Load command print
Serverless: Load command remove
Serverless: Load command rollback
Serverless: Load command rollback:function
Serverless: Load command slstats
Serverless: Load command plugin
Serverless: Load command plugin
Serverless: Load command plugin:install
Serverless: Load command plugin
Serverless: Load command plugin:uninstall
Serverless: Load command plugin
Serverless: Load command plugin:list
Serverless: Load command plugin
Serverless: Load command plugin:search
Serverless: Load command emit
Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command info
Serverless: Load command logs
Serverless: Invoke invoke
Serverless: Calling function: version...

  Error --------------------------------------------------

  Not Found

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Stack Trace --------------------------------------------

Error: Not Found
    at Request.parseReponse [as _callback] (/Users/kbarret8/Desktop/devel/serverless-kubeless/examples/get-ruby/node_modules/serverless-kubeless/lib/invoke.js:110:18)
    at Request.self.callback (/Users/kbarret8/Desktop/devel/serverless-kubeless/examples/get-ruby/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.EventEmitter.emit (domain.js:442:20)
    at Request.<anonymous> (/Users/kbarret8/Desktop/devel/serverless-kubeless/examples/get-ruby/node_modules/request/request.js:1157:10)
    at Request.emit (events.js:182:13)
    at Request.EventEmitter.emit (domain.js:442:20)
    at IncomingMessage.<anonymous> (/Users/kbarret8/Desktop/devel/serverless-kubeless/examples/get-ruby/node_modules/request/request.js:1079:12)
    at Object.onceWrapper (events.js:273:13)
    at IncomingMessage.emit (events.js:187:15)
    at IncomingMessage.EventEmitter.emit (domain.js:442:20)
    at endReadableNT (_stream_readable.js:1081:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
From previous event:
    at PluginManager.invoke (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:372:22)
    at PluginManager.run (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:403:17)
    at variables.populateService.then (/usr/local/lib/node_modules/serverless/lib/Serverless.js:102:33)
    at runCallback (timers.js:696:18)
    at tryOnImmediate (timers.js:667:5)
    at processImmediate (timers.js:649:5)
    at process.topLevelDomainCallback (domain.js:121:23)
From previous event:
    at Serverless.run (/usr/local/lib/node_modules/serverless/lib/Serverless.js:89:74)
    at serverless.init.then (/usr/local/lib/node_modules/serverless/bin/serverless:42:50)

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           10.4.1
     Serverless Version:     1.27.3

I get the exact same result from the Python example, I can call the function through kubeless function but the serverless client does know know where to find it.

Here's my package-lock.json in a gist too, in case that is helpful:

$ cat package-lock.json

...

https://gist.github.com/kingdonb/d87bfefbee7de89a431082b429211b1b

environment variables support

I didn't see any documentation for serverless variables, such as exist with AWS, example:

provider:
name:aws
environment:
PUBSUB_KEY: pubsub_admin_key.json
EVENTS_TOPIC: events

Is the passing of environment variables in this manner supported?

thanks

Unable to find any running pod for hello. Retrying..

i got this error "Unable to find any running pod for hello. Retrying.." while doing serverless deploy ? i have cloned all the files and i have kubernetes cluster running on-premise ? what i am missing here

complete metadata

I looked at the other plugins in detail to find the lowest common denominator and cross-checked kubeless functionality.

There are a few features that we need to add in kubeless and I created:
vmware-archive/kubeless#215 to track them.

As of today, we need to aim for complete metadata to become:

provider:
  name: kubeless
  namespace: default
  runtime: nodejs6.10
  memorySize: 512

functions:
  hello:
    handler: handler.hello
    description: "this will be free from annotation for a function"
    environment:
      variable2: value2
    labels:
      foo: bar
    events:
      - http:
          path: users/create
          method: get
      - trigger: <topic_name>
      - schedule: '*/8 * * * * *'
  • namespace can be added right away #26
  • memorySize needs support added in kubeless
  • description needs support added
  • environment needs support added
  • labels needs support added
  • events schedule needs support added but trigger and http already exist. #25

Note that keys can be added at the provider level to make all functions in the service inherit them. Or they can be specified per function. For instance the provider level memory could be set to 512 but then overriden at the function level.

strange error

I got an error while deploying, but the function did deploy and serverless info later returns:

$ serverless deploy
Serverless: Packaging service...
/Users/sebgoa/Documents/go/src/github.com/kubeless/serverless-kubeless/deploy/kubelessDeploy.js:88
        if (err) throw new Error(err);
                 ^

Error: Error: etcdserver: request timed out
    at core.pods.get (/Users/sebgoa/Documents/go/src/github.com/kubeless/serverless-kubeless/deploy/kubelessDeploy.js:88:24)
    at /Users/sebgoa/Documents/go/src/github.com/kubeless/serverless-kubeless/node_modules/kubernetes-client/lib/base.js:11:14
    at Request.request [as _callback] (/Users/sebgoa/Documents/go/src/github.com/kubeless/serverless-kubeless/node_modules/kubernetes-client/lib/api-group.js:123:7)
    at Request.self.callback (/Users/sebgoa/Documents/go/src/github.com/kubeless/serverless-kubeless/node_modules/request/request.js:188:22)
    at emitTwo (events.js:106:13)
    at Request.emit (events.js:194:7)
    at Request.<anonymous> (/Users/sebgoa/Documents/go/src/github.com/kubeless/serverless-kubeless/node_modules/request/request.js:1171:10)
    at emitOne (events.js:96:13)
    at Request.emit (events.js:191:7)
    at IncomingMessage.<anonymous> (/Users/sebgoa/Documents/go/src/github.com/kubeless/serverless-kubeless/node_modules/request/request.js:1091:12)
    at Object.onceWrapper (events.js:293:19)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:188:7)
    at endReadableNT (_stream_readable.js:975:12)
    at _combinedTickCallback (internal/process/next_tick.js:80:11)
    at process._tickDomainCallback (internal/process/next_tick.js:128:9)
sebgoa@foobar nodejs $ l s-l
-bash: l: command not found
sebgoa@foobar nodejs $ serverless info

Service Information "capitalize"
Cluster IP:  10.23.243.165
Type:  NodePort
Ports: 
  Protocol:  TCP
  Port:  8080
  Target Port:  8080
  Node Port:  32685
Function Info
Handler:  handler.capitalize
Runtime:  nodejs6.10
Topic:  
Dependencies:  {
  "name": "kubeless-nodejs",
  "version": "1.0.0",
  "description": "Example function for serverless kubeless",
  "dependencies": {
    "serverless-kubeless": "^0.1.3",
    "lodash": "^4.1.0"
  },
  "devDependencies": {},
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "serverless",
    "kubeless"
  ],
  "author": "The Kubeless Authors",
  "license": "Apache-2.0"
}

labels and description not set in metadata section

labels and description are set outside the metadata section:

$ kubectl get function hello-world -o yaml
annotations:
  kubeless.serverless.com/description: example node.js kubeless function
apiVersion: k8s.io/v1
kind: Function
labels:
  kubeless: nodejs
metadata:
  creationTimestamp: 2017-08-15T14:21:40Z
  name: hello-world
  namespace: default
  resourceVersion: "2116"
  selfLink: /apis/k8s.io/v1/namespaces/default/functions/hello-world
  uid: 0e64074e-81c5-11e7-986b-0800279006b6

unable to authenticate against the cluster

I was able to deploy to my Google Container Engine cluster the first time.

After I made a change and tried to re-deploy, I get this error:

Serverless: Excluding development dependencies...
Unable to find required information for authenticating against the cluster

I tried to re-run:
gcloud container clusters get-credentials production --zone us-west1-a --project pname

but didn't help

thanks

Deployment of functions is failing on new release of Kubeless 0.3.2 with error "spec.ports: Required value"

Tried deploying a very basic python function. Looks like this issue is due to newly added custom port support in latest kubeless release (0.3.2)

Serverless deploy log:

root@vishu-dev-vm:/workspace/devops-insight/functions/new-project# serverless deploy -v
Serverless: Load command run
Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command create
Serverless: Load command install
Serverless: Load command package
Serverless: Load command deploy
Serverless: Load command deploy:function
Serverless: Load command deploy:list
Serverless: Load command deploy:list:functions
Serverless: Load command invoke
Serverless: Load command invoke:local
Serverless: Load command info
Serverless: Load command logs
Serverless: Load command login
Serverless: Load command logout
Serverless: Load command metrics
Serverless: Load command print
Serverless: Load command remove
Serverless: Load command rollback
Serverless: Load command rollback:function
Serverless: Load command slstats
Serverless: Load command plugin
Serverless: Load command plugin
Serverless: Load command plugin:install
Serverless: Load command plugin
Serverless: Load command plugin:uninstall
Serverless: Load command plugin
Serverless: Load command plugin:list
Serverless: Load command plugin
Serverless: Load command plugin:search
Serverless: Load command emit
Serverless: Load command config
Serverless: Load command config:credentials
Serverless: Load command info
Serverless: Load command logs
Serverless: Invoke deploy
Serverless: Invoke package
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Deploying function hello...
Serverless: Unable to find any running pod for hello. Retrying...
Serverless: Unable to find any running pod for hello. Retrying...
Serverless: Unable to find any running pod for hello. Retrying...
Serverless: Unable to find any running pod for hello. Retrying...
Serverless: Giving up, unable to retrieve the status of the hello deployment.
/workspace/devops-insight/functions/new-project/node_modules/bluebird/js/release/async.js:61
        fn = function () { throw arg; };
                           ^

Error: Unable to retrieve the status of the hello deployment
    at module.exports.logError (/root/.nvm/versions/node/v8.9.3/lib/node_modules/serverless/lib/classes/Error.js:94:11)
    at process.on (/root/.nvm/versions/node/v8.9.3/lib/node_modules/serverless/bin/serverless:21:3)
    at emitTwo (events.js:126:13)
    at process.emit (events.js:214:7)
    at methodName (/workspace/devops-insight/functions/new-project/node_modules/bluebird/js/release/debuggability.js:189:33)
    at activeFireEvent (/workspace/devops-insight/functions/new-project/node_modules/bluebird/js/release/debuggability.js:232:44)
    at fireRejectionEvent (/workspace/devops-insight/functions/new-project/node_modules/bluebird/js/release/debuggability.js:617:14)
    at Promise._notifyUnhandledRejection (/workspace/devops-insight/functions/new-project/node_modules/bluebird/js/release/debuggability.js:64:9)
    at Timeout._onTimeout (/workspace/devops-insight/functions/new-project/node_modules/bluebird/js/release/debuggability.js:43:14)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5)

Kubeless Controller log:

time="2017-12-29T15:33:47Z" level=info msg="Processing change to Function default/hello" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Function can not be created/updated: Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Error processing default/hello (will retry): Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=info msg="Processing change to Function default/hello" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Function can not be created/updated: Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Error processing default/hello (will retry): Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=info msg="Processing change to Function default/hello" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Function can not be created/updated: Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Error processing default/hello (will retry): Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=info msg="Processing change to Function default/hello" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Function can not be created/updated: Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=error msg="Error processing default/hello (will retry): Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:47Z" level=info msg="Processing change to Function default/hello" pkg=controller
time="2017-12-29T15:33:48Z" level=error msg="Function can not be created/updated: Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:48Z" level=error msg="Error processing default/hello (will retry): Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:48Z" level=info msg="Processing change to Function default/hello" pkg=controller
time="2017-12-29T15:33:49Z" level=error msg="Function can not be created/updated: Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
time="2017-12-29T15:33:49Z" level=error msg="Error processing default/hello (giving up): Service \"hello\" is invalid: spec.ports: Required value" pkg=controller
E1229 15:33:49.543861       1 controller.go:171] Service "hello" is invalid: spec.ports: Required value

Check plugin on Windows

There could be an issue on windows where the kube config file is not properly found due to the HOME env var.

`sls deploy` prints "Unable to find any running pod for <xxxxx>. Retrying..."

The deployment is indeed successful, despite the error message.
Seems that the detection of the deployed pod failed, so serverless-kubeless keeps printing the error message and creating new pods.
With kubectl get pod I can see there is one function pod in Running status and several in Terminating status.

image

My environment:

$ lsb_release -a
Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.3 LTS
Release:	16.04
Codename:	xenial

$ npm -v
3.10.10

$ node -v
v6.11.5

$ sls -v
1.23.0

$ kubeless version
Kubeless version: v0.2.3 (bfefb404)

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"8", GitVersion:"v1.8.2", GitCommit:"bdaeafa71f6c7c04636251031f93464384d54963", GitTreeState:"clean", BuildDate:"2017-10-24T19:48:57Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"7+", GitVersion:"v1.7.6-gke.1", GitCommit:"407dbfe965f3de06b332cc22d2eb1ca07fb4d3fb", GitTreeState:"clean", BuildDate:"2017-09-27T21:21:34Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

$ cat package.json 
{
  "name": "kubeless-python",
  "version": "1.0.0",
  "description": "Sample Kubeless Python serverless framework service.",
  "dependencies": {
    "serverless-kubeless": "^0.2.2"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "serverless",
    "kubeless"
  ],
  "author": "The Kubeless Authors",
  "license": "Apache-2.0"
}

Add verbosity information

Currently there is no verbosity information when doing the commands.

we need to add some basic verbosity info

More docs for nodejs runtime

(I am happy to help with this if I know the right place to put it.)

For someone mainly coming from AWS, I had a lot of questions about running in Kubeless that weren't that hard to track down, but would've been nice to be documented all in one place.

For example (in the docs, this could be explained in more detail):

  • the http event is proxied by express
  • data passed to the function as event.data is either a string or an object depending on the request's content-type header
  • all HTTP methods are supported by default, and this is not configurable
  • functions can return promises for the response they want to return
  • functions can return a string, an object (in which case the response's content-type will be application/json) or anything else and that anything else will be JSON.stringify-d
  • there is no way to return a custom HTTP status code
  • there is no way to return custom HTTP headers
  • if you throw an error, the response to the client will always be 500 Internal Server Error
  • the only other HTTP response is 408 script timeout (with a default of 180 seconds)(
  • CORS is handled by for you automatically and will allow all requested methods and header in the pre-flight, but the allow origin will always be '*', which will not work with credentialed CORS requests
  • the shape of the event you get in your function will look like (where request is a standard nodejs request object edit: and response is a standard nodejs http response object ):
{
            'event-type': req.get('event-type'),
            'event-id': req.get('event-id'),
            'event-time': req.get('event-time'),
            'event-namespace': req.get('event-namespace'),
            data,
            'extensions': { request: req, response: res },
        }

I'm also interested in opening some PRs to extend some of the capabilities to allow for more flexible responses, is that encouraged?

Ingress, manually configured for TLS, loses TLS configuration on redeploy

Hello, fairly new to Kubernetes/Kubeless/Serverless so I don't know what details to provide. Happy to give more if needed.

I'm running Rancher 2.0, Kubernetes 1.10.1, and Kubeless 1.0.0-alpha3. I have a function configured like this:

service: myservice

provider:
  name: kubeless
  runtime: nodejs8
  namespace: myapp
  hostname: example.com

plugins:
  - serverless-kubeless

functions:
  feed:
    handler: handler.feed
    events:
      - http:
          path: /api/feed

This correctly creates everything as expected, only my service responds to http://example.com/api/feed.

Next I use cert-manager 0.2.9 to deploy a LetsEncrypt cert in the function's namespace. I log into Rancher's web interface, then pair the cert with the ingress created by the plugin. My function is now accessible at https://example.com/api/feed. Perfect.

But when I redeploy the service, the pairing with the certificate is lost. Once again the function is only accessible via http, and once again I have to connect my cert with my ingress.

I'm not immediately sure how this plugin is reconfiguring the ingress if it already exists. Could it be configured to merge any changed configs rather than completely override everything? I imagine it has to point to the new function somehow, but it'd be great if my manual changes were preserved.

Alternately, some means of configuring a TLS cert on the ingress from serverless.yml would also be helpful. I just don't want to keep losing https on every new serverless deploy. I don't want to bikeshed the specifics on how that will ultimately happen. :)

Thanks.

Unable to redeploy functions

When deploying a function, the first time I can deploy it without any issues, but if I try to redeploy it, either with the command sls deploy or only deploying the function with sls deploy -f ping, I got an error coming from kubernetes:

$ sls deploy -f ping
Serverless: Packaging function: ping...
Serverless: Excluding development dependencies...
Serverless: Redeploying ping...

  Error --------------------------------------------------

  Found errors while processing the given functions:
Error: Unable to update the function ping. Received:
  Code: 422
  Message: Function.kubeless.io "ping" is invalid: apiVersion: Invalid value: "Function": must be kubeless.io/v1beta1

     For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           8.11.1
     Serverless Version:     1.27.3

The first time after deploying everything it works perfect, but afterwards I am getting this error.

This is my serverless.yml file:

service: pingpong
provider:
  name: kubeless
  runtime: nodejs8
  hostname: myhostname.io

plugins:
  - serverless-kubeless

functions:
  ping:
    handler: handler.ping
    events:
      - http:
          path: /ping

And this is the handler:

const _ = require('lodash');
const fetch = require('node-fetch');

const ping = (event, context) => {
  const { request, response } = event.extensions;
  _.assign(event.data, { date: new Date().toTimeString() });

  return fetch('http://pong:8080/pong', {
    method: 'GET'
  }).then(async (res) => {
    const resp = await res.json();
    return {
      msg: 'called from ping, and response from',
      resp
    }
  }); 
};

module.exports = {
  ping
};

I noticed that if I change the handler file and try to redeploy, then I don't get any error, even if I only change one space.

Is it possible for one function to call another via http post/get?

Using the node capitalize example:

// serverless.yml

service: capitalize

provider:
  name: kubeless
  runtime: nodejs6

plugins:
  - serverless-kubeless

functions:
  capitalize:
    handler: handler.capitalize
  capitalize2:
    handler: handler.capitalize2
// handler.js
"use strict";

const _ = require("lodash");

module.exports = {
  capitalize(req, res) {
    let body = [];
    req
      .on("error", err => {
        console.error(err);
      })
      .on("data", chunk => {
        body.push(chunk);
      })
      .on("end", () => {
        body = Buffer.concat(body).toString();
        res.end(_.capitalize(body));
      });
  },
  capitalize2(req, res) {
    let body = [];
    req
      .on("error", err => {
        console.error(err);
      })
      .on("data", chunk => {
        body.push(chunk);
      })
      .on("end", () => {
        body = Buffer.concat(body).toString();
        if (body === "hello world!") {
          var fetch = require("node-fetch");
          fetch("/capitalize", {
            method: "POST",
            body: body
          })
            .then(res => res.text())
            .then(text => res.end(text.concat("cool!")))
            .catch(console.error);
        } else {
          res.end(body);
        }
      });
  }
};

I'm trying to have capitalize2 call capitalize based on the string that was passed in to the body. Contrived example I know, but I would need to be able to do similar things for a more complex setup.

I'm getting a relative path error. How would I be able to make this work?

is invoke local working

i m trying out sls kubeless plugin, im using the kubeless-nodejs template to create a new function.
Executing the command serverless invoke local --function capitalize --data 'this is a test' --raw however, doesn't seem to return anything, am I missing something here?

How to support folder in handler

I use aws lambda in the past but it almost unavailable in China. So I try to use kubeless, but still have some questions, hople you can help me.

In the past my serverless.yml file like this:

  listIndexPicture:
    handler: picture/picture.list
    events:
      - http:
          path: picture/index
          method: get

But it seems that this plugin didn't support folder, I must write like this:

  save-music:
    handler: music.save
    events:
      - http:
          path: /music

If I make a folder named music and move music.js into music then change handler to music/music.save it will 503.
If handler must in root folder I think itn't good for large project, maybe I can divide the project into a lots of small project but every small project may need some common utils just as helper.js, how to manage the common js is a problem for me. Also if I want to deploy the function to server I must goto the folder and run sls deploy then goto other folder and run command again.

If the handler support folder please let me know, thanks.

Add event type

We should be able to define whether the functions is http or event triggered.

There does not seem to be a standard among the current providers but there is an event section, in which we can define http and trigger...need to check exact syntax.

events:
  - http

or:

events:
  - stream: <topic name>

Something like that we need to investigate the best schema for it.

Unable to deploy serverless-kubeless functions from Windows

Commands executed:

git clone https://github.com/serverless/serverless-kubeless
cd examples\get-python
npm install
serverless deploy

Error log:

Serverless: Packaging service...
Serverless: Excluding development dependencies...

Error --------------------------------------------------

ENOENT: no such file or directory, open 'C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\C'

 For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.

Stack Trace --------------------------------------------

Error: ENOENT: no such file or directory, open 'C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\C'
at Object.fs.openSync (fs.js:646:18)
at Object.fs.readFileSync (fs.js:551:33)
at _.each.configFile (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\serverless-kubeless\lib\helpers.js:31:43)
at arrayEach (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\lodash\lodash.js:537:11)
at Function.forEach (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\lodash\lodash.js:9359:14)
at Object.loadKubeConfig (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\serverless-kubeless\lib\helpers.js:30:7)
at new Functions (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\serverless-kubeless\lib\functions.js:29:60)
at _.each (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\serverless-kubeless\lib\deploy.js:294:30)
at arrayEach (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\lodash\lodash.js:537:11)
at Function.forEach (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\lodash\lodash.js:9359:14)
at BbPromise (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\serverless-kubeless\lib\deploy.js:292:7)
at deploy (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\serverless-kubeless\lib\deploy.js:291:10)
at BbPromise.then (C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\node_modules\serverless-kubeless\deploy\kubelessDeploy.js:129:19)
From previous event:
at PluginManager.invoke (C:\Users\myusername\AppData\Roaming\npm\node_modules\serverless\lib\classes\PluginManager.js:368:22)
at PluginManager.run (C:\Users\myusername\AppData\Roaming\npm\node_modules\serverless\lib\classes\PluginManager.js:399:17)
at variables.populateService.then (C:\Users\myusername\AppData\Roaming\npm\node_modules\serverless\lib\Serverless.js:102:33)
at runCallback (timers.js:789:20)
at tryOnImmediate (timers.js:751:5)
at processImmediate [as _immediateCallback] (timers.js:722:5)
From previous event:
at Serverless.run (C:\Users\myusername\AppData\Roaming\npm\node_modules\serverless\lib\Serverless.js:89:74)
at serverless.init.then (C:\Users\myusername\AppData\Roaming\npm\node_modules\serverless\bin\serverless:42:50)
at

Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Forums: forum.serverless.com
Chat: gitter.im/serverless/serverless

Your Environment Information -----------------------------
OS: win32
Node Version: 8.9.3
Serverless Version: 1.25.0

Error says

Error: ENOENT: no such file or directory, open 'C:\Users\myusername\workspace\serverless-kubeless\examples\get-python\C'

But there is no directory with name "\C" under cloned example "serverless-kubeless\examples\get-python" directory.

I am using Kubeless version v0.3.1 on Kubernetes. Everything works fine if I directly create functions on Kubeless.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.