serverless / serverless-kubeless

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

Deploy function : Docker image as runtime-image #178

Open aurelienspnll opened 5 years ago

aurelienspnll commented 5 years ago

Hello, I would like to know if it is possible to deploy a function using a Docker image on minikube cluster.

With Kubeless, I was able to do this : kubeless function deploy foo --runtime-image docker_image_foo

What I did not succeed to reproduce with serverless. Here is my serverless.yaml file that I used:

service: myfoo

provider: kubeless

plugins:
  - serverless-kubeless

functions:
  myfoo:
    description: 'My function'
    #handler: not define
    memorySize: 300Mi
    image: docker_image_foo

So I got this error : Serverless: Skipping deployment of myfoo since it doesn't have a handler

Is there a way to not define handler? Is there an equivalent to the kubeless command line above for serverless?

andresmgot commented 5 years ago

Hi @aurelienspnll,

It's true that the plugin has a check to avoid empty handlers but it should not be necessary. You should get the same result if you define something in the handler, it will just be ignored:

functions:
  myfoo:
    description: 'My function'
    handler: "not empty"
    memorySize: 300Mi
    image: docker_image_foo
aurelienspnll commented 5 years ago

Hi @andresmgot,

Thanks for your quick answer. But now I have this error :

if (runtime.match(r.ID)) {
                ^
TypeError: Cannot read property 'match' of undefined

I know it's because I do not set the runtime field but actually, I would like to use a Docker image. How can I do? Sorry for the inconvenience.

andresmgot commented 5 years ago

I see, you may be able to workaround that issue as well if you set a valid runtime (e.g. python2.7). If you are using a prebuilt image that, in theory, should be ignored as well if you don't specify dependencies. Does it work for you if you set a runtime? TBH this plugin is not prepared to use prebuilt images.

aurelienspnll commented 5 years ago
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Unable to find any running pod for announcement-fn. Retrying...
Serverless: Unable to find any running pod for announcement-fn. Retrying...
Serverless: Unable to find any running pod for announcement-fn. Retrying...
Serverless: Unable to find any running pod for announcement-fn. Retrying...
Serverless: Giving up, unable to retrieve the status of the announcement-fn deployment.

That doesn't work either. (By the way announcement-fn = myfoo of previous comments). Anyway, thanks for your help. 😄

andresmgot commented 5 years ago

I see, now the problem is in the back-end. Can you check the logs of the function controller to know what's the issue?

Also, if you are able to deploy the same function with the kubeless cli, can you compare the output of kubectl get function -o yaml <func_name>? (being func_name both the working and failed function). That will give you the reason of the failure as well.

aurelienspnll commented 5 years ago

The problem comes from the handler. When I deploy in this way : kubeless function deploy announcement-fn --runtime-image localhost:5000/al/announcement --env SPRING_KAFKA_BOOTSTRAP_SERVERS='kafka:9092' --memory 300Mi I don't have to specify handler.

Here are the logs of the function-controller :

time="2019-05-03T07:54:23Z" level=info msg="Processing change to Function default/announcement-fn" pkg=function-controller
time="2019-05-03T07:54:23Z" level=info msg="Skipping image-build step for announcement-fn"
time="2019-05-03T07:54:23Z" level=warning msg="Expected non-empty handler and non-empty function content"
time="2019-05-03T07:54:23Z" level=info msg="Processed change to function: default/announcement-fn" pkg=function-controller

As you see I just have a warning for handler.

And here is the function created by Kubeless (obtain with kubectl get function -o yaml announcement-fn) :

apiVersion: kubeless.io/v1beta1
kind: Function
metadata:
  creationTimestamp: "2019-05-03T07:54:23Z"
  finalizers:
  - kubeless.io/function
  generation: 1
  labels:
    created-by: kubeless
    function: announcement-fn
  name: announcement-fn
  namespace: default
  resourceVersion: "3938"
  selfLink: /apis/kubeless.io/v1beta1/namespaces/default/functions/announcement-fn
  uid: aa3733f5-6d78-11e9-8a77-0800279a3ffc
spec:
  checksum: ""
  deployment:
    metadata:
      creationTimestamp: null
    spec:
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
        spec:
          containers:
          - env:
            - name: SPRING_KAFKA_BOOTSTRAP_SERVERS
              value: kafka:9092
            image: localhost:5000/al/announcement
            imagePullPolicy: Always
            name: ""
            resources:
              limits:
                cpu: "0"
                memory: 300Mi
              requests:
                cpu: "0"
                memory: 300Mi
    status: {}
  deps: ""
  function: ""
  function-content-type: ""
  handler: ""
  horizontalPodAutoscaler:
    metadata:
      creationTimestamp: null
    spec:
      maxReplicas: 0
      scaleTargetRef:
        kind: ""
        name: ""
    status:
      conditions: null
      currentMetrics: null
      currentReplicas: 0
      desiredReplicas: 0
  runtime: ""
  service:
    ports:
    - name: http-function-port
      port: 8080
      protocol: TCP
      targetPort: 8080
    selector:
      created-by: kubeless
      function: announcement-fn
    type: ClusterIP
  timeout: "180"

But when I deploy with serverless, I am obliged to declare a handler (As you told me "not empty"). My serverless.yaml file :

service: announcement-fn

provider:
  name: kubeless
  runtime: python2.7

plugins:
  - serverless-kubeless

functions:
  announcement-fn:
    description: 'Announcement function'
    memorySize: 300Mi
    handler: "not empty"
    environment:
      SPRING_KAFKA_BOOTSTRAP_SERVERS: 'kafka:9092'
    image: localhost:5000/al/announcement

Here is the logs of the function-controller after I execute serverless deploy :

time="2019-05-03T08:03:07Z" level=info msg="Processing change to Function default/announcement-fn" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Error processing default/announcement-fn (will retry): failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=info msg="Processing change to Function default/announcement-fn" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Error processing default/announcement-fn (will retry): failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=info msg="Processing change to Function default/announcement-fn" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Error processing default/announcement-fn (will retry): failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=info msg="Processing change to Function default/announcement-fn" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Error processing default/announcement-fn (will retry): failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=info msg="Processing change to Function default/announcement-fn" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Error processing default/announcement-fn (will retry): failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=info msg="Processing change to Function default/announcement-fn" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Function can not be created/updated: failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
time="2019-05-03T08:03:07Z" level=error msg="Error processing default/announcement-fn (giving up): failed: incorrect handler format. It should be module_name.handler_name" pkg=function-controller
ERROR: logging before flag.Parse: E0503 08:03:07.662022       1 function_controller.go:185] failed: incorrect handler format. It should be module_name.handler_name

And to finish the function created by Kubeless :

apiVersion: kubeless.io/v1beta1
kind: Function
metadata:
  annotations:
    kubeless.serverless.com/description: Announcement function
  creationTimestamp: "2019-05-03T08:03:07Z"
  finalizers:
  - kubeless.io/function
  generation: 2
  labels:
    created-by: kubeless
    function: announcement-fn
  name: announcement-fn
  namespace: default
  resourceVersion: "4677"
  selfLink: /apis/kubeless.io/v1beta1/namespaces/default/functions/announcement-fn
  uid: e2c3e3e0-6d79-11e9-8a77-0800279a3ffc
spec:
  checksum: sha256:038cfa6c3ff8dfe61d4ec6c70c10c5d847e67c4aa63a87ef1bb90c0d54176f90
  deployment:
    metadata:
      creationTimestamp: null
    spec:
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
        spec:
          containers:
          - env:
            - name: SPRING_KAFKA_BOOTSTRAP_SERVERS
              value: kafka:9092
            image: localhost:5000/al/announcement
            name: announcement-fn
            resources:
              limits:
                memory: 300Mi
              requests:
                memory: 300Mi
    status: {}
  deps: ""
  function: UEsDBBQACAAIAAAAIQAAAAAAAAAAAAAAAAARAAAAcG [...
a lot of character...] EAABEsAAAAAA==
  function-content-type: base64+zip
  handler: not empty
  horizontalPodAutoscaler:
    metadata:
      creationTimestamp: null
    spec:
      maxReplicas: 0
      scaleTargetRef:
        kind: ""
        name: ""
    status:
      conditions: null
      currentMetrics: null
      currentReplicas: 0
      desiredReplicas: 0
  runtime: python2.7
  service:
    ports:
    - name: http-function-port
      port: 8080
      protocol: TCP
      targetPort: 8080
    selector:
      function: announcement-fn
    type: ClusterIP
  timeout: "180"

So the problem is that with Serverless I can not deploy a function without defining a hander. What poses problem thereafter for Kubeless... 😩

andresmgot commented 5 years ago

I see, the error is actually complaining about the format of the handler so maybe if you try not.empty would work.

In any case, I think it's better if we remove the check for non empty handlers here. Would you mind sending a PR? It should be easy to just remove the condition:

https://github.com/serverless/serverless-kubeless/blob/master/lib/deploy.js#L556