 Hello everybody and thanks for doing this maintainer track. So we're gonna talk really about next 35 minutes. K-name more than just serverless container. My name is Daniel Oh. I'm more than happy to be here in the modeling dissection. I'm also CNCF ambassador. I've been a long time to like a session tracking and then CNCF ambassador and then like a track chair, some of the stuff of CNCF. So today we're gonna have full great speaker from VMware, Marcio and Ivan and from Redhead and then Nina and Lars. Please welcome to our great speaker. Hello everyone. Good to see so many faces here and as excited as we are about K-native. So today we are gonna talk about more than just serverless containers, K-native, why is K-native? And I'm gonna give it to Evan so. So Nina also pointed out that we should give you a little preview of what this is gonna be because there's kind of three different things that we've squeezed into one. So I'm gonna spend five or 10 minutes explaining to you why you might wanna use K-native. Then Lance is gonna show you for five or 10 minutes how you'd use it and how easy it is and then we're gonna spend like the remaining time which I guess is probably about 15 or 20 minutes, answering some questions, either questions that you've got or we've pre-prepared a list if everyone is so floored by our performance. They haven't thought of anything at all to ask. We don't expect that will be the case. We're gonna start with the quintessential question is why is K-native? So Evan, go ahead. Oh, yeah, the next slide. So the question is why do we make K-native? And the really short answer is so you want to deploy a third on K-native. Look at all the stuff you have to learn on the left hand side. If you're building a standard application using best practices, if you're building a 12-factor app, you better understand labels. You better understand services and deployments and pods and containers and ingresses and you probably want a horizontal pod on a scalar and maybe there's a couple other resources in there that we haven't talked about that you're gonna need to understand as a developer. What is, in learning those, you have to push something else out of your brain. That's probably your business domain concepts. The stuff that gives you value. So how can, for these common cases, we make it simple and easy to run a web application and to build event-driven applications because if you go to your Kubernetes toolbox and you're like, where's the event-driven stuff? The answer is it's not in that box. And so K-native gives you that box as well. So talk a little bit about how serving works under the hood to give you basically a magical experience. So if your container speaks HTTP, you can get all these benefits, but you can write less YAML than normal Kubernetes. And if you're wondering how this works under the covers, we work with a variety of different HTTP routers. Istio contour, we have our own one that people wrote to be a really lightweight one that works with K-native. And the Gateway API, we've got decent coverage there as well. So you can swap in whichever HTTP router you want. And then when a request comes in, if there's not enough instances running, we will route requests to the activator, which will basically say, oh, wait just a minute. I'm not gonna answer this HTTP request yet. And it'll turn around real fast and it'll run to the auto-scaler and tell the auto-scaler, hey, we need more capacity. And the auto-scaler will tell the API server, please increase the number of pods. And then a pod will come up and the activator had been sitting there with his request in his hand. He's like, oh yes, I can send this guy over here. And then we'll route the request there and that's what you would call a cold start in the serverless world. And that can happen when you're scaling up from zero. It can also happen if you get a burst of 2,000 requests all at once and you were scaled to five instances. Maybe five instances isn't enough for 2,000 requests. So you can either dump all that load on those instances or you can pause some of those requests and go quick, get some more capacity. And it may be a better choice for your end users to pause things for a little bit, get that extra capacity. Some of the requests flow through on your active ones in the meantime but will limit the number of requests in flight to a user container. That proxy in there is aware of how much, how many concurrent requests you think your container can handle. And then we scale based on that concurrency. You also get stuff like automatic TLS and automatic URL provisioning because this is not the 90s and this stuff should be easy. We've got tools for it. Next slide. So one more. So we're gonna talk about eventing as well. I do interstitials but then I skip over them, I guess. So you wanna be able to build event driven applications too. This is a great way to take existing applications and extend them. There's a pattern that we identified a couple years back that we call publishing your internal monologue. So this is a great way to take an existing application that's maybe, I call it an heirloom app. You've had it for quite a while but it's important to you. Maybe it makes half your revenue. Maybe it's also written in a language that's hard to hire for. Maybe it's hard to extend for other reasons, infrastructurally, architecturally. How can you take those events out of your application? Hey, I added this thing to a cart. I added this other thing to a shopping cart. The shopping cart monolith is huge and enormous. What if I publish all those things going into the cart into an event broker which can route all these different events to the people who are interested in them and they can call back into my API and be like, hey, I saw that this person got these three products in their shopping cart. Let's add a coupon. But now you didn't have to write that in your monolith. You could write it in a little function on the side. Or maybe you want to incorporate infrastructure events. GitHub pull requests or Slack messages or Twilio. You want to get text messages from customers and you want to build that in a microservice way where you don't have to rebuild the integration with Twilio into every single thing that wants to do messaging. Hey, we got this text from a customer. Maybe that triggers three or four different things and they can all trigger independently. An event driven architectures give you tools for that. And again, just like we could plug in a lot of different HTTP routing implementations, we can plug in a lot of different message routing or message persistence implementations, Kafka, Nats, RabbitMQ and so forth. And so you can choose that based on configuration rather than writing a bunch of code that's Kafka specific and then you discover that there's something about Kafka that doesn't work for you. Like maybe you get head of line stalling or something like that. And you want to switch to a different implementation. It'd be really nice if that was like 10 lines of YAML and not like, oh well, we need to build a new ORM layer based off of RabbitMQ instead. And maybe in two different languages because we're a polyglot. 10 lines of YAML sounds real good in exchange. So the last piece that's a big, go ahead, one more. A big piece of Knative is I called it serverless. Everyone thinks of serverless as functions as a service. AWS Lambda popularized this idea. But basically you can take just a little bit of code and Alliance will show you this later and you can write it in your regular language and then we'll wrap an HTTP server around it and we'll turn it into a container and we'll put it up on Knative and you just think about your business logic in there. We were talking earlier about the metacontroller thing. Lance only had to think about the resources that metacontroller did. Didn't have to think about, oh, how do I pick a HTTP stack? How do I make sure that monitoring's in there? How do I make sure that all these other things? We build that logic into the function framework and then we have function frameworks for Quarkus and Spring Boot and Python and Java and go and TypeScript and Node and so forth. And so you can just take one of these off the shelf and start building containers without having to think about it and we've got all the expertise of building containers in there. So you get good strong minimal containers and you don't have to write like a two-stage Docker file for your Node.js stuff and I'm sure that everyone's shedding tears at this point thinking about, oh, but I don't get to write those Docker files anymore. I don't get to write a lot of YAML. Yeah, sometimes Kubernetes is not all about YAML. And so now Lance is gonna put things together with the demo and Marisha's gonna tell you more about what's going on. Yeah, so there was a lightning talk yesterday. I don't know if anybody of you caught it and Lance is gonna do the demo of that exact lightning talk today. So Lance and Maricia, go ahead. Yeah, they wouldn't let me do the actual demo during the lightning talk, I guess, because there's demos are notoriously dangerous. But you prepared for it, right? Yeah, I prepared for it. Okay, so I wanna talk a little bit about what I'm gonna build first and then I'll do it. So basically I'm gonna create a little translation bot that uses a Twitter search camlet from Camelk as an event source. It takes tweets from the Twitter search API, converts those into cloud events, sends them all directly to the Knative event broker. And the event broker has a couple of triggers attached to it. One of them filters on the type of events that are coming from the Twitter search camlet and sends those directly to the translation function. The translation function will respond with a cloud event directly back to the broker and then the broker will send that new event onto a viewer function, which isn't really doing much, just printing it to the screen, printing the cloud event to the screen so that we can see it worked and hopefully it will. So let's see. Okay, so the first thing I wanna do is show you a little bit about what these, do I have this? So we've got a translate function here. Really basic, really simple. This is all of it. You can see it's about less than 40 lines of code. It has a single function in here, some defaults. The first thing it does is it receives a cloud event as part of its invocation. That cloud event has the tweet attached to it in the data field. And then if the tweet is in English, we just return a new cloud event with these defaults with a new cloud event type and source with the text of the tweet itself. If the tweet is not in English, then we call the Google translate API. Translating that, returning the result of that translation as the data field for the new cloud event and the original text is just included as another field on the data. Excuse me. Can I mention something there? Yeah, yeah, please. So Lance is showing a function that he created with a command line tool that it's called funk. And you can run a command. I don't know if you're going to create a new function. I'm not gonna create it. Okay, good stuff. So basically he used the command line tool that it's funk create. And it allows you to choose the language that you want to use in order to create that function. And it will scaffold a function for you in the specified language. You can use some repositories to bring some templates where you can just start off from scaffolding function in the language of your choice that already has some dependencies in it and just bring all the stuff that your company wants for you to use to interact with all the systems. So he's showing already a function that it's already been built and created and coded, right? Yeah, so actually I'll just, if I were to create this function from scratch, I'd do funk create minus L node minus T cloud events and give it a name. L is the language runtime. T is the type of function that we want. It's either cloud events or HTTP by default. But we've already done that. I've already built it and pushed it up to a registry because that takes time and I don't trust the network here. So I'm just gonna do funk deploy and tell it, don't build it, don't push it. And yeah, I'm not in the right directory. Translate, funk deploy. And it'll take just a second. And I can go back over here to my IDE. And I should. When you're switching, let me just mention that basically what that funk deploy is doing is using a project that's called cloud native build packs to transform the source code of the function into a container image. He's not pushing that container image right now, but he already did that before and funk will take care of all of that for you. So if you are logged into a container registry, when you run funk deploy, it's going to build the container image, publish it into a registry and then deploy to the cluster that it's configured to deploy. Right. Very good. Yes. And then we have a viewer function. And let me get back here to my IDE and show you that. The viewer function is even simpler than the translate function. This one is written in go. And this is all of it. It's less than 15 lines of code. Now, of course, it's not really doing anything very interesting. Can I make this bigger so you can see it? It's not really doing a whole lot that's interesting. It's just printing out the cloud event to the console so that we can see that everything worked. So I'll go build this. Do you want to show the funk YAML as well? Maybe. Sorry. Well, wait. After. After. So quick note there as well. So here also the funk create with go in this case for creating that other function. And also now he's also using buildpacks to transform, again, now a function that's written in go into a container image. The nice thing about using buildpacks is that you can create buildpacks to detect what language are you using and then the transformation of that code into a container image, no matter, again, the language that you're using. It's pretty cool because it will allow platform teams, for example, to curate how that process works. So you can include some governance about how you transform source code to container images that your company might require to use certain base layers and different containers and validate security and all that stuff. Yeah, and you can see actually down here, I'm watching the pods of this as I deploy things. And you can see that these functions are spinning up, but then there's no traffic on my cluster. So you can see that they've already terminated as we've been talking. All right, the other piece of the puzzle is that Twitter search camlet. It's just, it's from the camel K project. It's just a bunch of YAML. I've got at the top of that, in that file, all of my private keys, so I'm not gonna show that right now. Just know that if you have your keys and a search term, really all you have to do is fill the blanks in in the YAML file and then use kubectl apply. If you use the word. Again, quick note around that, so he configured a component that goes against the Twitter APIs, fetch tweets, transform those into cloud events, and then it routes those cloud events into the functions that he's deploying. And these components are taking care of doing all the routing and moving and transforming tweets into cloud events. And you can easily do that with camlet in this case. Pretty easy. Configure the credentials and it works. Oh, okay. So, the demo gods hit me. My cluster doesn't have camel K installed. Let's see if I can do that real quick. Let's do it, let's do it. Show all of your credentials. And another thing about functions is that if you provide local developer experience through CLI, you can use it through IDI. We have extensions in VS Code and IntelliJ and you can build it on cluster itself. So you don't need to do it on your local, but all of those things, you're covered. All right. That looks like it might take a little while. Yeah, this is gonna take a little while. And I was all braggy about this working in five minutes. Okay, well, that you saw me deploy a function. You saw me deploy two functions actually. Our functions generally out of the box will just echo the input that they receive. So let me do one more thing and just create another function and see if we can use the funkinvote command to see if it works. Okay, so this I'll just do funk create and we'll do the hello. And then I can do funk deploy. Ooh, hopefully. Yeah. You need to push that one, right? Yeah, I think so. Push it, push it. Okay, so this is gonna take some time. So you talk a little bit. Yeah, I think I just wanted to say something about that. So we are using funk create to create functions. We are using funk deploy to deploy functions into a Kubernetes cluster. But it's also worth mentioning that we have funk run that will actually start the container locally. So it will build the container and it will start the container locally in case that you want to interact with it. As Nina mentioned as well. I was gonna say that and if you wanna test it, we have an invoke functionality which I think Lance is gonna show us. Yeah, I mean I can do that by actually just going to, let me split this screen. You can use the viewer to invoke the viewer, right? Yeah, I think I can just do the viewer. So all those local development and the local testing you can do of your function for your faster iterations, right? So. And to be clear, these Knative functions are locally building a container and then creating a Knative service which you can also, like any container works there, these happen to work well but you can find other ones that work well too. So, and you'll see that each service tells you, he's running the KN service list all my services and they all will tell you what their address is so that you can go and reach them. I mean in this case, you have to be on his machine to reach them because that looks like a local host address. Okay, so we've got a viewer function running from the directory of that function project, I can run Funkinvoke and we can see in the bottom that the function was spun up and then it received the response. Let's see Funkinvoke minus V, there we go. It received the response, hello world. It's basically sending hello world just to test that the function works. So when I do Funkinvoke, the Funk CLI is creating a cloud event, just a synthetic event that it sends directly to the function on the cluster if it happens to be running on the cluster, if it's not running on the cluster, you can run your functions locally so I could run, I could do Funk run here to run and build false. Again, either you can use the language tools that you're using, let's say for example you're using Quarkus or Spring Boot, you can use Maven tools to do the testing but we also provide this functionality of Funk run. There's gonna create a container and test the container on your machine so you don't have that, works on my machine. Something that I wanted to add to that is that the commands that we are showing here to interact, to create and deploy functions are interesting in the sense that you don't actually need to write again any Jammer file or any Docker file like as Evan mentioned but also it provides you a programming model based on functions so when you give these tools to developers, they only need to focus on building very, very focused functions and the tool will take care of the rest. They may need registry auth and a kube config but if you tell them put this file here and put this file there, they don't need to actually understand what a registry is or how Kubernetes works, they just say here's my function, please deploy it and then they get a URL and they can call invoke and stuff like that without having to learn all that stuff and then it's there and they can learn it later when it's convenient, when they need it to debug but it's not like oh well the first thing you need to do is climb the wall that's this tall and after that you're in the garden and it's wonderful, maybe we should put a gate there. Evan I'm gonna take your advice and just show a little bit of the funk.yaml file. These are some of the innards that the funk CLI uses. There's some stuff in here that's kind of interesting that maybe I'll share with you. First of all, we keep a record of what the image is and in fact what the SHA is for the image that's currently deployed so we know if you've changed your source code in any way we can build and push a new image directly. We keep a record of what the invocation format is whether it's just simple HTTP or cloud event. You can also do things like add environment variables and labels and annotations directly to your function using the funk CLI. And you can- So that'll rewrite this file and you don't have to actually read the YAML. You can just- Yeah, yeah actually let me show you this. I can do funk config env's add and it'll ask me what environment variable and I want to add a new one and I'll just give it a specified value. We'll say it's foo and bar and then when I go back to my funk.yaml I should. I'm in the wrong factory. Let's look at it in VI. There we go. So you don't have to directly manipulate the YAML file yourself. But you can if you want to. You can if you want to. If you want to mess it up. Then debug it. Yeah. I only get tabs in there half the time so you know. Sorry? I only get tabs in there half the time so I'm all good. Right. Okay so the demo gods bit us a little bit but I hope that helped you get a sense of the function CLI and how that works and how it ties all of the pieces of Knative together in some way, right? We use cloud events in the functions. We interact directly with the Knative services, creating services from this function code and then of course deal with brokers and triggers and everything else. To mention that we have a couple of examples and I know that Red Hat and Fox here at VMware we are building different examples of more like event based applications using functions, using Knative serving and all that stuff. So if you're interested in that feel free to reach out and we can share. Yeah and we have a slide we'll share about how to reach it and how to join the community in as well but I think with this we can open the floor for questions. That QR code. We didn't get it? I didn't get it. Yeah okay. So I guess we have what about 10 more minutes. Should we open it up for questions? Yeah sounds good. Too fast. Oh thank you. I saw that the CLI builds an image for you. I was wondering if I can set the target for other architectures. So probably you'll be building AMD and I want to run my workloads on ARM for instance so I would be able to configure that. I don't know how you configured that but I know that build packs can build multi-architecture images or presumably for an architecture that's not the one that you're on. It's a wrap around the whole pack. It uses build packs. Is everything that's available on CLI is also available through API because we currently integrate K-Native in our platform. It's a developer build platform. Yes. I suspect that there's some stuff available through the API that may not be exposed on the CLI but there's nothing that's the opposite way. Yeah, we're using the API. Are there known scaling limits? Oh, absolutely. How many transactions per second or operations per second? So those limits are pretty high when we've tested them because in the case where throughput becomes high we actually take the activator completely out of the path and so it looks like your requests come in to your contour or you're a zero or whatever and they go to a pool of backends which looks like Kubernetes in general the way you deploy it. And so I don't have specific scalability numbers but I would guess that 20,000 requests per second on an appropriately sized cluster would work. You can obviously, depending on your Kubernetes cluster like there's limits to how big your Kubernetes cluster can be but there's nothing, we haven't seen substantial scalability limits in terms of a single service throughput. I know the IBM folks gave a really good talk about accommodating many, many tenants on one cluster for IBM code engine. So they run open source Knative with Istio in mesh mode and there's a bunch of tuning that they described in some detail on Monday around tuning the Istio mesh so that it doesn't get angry with you. Service meshes are subtle and quick to anger, like wizards. In terms of cost effectiveness, if you compare it with the clouds itself, what is the threshold after which Knative makes sense versus just using one of the cloud providers because there are a certain number of free triggers that I allowed. Do you want me to take this, sir? Yeah. So I think that's a really hard question to answer because there's so many different variables but a couple of thoughts that I would give you for why I think Knative is a promising place. You've got the strength of Kubernetes underneath. So if you want to do GPU models with acceleration you can get that pretty easily with Knative. You just say request GPU one on the various cloud providers that can be hard to get access to. Similarly, your size of a pod could be enormous if that was the right thing for you. So there's a bunch of capabilities that are different between the two. And also costs, it depends on how well you utilize your cluster because Knative is gonna run on a cluster whereas the cloud provider is gonna use magic. But I also like to tell people that you're one acquisition away from being multi-cloud. But if it is your own cluster, but if it is your own cluster and you are looking for cost effectiveness then I think that's immediate, right? If you are running through Knative services you are only using your resources when they are in action. There is a small overhead for the Knative controllers and potentially the activator. Absolutely, yeah. But overall that is fairly small if you are actually scaling multiple things so that they fill in each other's valleys then you'll tend to win from that. There's also just a ease of mind I don't have to think about and tweak this stuff that pays for it in terms of developer time spent on business problems rather than on playing with Kubernetes. So that was one of my curated questions as well that why do I use Knative if some resources are still running, right? So thank you for answering that already. So this question is on integration. You mentioned like two integration, the cloud events based integration that the HTTP integration also. What are other integrations that kind of come out of the box if I call that way, right? And the second question is like, if it is HTTP integration, what, how much plumbing is taken care of? For example, HTTP connection pooling, right? Do I have to worry about it? Is it like baked into some, you know, boilerplate code or whatever? Thank you. So I feel like I can answer the second question about the connection pooling with a little bit of description of what's going on there. So because the HTTP proxy and the activator are both level seven aware things, they will connection pool between them and all the way to that Qproxy sidecar. And then you've got connections over local host and you can spin up connections over local host and send throughput over local host. It's not free, but it's darn near free. So in terms of connection stuff, we'll wire all the hard parts and then you get the easy part of, you know, oh, I just closed the connection every time and it's fine. Or, you know, I implement pipelining and, because my library does it and I didn't think about turning it off. In terms of integrations, Knative is really focused on having a couple key APIs, cloud events for eventing and particular cloud events over HTTP post. So it's actually, it's HTTP underneath for all of it. And then Knative eventing has all of these event sources like the camel universe and some things that we've built on our own that take things from the outside world and turn them into cloud events that you get posted. Yeah, and the nice thing about that is that you can just rely on HTTP for connecting to all the systems. So you don't need libraries to, for example, send messages or, you know, more like event-based systems. So you can just rely on HTTP, let developers use HTTP for all the communications and it makes it like a little bit easier for developers to start with at least. And we support most of the flavors of HTTP. I'm not sure that we've got HTTP three yet, but we support GRPC, WebSockets, HTTP two, yeah. Let's say your lookup or your function involves doing a lookup against a relational database or something that similarly involves expensive tech, okay. Well, no, I mean, your problem is less that it's tech and more that like my SQL database has connection limits, for example. And if I start up 700 pods against a database that supports 500 connections, I'm gonna have 200 sad pods, right? To some extent, yes, but even if you're running in a function system like Lambda, which I'm familiar with, you're gonna hit that faster just because everything is creating a new connection for every single invocation. So I'm wondering if you have any. So there's two features of Knative that can help you avoid that. One is because we're HTTP native, we have a connection concurrency bound that you can set on the containers and you can set that higher than one. So you can say I handle 20 connections at a time and then I have one connection pooled like connection to my SQL for those 20 requests in flight. Because Lambda's connection concurrency is effectively one always, you can't get as effective pooling. The other thing is that there are tuning knobs so you can say max number of instances is something and then after that, when you cross it, you get errors, but you're gonna get errors anyway and maybe they're cheaper errors. So I'll say that for every request, there is not another function that's gonna handle it, right? The one function that has been deployed in the container is gonna help handle those concurrent requests that the knob that you have set. So after that, you say I have 75% later, I want more so then there will be more. Yeah, I mean we did see the function spin down on when I was watching the pods, but they will, like Naina just said, they'll handle multiple requests. If you've got lots of requests coming in, it's not spinning up a new function for every request, it's spinning up a new pod based on the scaling need, but each pod handles many incoming requests. Can handle. So we do a few things to manage the life cycle for you so you don't have to think about it. So when we determine that we should spin down a pod because let's say you've got 500 requests worth of capacity, concurrent requests worth of capacity and you've got your load of 200. There's this big gap in between. We will start the termination and use termination grace period. We'll start the termination grace period in our own thing and we will not let new connections in but we'll close out the existing one smoothly. So you don't have to think about that type of thing. And we've got one more question back here, it looks like. Yeah, that's not a question. It's just an add on to what Evan said about the cost infliction point. So I think for a single cluster for cost infliction point with K native, you can consume cheaper compute shapes like arm devices and stuff like that in spot instances which will be much more economical than lambda functions and to expand upon what he talked about multi cloud with K native, you can consume the cheapest compute across multiple cloud providers in a federated Kubernetes cluster environment as opposed to being tied down to a single cloud vendor. So those are the two cost base. I think would be very interesting with K native. I think we are at the time. I'm happy to continue the conversation with outside. We can take the conversation outside. And this is how you can get in touch with us all the questions, all the concerns. And if you just want to come and say hi. Thank you everyone. I have a few stickers and they have more stickers downstairs.