vmware-archive / kubeless

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

deploying function using yaml #1083

Closed yvz5 closed 3 years ago

yvz5 commented 4 years ago

Hi there,

I tried creating a function using a yaml file like this:

apiVersion: kubeless.io/v1beta1
kind: Function
metadata:
  name: api-endpoint
spec:  
  deps: "package.json"
  function: "app.js"
  function-content-type: url
  handler: app.app
  runtime: nodejs8
  service:
    metadata:
      annotations:
        service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    ports:
    - name: http-function-port
      port: 80
      protocol: TCP
      targetPort: 80
    selector:
      created-by: kubeless
      function: api-endpoint
    type: LoadBalancer

my function code:

const uuid = require('uuid/v4');
const kafka = require('kafka-node');

// use an env variable for the kafka url
const kafkaClient = new kafka.KafkaClient({ kafkaHost: 'kafka.kubeless:9092' });
const kafkaProducer = new kafka.Producer(kafkaClient);

module.exports = {
    app: function (event, context) {

        return new Promise((resolve, reject) => {
            // check if incoming data is valid
            // if (!event.data.title) {
            //     reject('Missing field: title');
            // } 

            resolve({
                id: uuid(),
                created_at: new Date(),
                data: event.data
            });
        }).then((data_message) => {
            return new Promise((resolve, reject) => {
                kafkaProducer.send([{
                    topic: 'data-arrived',
                    messages: JSON.stringify(data_message),
                    partition: 0
                }],
                (err, data) => {
                    if (err) {
                        reject(err);
                    } else {
                        resolve(data_message);
                    }
                });
            });
        }).then((data_message) => {
            event.extensions.response.statusCode = 201;
            return data_message;
        }).catch((err) => {
            event.extensions.response.statusCode = 400;
            return err;
        });
    }
}

if I use cli to deploy this function, it works perfectly. But if I try kubectl apply -f the pod does not start correctly. Here is the describe from the function pod:

Name:               api-endpoint-7ddf9d6b5c-h2jw2
Namespace:          kubeless
Priority:           0
PriorityClassName:  
Node:               aks-agentpool-27567343-0/10.0.0.35
Start Time:         Tue, 24 Sep 2019 10:28:39 +0200
Labels:             created-by=kubeless
                    function=api-endpoint
                    pod-template-hash=7ddf9d6b5c
Annotations:        kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"kubeless.io/v1beta1","kind":"Function","metadata":{"annotations":{},"name":"api-endpoint","namespace":"kubeless"},"spec":{"...
                    prometheus.io/path: /metrics
                    prometheus.io/port: 80
                    prometheus.io/scrape: true
Status:             Pending
IP:                 10.0.0.45
Controlled By:      ReplicaSet/api-endpoint-7ddf9d6b5c
Init Containers:
  prepare:
    Container ID:  docker://b1c2eefdf192d2320d349203da71986a79d6e03b2f7a5a3ab09eae0af04caa2d
    Image:         kubeless/unzip@sha256:f162c062973cca05459834de6ed14c039d45df8cdb76097f50b028a1621b3697
    Image ID:      docker-pullable://kubeless/unzip@sha256:f162c062973cca05459834de6ed14c039d45df8cdb76097f50b028a1621b3697
    Port:          
    Host Port:     
    Command:
      sh
      -c
    Args:
      curl app.js -L --silent --output /tmp/func.fromurl && cp /tmp/func.fromurl /kubeless/app.js && cp /src/package.json /kubeless
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Error
      Exit Code:    6
      Started:      Tue, 24 Sep 2019 10:34:31 +0200
      Finished:     Tue, 24 Sep 2019 10:34:31 +0200
    Ready:          False
    Restart Count:  6
    Environment:    
    Mounts:
      /kubeless from api-endpoint (rw)
      /src from api-endpoint-deps (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-brz2l (ro)
  install:
    Container ID:  
    Image:         kubeless/nodejs@sha256:5f1e999a1021dfb3d117106d80519a82110bd26a579f067f1ff7127025c90be5
    Image ID:      
    Port:          
    Host Port:     
    Command:
      sh
      -c
    Args:
      echo '7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519  /kubeless/package.json' > /tmp/deps.sha256 && sha256sum -c /tmp/deps.sha256 && /kubeless-npm-install.sh
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
    Restart Count:  0
    Environment:
      KUBELESS_INSTALL_VOLUME:  /kubeless
      KUBELESS_DEPS_FILE:       /kubeless/package.json
    Mounts:
      /kubeless from api-endpoint (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-brz2l (ro)
Containers:
  api-endpoint:
    Container ID:   
    Image:          kubeless/nodejs@sha256:5f1e999a1021dfb3d117106d80519a82110bd26a579f067f1ff7127025c90be5
    Image ID:       
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Waiting
      Reason:       PodInitializing
    Ready:          False
    Restart Count:  0
    Liveness:       http-get http://:80/healthz delay=3s timeout=1s period=30s #success=1 #failure=3
    Environment:
      FUNC_HANDLER:             app
      MOD_NAME:                 app
      FUNC_TIMEOUT:             180
      FUNC_RUNTIME:             nodejs8
      FUNC_MEMORY_LIMIT:        0
      FUNC_PORT:                80
      KUBELESS_INSTALL_VOLUME:  /kubeless
      NODE_PATH:                $(KUBELESS_INSTALL_VOLUME)/node_modules
    Mounts:
      /kubeless from api-endpoint (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-brz2l (ro)
Conditions:
  Type              Status
  Initialized       False 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  api-endpoint:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  
  api-endpoint-deps:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      api-endpoint
    Optional:  false
  default-token-brz2l:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-brz2l
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                    From                               Message
  ----     ------     ----                   ----                               -------
  Normal   Scheduled  6m50s                  default-scheduler                  Successfully assigned kubeless/api-endpoint-7ddf9d6b5c-h2jw2 to aks-agentpool-27567343-0
  Normal   Pulled     5m16s (x5 over 6m48s)  kubelet, aks-agentpool-27567343-0  Container image "kubeless/unzip@sha256:f162c062973cca05459834de6ed14c039d45df8cdb76097f50b028a1621b3697" already present on machine
  Normal   Created    5m11s (x5 over 6m48s)  kubelet, aks-agentpool-27567343-0  Created container
  Normal   Started    5m11s (x5 over 6m48s)  kubelet, aks-agentpool-27567343-0  Started container
  Warning  BackOff    99s (x25 over 6m46s)   kubelet, aks-agentpool-27567343-0  Back-off restarting failed container
andresmgot commented 4 years ago

Hi,

See the documentation for the advanced deployment (using YAML):

https://kubeless.io/docs/advanced-function-deployment/

So far I see a couple of issues with your YAML. function should be the full URL of the function and the type should contain the format (e.g. url+text).

My recommendation for you is to run the kubeless binary with the options --dryrun and -o yaml so you can see a valid YAML and work from there.

yvz5 commented 4 years ago

Hi, I want to create the function from a file. file://app.js or ./app.js did not work. how do I create the function from a local file ?

andresmgot commented 4 years ago

That's not exactly how that works. You can either copy the actual content of your app.js in the function definition or you can set that field to point to an URL. With that info, Kubeless generates the file locally within the Pod.

yvz5 commented 4 years ago

I think thats a bit counter productive. In the end, I would like to control everything. The only way to change the service and deployment is through this yaml file. Putting the function code inside is aweful. if kubeless cli could do this, that would be great. Maybe I ll take a look at the cli

delanni commented 3 years ago

@yvz5 you can do this through templating if you're using this inside helm. But I'm not sure if this is relevant after more than a year

yvz5 commented 3 years ago

@delanni Thanks for your reply but we moved to azure functions because of these limitations.