vmware-archive / kubeless

Kubernetes Native Serverless Framework
https://kubeless.io
Apache License 2.0
6.87k stars 752 forks source link

Unable to create java functions using yaml specs #878

Closed anishj0shi closed 6 years ago

anishj0shi commented 6 years ago

Is this a BUG REPORT or FEATURE REQUEST?: Not Sure

What happened: I tried deploying a java function using below yaml specification

apiVersion: kubeless.io/v1beta1 kind: Function metadata: name: get-java namespace: playkyma spec: runtime: java1.8 timeout: "180" handler: HelloKubeless.sayHello function-content-type: url+zip function: https://github.com/joshianish/javakubeless/raw/master/kubeless.zip

and my core pod status goes to Crashloopbackoff

What you expected to happen: I expected a successful deployment of a java function as this kind of deployment is poosible with python and nodejs

How to reproduce it (as minimally and precisely as possible): Just Deploy this yaml resource as it is to any kubernetes server and expose an API for HTTP Handling

Anything else we need to know?:

Environment:

andresmgot commented 6 years ago

Hi @joshianish, there are two problems with that YAML definition:

To fix the above you can deploy the following yaml:

apiVersion: kubeless.io/v1beta1
kind: Function
metadata:
  name: get-java
  namespace: default
spec:
  runtime: java1.8
  timeout: "180"
  handler: HelloKubeless.sayHello
  deps: |
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <artifactId>function</artifactId>
      <name>function</name>
      <version>1.0-SNAPSHOT</version>
      <dependencies>
         <dependency>
           <groupId>joda-time</groupId>
           <artifactId>joda-time</artifactId>
           <version>2.9.2</version>
         </dependency>
         <dependency>
           <groupId>io.kubeless</groupId>
           <artifactId>params</artifactId>
           <version>1.0-SNAPSHOT</version>
         </dependency>
      </dependencies>
      <parent>
        <groupId>io.kubeless</groupId>
        <artifactId>kubeless</artifactId>
        <version>1.0-SNAPSHOT</version>
      </parent>
    </project>
  function-content-type: url+text
  function: https://raw.githubusercontent.com/joshianish/javakubeless/master/HelloKubeless.java
anishj0shi commented 6 years ago

Hi @andresmgot

Thank you for such a swift response, I also tried deploying a function using the kubeless cli, unfortunately i noticed that java1.8 runtime isn't available in the server config, is there a documentation which explains getting these runtimes embedded in the kubeless config?

Thanks and Regards, Anish

andresmgot commented 6 years ago

Java should be available since the version 1.0.0-alpha.3 of Kubeless. You can check the available runtimes in the Kubeless configmap:

kubectl get configmaps -n kubeless -o yaml

If you want to install the latest manifest you can execute:

kubectl apply -f https://github.com/kubeless/kubeless/releases/download/v1.0.0-alpha.7/kubeless-v1.0.0-alpha.7.yaml
anishj0shi commented 6 years ago

Thanks Andres

anishj0shi commented 6 years ago

Hello @andresmgot ,

I know its too much to expect from Kubeless, but I'm trying to figure out the feasibility to expose our SDK APIs via Kubeless deployments and I tried deploying a function as below:

apiVersion: kubeless.io/v1beta1
kind: Function
metadata:
  name: get-java
  namespace: stage
spec:
  runtime: java1.8
  timeout: "180"
  handler: HelloKubeless.sayHello
  deps: |
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <artifactId>function</artifactId>
      <name>function</name>
      <version>1.0-SNAPSHOT</version>
      <dependencyManagement>
      <dependencies>
      <dependency>
        <groupId>com.sap.cloud.s4hana</groupId>
        <artifactId>sdk-bom</artifactId>
        <version>2.1.0</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      </dependencies>
      </dependencyManagement>
      <dependencies>
      <dependency>
      <groupId>com.sap.cloud.s4hana</groupId>
      <artifactId>datamodel</artifactId>
      </dependency>
      <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <scope>compile</scope>
      </dependency>
      <dependency>
      <groupId>com.sap.cloud.s4hana.cloudplatform</groupId>
      <artifactId>scp-cf</artifactId>
      </dependency>
      <dependency>
      <groupId>joda-time</groupId>
      <artifactId>joda-time</artifactId>
      <version>2.9.2</version>
      </dependency>
      <dependency>
      <groupId>io.kubeless</groupId>
      <artifactId>params</artifactId>
      <version>1.0-SNAPSHOT</version>
      </dependency>
      </dependencies>
      <parent>
      <groupId>io.kubeless</groupId>
      <artifactId>kubeless</artifactId>
      <version>1.0-SNAPSHOT</version>
      </parent>
      </project>
  function-content-type: text
  function: |
    package io.kubeless;
    import io.kubeless.Event;
    import io.kubeless.Context;
    import com.sap.cloud.sdk.odatav2.connectivity.ODataException;
    import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultBusinessPartnerService;

    public class HelloS4SDK {
      public String sayHello(io.kubeless.Event event, io.kubeless.Context context) {
      try {
      return new DefaultBusinessPartnerService().getAllBusinessPartner().execute().toString();
      } catch (ODataException e) {
      return e.getMessage();

      }}}

but unfortunately pod initializing crashes due to maven build,

containerID: docker://443651b81a2b7acd0ec2c193b4663122b79d7195b00ab4daeeb1ce492e62037d
    image: sha256:7dbba77079fe98b4818d67e3b36170661ee5b0730026aa95848f3b15484036ee
    imageID: docker-pullable://kubeless/java-init@sha256:7e5e4376d3ab76c336d4830c9ed1b7f9407415feca49b8c2bf013e279256878f
    lastState:
      terminated:
        containerID: docker://443651b81a2b7acd0ec2c193b4663122b79d7195b00ab4daeeb1ce492e62037d
        exitCode: 1
        finishedAt: 2018-08-10T06:39:44Z
        message: " 8.0/8.2 MB\rProgress (1): 8.0/8.2 MB\rProgress (1): 8.0/8.2 MB\rProgress
          (1): 8.0/8.2 MB\rProgress (1): 8.0/8.2 MB\rProgress (1): 8.0/8.2 MB\rProgress
          (1): 8.0/8.2 MB\rProgress (1): 8.0/8.2 MB\rProgress (1): 8.0/8.2 MB\rProgress
          (1): 8.0/8.2 MB\rProgress (1): 8.0/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress
          (1): 8.1/8.2 MB\rProgress (1): 8.1/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress
          (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress
          (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress
          (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress
          (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress
          (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress (1): 8.2/8.2 MB\rProgress
          (1): 8.2/8.2 MB\rProgress (1): 8.2 MB    \r                    \rDownloaded
          from central: https://repo.maven.apache.org/maven2/com/sap/cloud/s4hana/datamodel/odata-api/2.1.0/odata-api-2.1.0.jar
          (8.2 MB at 110 kB/s)\n[INFO] \n[INFO] --- maven-resources-plugin:2.6:resources
          (default-resources) @ function ---\n[WARNING] Using platform encoding (UTF-8
          actually) to copy filtered resources, i.e. build is platform dependent!\n[INFO]
          skip non existing resourceDirectory /kubeless/function/src/main/resources\n[INFO]
          \n[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ function
          ---\n[INFO] Changes detected - recompiling the module!\n[WARNING] File encoding
          has not been set, using platform encoding UTF-8, i.e. build is platform
          dependent!\n[INFO] Compiling 2 source files to /k"
        reason: Error
        startedAt: 2018-08-10T06:35:24Z

Is there a way to fix this ?

Regards, Anish

andresmgot commented 6 years ago

Hi, that seems like a maven error while trying to compile the function. I have no experience working with maven but you could debug the compilation locally to obtain more information about why that is crashing. What I recommend you to do is to first edit the deployment that is trying to run your function:

kubectl edit deployment -n stage get-java

There you can edit the initContainer that runs the compilation and change mvn package > /dev/termination-log 2>&1 && mvn install > /dev/termination-log with tail -f /dev/null. That will let the container running indefinitely. After saving the changes you will see the pod running and waiting in the state Init:2/3. Now you can open a shell in the container and debug locally:

kubectl exec -n stage -it <your_pod_name> -c compile sh
/kubeless $
sajit commented 6 years ago

@andresmgot how would I give dependencies for a java function thats packaged through gradle? Is there an example for that? Thank you

sajit commented 6 years ago

Also is there a working example of a java function, or be given some guidance. I want to deploy a function , which is packaged as a zip, its built using grade. [which I guess shouolnt matter , I can still give deps in xml. But this package has multiple classes that the Handler uses. Finally this Handler reads some env variables. Happy to provide more details if my question is unclear

anishj0shi commented 6 years ago

@sajit I'd recommend you to create a Custom Runtime Image for the same,

As Simple Java Functions can be created on kubeless, I'm closing this issue.

andresmgot commented 6 years ago

thanks @joshianish

@sajit you can find an example of how to deploy a java function using gradle here: https://github.com/kubeless/kubeless/tree/master/examples/jvm/java

Hope that helps.

sajit commented 6 years ago

@andresmgot @joshianish Firstly thanks guys. Can you please point out whats wrong with following yaml.? hw:2 is a working docker image i have built locally and trying to deploy the function to minikube. I am able to invoke the jar directly in docker using docker run This is the last docker command CMD ["sh", "-c", "java -jar /home/hw.jar"] and calling docker run works great.

apiVersion: kubeless.io/v1beta1
kind: Function
metadata:
  name: hwjava5
  namespace: smktest1
spec:
  timeout: "180"
  deployment:
    spec:
      template:
        spec:
          containers:
          - image: hw:2
            name: hwjava5-container
            imagePullPolicy: Never
            env:
             - name : FOO
               value : bar
            resources:
              limits:
                cpu: 100m
                memory: 100Mi
              requests:
                cpu: 100m
                memory: 100Mi
kubeless function describe  hwjava5 --namespace smktest1
Name:           hwjava5
Namespace:      smktest1
Handler:
Runtime:
Label:          null
Envvar:         [{"name":"FOO","value":"bar"}]
Memory:         100Mi
Dependencies:
kubeless function ls hwjava5 --namespace smktest1
NAME    NAMESPACE   HANDLER RUNTIME DEPENDENCIES    STATUS
hwjava5 smktest1                                    0/1 NOT READY
andresmgot commented 6 years ago

I see that you are using a custom runtime. We have a bit of documentation about the requirements that a runtime should have. You can find that here: https://kubeless.io/docs/runtimes/#use-a-custom-runtime

For your deployment, you can find more info about what's wrong in the pod logs:

kubectl logs -n smktest1 -l function=hwjava5

This command should show the cause of the error.