 Hello everyone. So probably my first time to this meetup group. Lovely to see you all after your work, tired and come to your listen to my talk. So this is what I'm going to talk today. So this is going to be a talk on Knative. So if you want to go for the slides which I'm going to share today. So those are available here right there. You can pull the slides from there. And you can also reach out to my social handles. This is my email on my Twitter handle. So if you have any questions after the session or anytime you want to reach out to me on any technical stuff related to Knative or Java anything please feel to drop a note to me. All right. So I'm not going to go through all the slides today. So what it will do is like have a lot of demo lined up. So I'll show you demos how we actually works in the real environment. And then probably the slides are public as I told you so you can just grab the slides and follow it up again. All right. So this is what I work for in Red Hat. So I work for an entity within Red Hat called as Red Hat developers. So we kind of talk to developers meet the community talk about the good things we are doing in upstream and then Java and all these stuff. And then we actually have lots and lots of contents as well available here where you can go and grab this content as well. So we write blogs. We have live webinars. Probably the right now the webinars are running in US East time zone every fortnightly which is called as Dev Nation Live. It's as a YouTube channel as well. So if you want to log into that then once you register that you can access the content offline content of the YouTube videos so that you can see what the content technical content we talk about as well. So this is a little bit about myself. Probably so I'm kind of an active open source contributor to Knative and many shift which is a single node OpenShift cluster. And then I've been contributing to Eclipse J and Fabric platform and all these stuff. And then I was also a creator for Vertex Mem and Plugin. So which is used to run your Vertex applications as well. All right. So the commands I'm going to type today. Don't worry if you miss my commands. So all these resources are there. So the left hand side I have three blogs written last couple of months back. So which talks about Knative build Knative serving each and every building block that we are going to see today. And the right hand side you have the GitHub links where you can go grab those sources the commands which I type today everything is documented there. So it's going to be step by step. We can see and do kind of things. Right. So don't worry about that. You can just look on to what I do so that you can grab your resources later and then start practicing yourself if you wish to. Right. All right. So the one of the fundamental question that you ask yourself before you actually go and say why I need to go to serverless. Right. So this is the fundamental two questions which you need to answer yourself. Whether you want to have an apps in API organizations a static advantage for your organization or you regard it as a cost center. For example, like most of the high D centers here which lives in Singapore. Most of them are cost centers where they want to cut costs rather than build anything like you're going to be an app or API serving that's been done here. Right. So today probably what I'll touch upon is that I'll see how we can use Knative to kind of reduce your costs rather than the other one like building an apps in API as well. Right. This is a fair bit of definition, the formal definition of a serverless computing. So probably I'll skip this for now. I can just read it offline. Just just definition officially from CNCF, a cloud netting computing foundation. So one thing which I want to burst in this session is probably like when you took Knative, Knative or serverless. I would rather I call serverless when you to serverless. Then imagine that serverless is not that I don't have servers. Right. This is a myth, which people say, look, if you have serverless, there is no servers. Right. It's nothing like that. So there are servers. One thing which we do is right when it has a servers. So we make a physical boxes running on operating system, but they're on demand. So that's what we mean to say, right. Whenever I need to scale up, scale down, so it comes up and goes out go down automatically. So that's what serverless means. Still, I have a probably I might be having an AWS cloud or a Google cloud and have VMs deployed there. Applications deployed there, but the applications will not be running 24 cross seven. That's what I mean to say. Suddenly, for example, let's imagine a simple case. I have a cron job to run. So what happens? A cron job starts at 12 o'clock in the night and then it gets over at 12.5 in the night. So I don't want to have the application running 24 cross seven to run this cron job. Instead, what I do is like I bring up the applications and let's say at 1155 run the job at 12. The job gets over 12.5 and then live for five more minutes or something and then bring it down automatically. So these things has to be done automatically. Still, we can do this without Kennedy before Kennedy when serverless was invented were done on manually by the your operational people. They go write some scripts, start the scripts, run it, execute it and bring the scripts down. Right. Somebody was there to do it manually. Now we are trying to do it automated way kind of things. All right. This is short history. Again, I leave this to you for the offline read. I just want to jump into demo as quickly as possible. These are the four silos which I call for why I need to go for serverless. The first thing is agility. The second one is even driven. And the third one is that I want to delegate to focus platform and services to do all the infrastructure related stuff. Rather than I concentrate only on my business stuff rather than doing other stuff. And then I want a consistent scalable operations across multiple applications. Right. So whenever I scale up and scale down, it should be the same way I do for Java. It should be the same way I do for Node. It should be the same way I do for some other technology. Right. And essentially what I do with like I just have resource optimization and cost savings, which is what we are talking about today. I said as I said earlier, I'm going to talk more from the IT cost center side of things. Right. This is what is serverless is going to give you as an immediate benefit for you. All right. So before we get on demo, I just want to give a quick architectural evolution of how the architectures evolved over the period. Like right now, these are the three big architectural styles which we follow. One is service, which is your clients have a model, your monolith applications and all these stuff. And then we have microservices. I'm sorry. And then we have functions. So these are the three different styles of architectural styles that's right now. Any applications could be developed in. What I suggest is that people are seeing IT industry, right? It's quite common, right? So when something new is introduced and hype is created, people say, okay, everybody is going to go for serverless. Right. Everybody is going to go for microservices. Right. With respect to whether it's going to help you or it's not going to help you. I'm not bothered about it. But I said, okay, everybody is doing microservices. I want to do microservices. Everybody is doing serverless. I want to do serverless, right? But still your application might be demanding that you run it as a monolith application, a service typical service-based architecture. You don't need a microservice at all, but still I go with that. So this is what you need to be conscious when you start doing things that way. For example, like when I want to have high control and high complexity, which means that for example, I run a banking application which has confidential data. So I want to have more control on what I do. Then it's preferred that still says monolith application within your data center. Right. And then we have microservices where I want to have single purpose, stateless, no data, stateful status maintained, independently scalable and automated. Then I can go with microservices-based architecture. Right. And when I want something to be single action and ephemeral, then by default, go to functions. So these are the three different architectural styles which we can follow. These are not the only use cases, but I'm just giving you the points, which means that it goes from high control, high complexity to low control and productivity. And then we have to stay in between if you want to have more productivity across. Right. Great. So this is something good and bad about serverless. I think probably the good one, which is big delivery speed, quicker and easier development, automatic cost reduction, etc. The only thing is that still it's a measuring technology. So there might not be debugging tools. There might not be monitoring tools. Right now, for example, like if you want to put serverless into production, there are only three, two ways probably. One is AWS Lambda, otherwise I have to go Azure functions. Right. There is no other way by which I can take these and deploy. So though the Canadian platform is still under development, it's not completely done. So we cannot rely that for the production deployments. Right. And then again, that's what I mean by vendor locking there. So you have to stick to one of the vendors probably end of the day. So you cannot use different vendors for different things. Okay. So before we go further, so what I'd love to show you is like a quick demo. Let me try to see. Okay. This is I have my application. Is that visible or you want me to increase this? This okay. So I have one VM. It's all in one OpenShift instance running in Google Cloud. This is my OpenShift application console. How many of you know about OpenShift? Kubernetes. I don't want the Red Haters out there. So okay. So two guys. Okay. So OpenShift is nothing but your enterprise Kubernetes. So if your enterprise Kubernetes platform that can be deployed within your enterprises. So because you can take Kubernetes, I can take Kubernetes and run it on on premises. But in case if you are stuck with an enterprise, which is not an IT shop, then you might need to know how to crack the bugs, how to fix the bugs and how to rerun this. That's where OpenShift comes in picture. So it's kind of an open source enterprise Kubernetes you can take and then it has packed a lot of enterprise features. And as you know that we are the biggest contributors back to upstream Kubernetes. So we are also leading 15 out of 21 SIGs that's part of the Kubernetes group as well. And then we do a lot of other things around Kubernetes. So you can trust this platform. So this is a platform that you can take your application and deploy it in production. All right. So it's nothing but I'm going to run all Kubernetes kubectl commands. If you're aware of Kubernetes, it's all going to be kubectl commands that I'm going to run. But it's going to get executed on OpenShift, which means that it's still the underlying platform is Kubernetes for you. So whatever you can do in Kubernetes, you can do with OpenShift as well. All right. So let me quickly jump to the applications. I might need to blow this up as well. Is it okay? Clear? You want me to? Okay. One, two, three, four, five. Hopefully my screen is beginning up to hold this. So the first one I'm just going to do a very simple deployment of a service. So let me quickly open this file for you as well. So this is another one. Yes, this one. So I have a node application. So no big code inside this node app. It's just a typical hello world. We just one have one service touch. Jason's saying hello to you. So the first thing you have to notice about Knative is that Knative uses Kubernetes primitives, which means that if you're aware of how do I write my deployment YAMLs, how do I might my service YAMLs, how do I write any other YAMLs that is part of Kubernetes resource definition. This is, you're going to follow the same steps here as well, but one thing is that the YAML structure is going to change. For example, here in this case, Knative has defined a serving.knative.dev. If people are not aware of what this is, this is called a CRDs in Kubernetes, custom resource definitions, wherein I can define my own controllers, own definitions, own resources within Kubernetes kind of pluggable, so that and then it creates the necessary resources that is required for you. So this is a little bit beyond this particular session, but just remember that these are custom APIs. They are called as CRDs in Kubernetes world. If you go to my blog links, which I said there, I have a link which can take you to CRD if you want to read more about CRDs. But just imagine that these are custom definitions, pluggable APIs and have something called as a service. This is different from Kubernetes service. So this is called a service and then I have given name for the service. What I'm going to do is I have something called as run latest as a spec, which means that at any given point of time, this is going to run you the latest version of the application revision. I'll tell you what is the latest revision in a second. Then it has a template and then it's typically like how do you define your, what do you call it, a port template within a deployment. If you know your port template within a deployment, within this is nothing new for you as well. So let me take the- Is this configuration specific to OpenShift or it works? No, it's nothing to OpenShift. So this is, in fact, it can run even in a normal Kubernetes as well. So if time permits, I'll tell you how we can create a quickly your Kubernetes cluster within GKE. If you have access to Google Cloud, I can show you because that's the most easiest way I have ever seen this. I've taken a simple example rather than the previous one because this is much simpler and cleaner. So if you see this, I have a service. I have a name. I say always run my latest revision because the Knative follows the 12-factor way of creating applications, which means that any change to your configuration is going to spin up a new version. I'll also tell you that. I'll also show you that during my demo. For example, I have an ENV called as message prefix thing hello. In case I'm going to change this to something else, then it's going to change. I'll change this. Once I deploy this application, I'm going to change the environment variable from hello to hi. You'll see that a new revision will be deployed within Knative and then it will always save from the latest revision. If you have time, the last part of the demo, I also have a distribution where I can fit for new revision, 10%, old revision, 20%. I can also jumble between those revisions as well. So I'll come back to that a bit later. Now imagine that run latest says that always run the latest revision. Revision in sense, it's a revision like how do you have in a Git commit. I have a tag, I have a branch. If it's going to be a tag, then I cannot edit it back. If it's going to be a revision, I mean, if it's going to be a branch, then I can go push things into branch. This is similar to a thing in revision is that revision is similar to a Git tag. Once I commit and push it, I cannot change it. And the history is maintained infinitely within Knative so that at any given point of time, I can go to the revision where I want. Let's say I had to deploy revision V1 and V2 into production and I found that revision V2 has some issues. I have to roll back something. That's what 12-factor says that at any given point of time, I have to go back to a last known good configuration. That's why revision does that so that if revision is mutable, then I cannot go back. Somebody will sneak in and then change the code or do something. I cannot go back to the exactly the same thing which is running perfectly before. That was the whole idea, the 12-factor way that I'm going to do this, run latest, run the latest revision of this. So I don't want to jump into the code. The code does not have anything big here. It's just a hello world thing. It's just going to say hello node.js or something. So how do I run this? So I'm going to go to this serving blocks. This is what the YAML I showed you. I say kubectl. I said I'm going to use kubectl only here. So kubectl-f with the file. I say service dot. What I mean by like I just don't worry about what I do in K here. K is nothing but my alias for kubectl. I'm a bit lazy typing the commands. So I just made it. So now I'm going to say kubectl-f. Sorry. kubectl-apply-f. I'm just going to apply the service YAML. The moment I do this, you will see this part is getting created for us. Give me a second. Yeah. You see this created deployment getting created. I'm also seeing that here. The part is getting initialized. If people know about Istio, how many of you know about Istio? Service mesh. So this is backed by Istio. I'm not going to get into that. Just imagine that there is a service mesh which runs behind the scenes. That's the reason why you see three of three parts here instead of one of one, usually which is the one which you've seen here because there are two more parts which is getting deployed behind the scenes. That is for K native infrastructure. So you don't need to worry about what it actually does. There's going to be only one part, which is going to take care of your application. Let me show that in the console. I'll just stop this so that it doesn't do this. So if I get on to this part, so we'll have three containers. There's one in it container, which is an Istio in it container. So don't worry about that. So this is Istio stuff for you. If people are not known to Istio, I think we can just get on to our damnation live. So we had as Istio session earlier on also. So we can just go and see what Istio does. This user container is an app container. So where your app is deployed. For example, in this case, it's going to be a Node.js app which is deployed here. This is kproxy. This kproxy, again, is internally used by K native. So to kind of delegate the request into this particular port, because it's going to be serverless, I keep getting requests to come up and down. The first thing what you're going to do right now, so we saw this, so I said I will go back to this. Just imagine this console is just like instead of me typing the command there, I just have this console here. You'll see this. The revision right now is greater for four zeros followed by one. This is the first revision of your thing. So how do I know the revisions? So what you can do is like K get revisions. Sorry, EI. So since I said it's going to be CRD. So the first thing is the resource name, the followed by serving.knav.dev, which is the API how CRD defines. That's a unique name that CRD gives for you. So when I said K get revisions.serving.knav.dev, it's going to give you what revisions you have now. It might take a few minutes because it has to go to my cloud. So we just have greater four zeros followed by one. That's the first one. So how do I invoke that? So to invoke this, what we need to do is like, so if you let's go to the, in Knative, once you deploy Knative, we have few namespaces created by Knative. Knative build. Knative eventing and Knative serving. So these are the three different namespaces that gets created for three different components, which we'll see right now. We just saw only serving. So what happens is once you go to serving, you'll see a bunch of three other components there. These are the internal Knative components that is created by things deployed. And then let's go to Istio system, which is deployed here. So we'll see a Knative ingress gateway. This is how your request comes inside Kubernetes, right? To a Knative part. I cannot directly call that. I have to go through this Knative ingress gateway. So then only I can go and invoke the pod, all right? So to fund what we'll do is right now. So I'm just going to start to watch. Get pods. Go see. I'll keep watching this. I'm just going to make it aged. Night now is three minutes. By default, it's five minutes plus. For the pods to automatically come down until it doesn't get any request. So what I'm going to do right now is I'm just going to keep it running. So that you'll see the pod getting terminated automatically. But before that, let's give a call. It's going to be curl. So this is a command. 32380 is my node port inside my service, ingress gateway service. I don't have a load balancer or domain name attached. So what I'm kind of mimicking the domain name, for example, greeter.myproject.example.com. That's a service name that gets automatically created when you deploy a service. And obviously, the example.com is kind of configurable. I can change if you are in real infrastructure. I can say, okay, I want to have something like redhat.com. Then I can go change that to redhat.com as well. So for now, by default, it's example.com. The name goes like the service name, the namespace name, followed by your domain suffix. So that you can have a wildcard pattern inside your DNS server so that the request comes inside this automatically. And if I'm here, I'm just kind of sending this header so that my request goes through. This is what I did. And then I got allow node.js given to you right now. So now what I'm going to do is, as I said earlier, so I'm just going to change this service to say hi. Instead of hello, I'm changing the value, which means that my environment value has changed. Technically, aspect 12 factor, what I'm supposed to do is like this needs to have a redeployment done. So what I'm going to do, go ahead, and then let me stop this for a second. And then kapply-nushf. You see the services configured. And then now if you go back to my project here, we'll have the next revision automatically deployed for you. So this revision, let's keep watching this as it get automatically died in a few minutes because by default, I have one more demo where I'll show you how to change the value. By default, it's five minutes. And this one is up. Since we are given run latest, so what happens? I'm going to fire the same request again. I've not changed anything here. So the previous one was hello, Node.js for you. Now when I say this, this is hi, Node.js for you. It's not going to the old service. The old service is still running. So let's try to see if the service is still running. Watch ports. Both of them are running. But what I've said in my configuration when I deployed my service in the Knative configuration, I said that do latest, means that run the latest revision of the code, which is 002. 002. That's the reason why you get the response back as hi instead of hello. The previous one was hello. After that, it was hi. All right? Cool. So I wanted to die before I can give the next demo where it's going to do this separate stuff. Also going to do is like in the last part of the demo. I'm also going to show you like how we can right now I deployed as a single service. Instead of that, I can deploy configuration separately, service separately, routes separately, in fact, not service. And then I can kind of make it link and work together where we can do the distribution. So I allow it to die. After that, like I'll kind of show you, which means that I have to leave it for some time without any request, nothing happening to this. By the time it does that, then it automatically dies. While it does, what I'm going to show you is like I'm just going to show you the other stuff which you have so that we can walk through some of the slides while it dies. And then I'll show you an example of how we can reconfigure that so that it can also do auto-scaling. Automatically, it scales to any number of requests and then come down automatically. Sorry? Yes, that's what I'm going to do next because I want the other parts to die so that you really know the difference. Otherwise, you'll not know the difference actually. So these are again for offline read. So what I'm going to do right now is jump to the three building blocks. I'm talking about giving you serving. The serving imagine is typically like your service, my Kubernetes service, plus deployment club together. The biggest advantage in this is that whenever I have to bring down my Kubernetes service, I have to use a replica account, scale down to replica 0 or something like that to bring down replicas. But the advantage with serving in Knative is that scale down to 0 happens automatically. If you see the block on the top, I execute some code right now. It's scaled down to 0. You'll see that in a few seconds. And then whenever I give the request back, it scales up to 1. And then it goes to 0. Not necessarily to be 1. It could be anything because by default, the concurrency is 100. It can handle 100 requests. One port can handle 100 requests. So if I reduce it down, it automatically scales to number of ports to satisfy that many number of requests. I'm going to mimic that soon. So imagine that it can go up and down automatically for you. I also have another one, another building block which is called as build. So what basically it means that if you remember that you have a Jenkins job, just imagine the scenario. I have a Jenkins job. I push some code into my GitHub. And then automatically the build starts. And then it keeps running. Make the jar a container and deploy that. And then your application is going to use a container. That's the usual thing with Kubernetes as of day. So what we do with build, the same thing right now, but it cannot automatically pull the build for run. There is a pipeline specification which is getting run right now, done right now, which can do that. If you see this picture. So what I'm trying to do, I'm creating a build. A build has a template. I'll come back to that in a second. I'll show you a code. Template means that it's kind of reusable components. And then it defines some parameters, like how your workspace, Jenkins job has some parameters. Similar to that, build has some parameters and it has some steps. For example, I need to check out the code, do a build, push the image into the container, et cetera, et cetera, right? Into registry, I'm sorry. And that's what it does. For example, I can define a build which is kind of inferred from this, refers to a build template. And a build is created. The build is going to pull the resource and it's going to execute step by step. Each step by step that you see here, right there. I'm sorry. Does it come here? No? Yeah. Good. As of now not, because the pipelines are still being developed. So right now, what the problem, what happens is I'll come back to the problem is, once a build has some errors, I have to delete the build again to start it again. The pipelines resource that, I can task a specific task, but it's still getting matured, so I don't have a pipeline demo with me right now. So here I just do a build, then the main build, I'm just going to show you the builds as I'll explain it again. Just remember that step by step 2, step 3 gets executed. Where it infers the steps is from the build templates. It knows which steps needs to be executed. Right now, what happens is for each of these steps, I will have one init container created, right? So which runs the actual code. And then it pushes the images to the container registry and then what happens, whichever service is going to refer to this build, that's going to receive a trigger and then it starts deploying the service automatically for you. Right? I'm going to deploy a Java service not a similar Java service, hello world kind of stuff, but everything is going to be done via this mechanism. Right? So let's do that before I jump to the next part of this. So while this, let's see if this is done. Okay? So only the two days, it's getting terminated right now because it ages five minutes. It crosses age five minutes, now everything is done. Right? So now what happens, see right now we had two deployments, if you remember, service revision one and revision two, right? Now when I scale my service, what happens is that only the latest get scale, it will not scale the older one. Right? So that's what I'm going to show you right now. So I have a script, what I'm going to do is like, in this script, what I'm going to do is like, I'm going to bring down the concurrency to 30. So by default, as I said that 100 requests can be served by a Canadian service and just going to bring it to 30, which means that if I fire 100 requests, I will have at least four pods serving the request for me. Right? Four deployments technically. Right? And then I'm also making this scale threshold to one minute, which means that after one minute, it's just going to watch for the request to come in. If no request come for next 30 seconds, it's going to scale down your deployments. Okay? This is what I mean. So scale to zero threshold and scale to zero grace period. These are the two parameters which you have to change. The threshold means that what is the time when it's under, which as the comment says that, it'll wait for that many number of minutes. Right? Until no request is received, it is scaled on automatically. Right? For a moment, like what happens, once it reaches one minute, it'll also have a grace period of 30 seconds, which means that it will suppose at the 99th or 59th second, you are firing a request. Right? Let's say it takes for 10 more seconds to complete, then it will not shut down at one minute, it'll wait for next 30 seconds more before it gets shut down. That's a grace period that it gives you. Right? So if there is a request that is probably in progress in the 59th second, all right? So it has to finish in the next 30 seconds. Absolutely. Absolutely. That's right. Okay? So that's what I'm going to do right now. So I have a script which actually does this. It's just a kubectl altering a config map. For example, I'll show you the config map as well. So if you go to the Knative serving namespace, config maps, these are the advantages you see with OpenShift, because if you run with the raw Kubernetes to go and see all this stuff, except GKE, it's not possible. But in OpenShift, it'll get you all those resources that you can edit online. Right? So that's what we mean here. If you see this, the concurrency target, this is here. By default, it's 100. Right? And then if you see this, scale to threshold is 5 minutes, scale to grace period is 2 minutes. Right? So this is what I'm going to change right now. This is a default one. So what I'm going to do right now is I just run this script, configure scaling.sh. So if you see this, this is getting changed to 30 now. And then you'll see this to 30 seconds. And this is to 1 minute. Right? Now technically what happens when I'm going to scale, I have a scaling here. I'm done a scale script. If people are not aware of this, so Siege is a tool that can be used to do concurrency testing with Kubernetes. Right? So Siege is a tool that can be used to run Kubernetes concurrency test. So for example, if you see here, what I'm trying to do is like, I'm just going to do one repetition. That's what R means. Right? And then I have a concurrency level of 100, which means that I'm going to pump in 100 requests. And I'm going to go to the same curl URL, which you saw earlier. Right? So if you have a domain name, then you can give the complete domain name, but I'm going to use the same URL again. So let's run this. And we are watching the ports on the right side. Just watch that. So it's now starting to serve. Now what happens is that your port gets up automatically. Now you see this? I got four right now, which is getting automatically for you. And then it's going to go up and then everything is going to serve your request, all the four. And I'll wait for one minute. You'll see automatically coming down. Right? So since this is what auto-scaling is, because right now I configured this, it has to serve all the requests, all the 100 requests. So I can have only concurrency of 30, which means that I should have four pods deployed, four deployments done, so that you can serve 30, 30, 30 on four. Right? Maximum 120 request can be served. And then that's the reason why it's scaled up to four deployments. And then it served the request now. And then if you watch this, I'm right now in 36 seconds. Maybe I have a liberty that I can wait for it to terminate for some time. Right? So while it terminates, probably I can take some questions as well, so that you can see that terminating on life. Right? So any questions? No, it has, it should have Kubernetes platform. Yeah, you can do it. I said, right? I'm not, if you see that I'm not done any OpenShift command here. Right? I've done anything, all Qtl commands, right? I've not done any OpenShift commands. Right? OpenShift I'm using because I get a nice console, Enterprise-ready Kubernetes for you, which can be used for your deployment. Other than that, Kubernetes is nothing new to this. Right? So if you are not an IT shop, tell me that will you be okay to take a Kubernetes, let's say 1.12 and run into some issues, and will you be concentrating on your business, or will you be concentrating on your fixing Kubernetes bugs? That's not your job, right? If I'm going to be a guy like who's going to take care of my business, then I'm not going to worry about what Kubernetes. I'll buy something from Red Hat or IBM or Microsoft or somebody else. Right? And then you start using them. Right? So if you see this now, it's one minute up. So all these spots are getting terminated. And they are gone. Right? If you see technically, if you count after one minute, it will be 30 seconds more because it gives you the grace period of 30 seconds before it actually kills it. Right? So for a fun, what you'll also do is like, let's change this to say technically, I would say I can bring it out to 20, for example. So which means that I should have five deployments. Correct? And then I'm going to configure this again. Now, when I say, Siege 100 now, I should have five deployments created right now for me. That's what it does. Right? So it's, in fact, this is no application. But even in Java also, you'll see that it's not that slow, comparatively both now, now, and no JS, both of them runs in pretty much, but still, you know that enterprise Java apps tend to be a bit slower considering the things. And now we have all the deployments doing their job for you. And again, so why you use OpenShift? It's all because you can go here. I can see this stuff here. Right? These kinds of console, these kinds of parts that I can scale up and scale down here. I can go this deployment. I can go and watch the configuration deployments here. I can watch the configuration. I can watch the environments. I can watch the events. I can change anything on the, on the console. Right? If I'm not a very good Kubernetes CLI user, then this is what is going to be there. Right? And if you imagine that Kubernetes earlier did not have the user thing for, for our backs, but latest Kubernetes versions have our backs for users, which was the one who contributed from OpenShift upstream to Kubernetes. Right? So we do that back to Kubernetes. So it means that, so we are doing a lot of things around Kubernetes. So we have much, much more expertise around Kubernetes than anybody else in the world because we are the, we are the top contributors there, upstream contributors. Yeah. That is, that is what I mentioned by CRD, Custom Resource Definitions. So what happens is that, let's say this Custom Resource Definitions, I'll come back to that in a second. You saw this, right? This is in a serving namespace. Right? So what happens right? If you go to a serving, Kennedy serving namespace, so we have all these parts deployed, activator, autoscaler, controller, and webbook. Right? So the webbook is something, which kinds of looks for the permissions, whether I can go and alter something dynamically, right? By default, all the objects within Kubernetes are immutable. Right? If you want to immute it, then I have to enable the admission controller, which is done by this webbook. Right? Which is by default, enable in this deployment. You have to do that, enable when you deploy K native. And then what this controller will do, the controller will look for these objects, resources being deployed. When I say K, apply this particular service.yaml. So this controller is configured to look for this particular serving. Once it is see this, it reconciles your objects. And if the object is not there, it deploys your new deployment for you. That's what the permission we are given to, to do a new deployment. By default, you cannot do this. That's the admission controller webbook. And OpenShift, as of 3.11, which I'm using, I have to do it manually. Next OpenShift version onwards, it's automatically enabled, because that API has been promoted to from beta to actually live. Okay? So that's what it does. So that's how it knows. Even you can write your own controller. That's what the CRDs are powerful about. Because if you want to write any custom functionality within Kubernetes, you don't need to go touch any of the Kubernetes core sources. Instead, you write CRDs and deploy CRDs. For example, if you heard of a serverless framework called as Cubeless. Cubeless uses CRDs. Okay? It uses CRDs to deploy your functions. It writes the CRDs. And then once it sees functions, it deploys the functions, right? So that's what everybody lays on. So that's what even Kubernetes has relied on. I think, and then if you also see every, for example, even build, build also does the same thing. It has a build controller, build webbook. So when I say something build, I'll show that build in a second. It does the same thing. Same thing with eventing as well. So eventing also does, I don't have a demo today for eventing. But eventing, I can do with Kafka channel sources. It's a little bit complicated. I want to avoid this today. More than that, I don't have a demo running right now. So, right? So, no. So eventing is just like your source. I'll come back to that. I have a diagram which explains that. All right? So right now, if you go back to our namespace, my project where I'm deploying all my apps, everything is dead right now. Okay? So what I'm going to do right now is, I'm going to clean up everything. So, key delete. Okay, one minute. Let me see which project I'm in. Because it's a more dangerous command like your root. Okay? You have to be very careful. Don't use this, please. Otherwise use it, but you know which project you are in. Because I remember multiple times, there is a default project with OpenShift create and OpenShift has all these infrastructure components. So I accidentally went, I was trying to demo, and then I was completing the steps up, and then I went and executed the command. Boom, gone. I have to run my Ansible scripts again to get it deployed. Okay? So just be careful about it. So I'm just cleared it off because I can show you what's the next one is. All right? So let me get back to my slides. Am I on time or? I think I have two more demos to go. I have 22 minutes. I think I'm doing good. Hope my face is not so fast. There might be something which you don't understand, but when you go back and read the blogs and then my repositories, you should be able to recollect it because first time everything looks Greek and Latin to you. We saw the demo. I think we need to see the build demo, right? Okay, let's see that. So let me go to my thing again. So I'm going to do a Java app deployment right now. So I have something called as a build. So just for the sake of faster builds, what I've done is that I did a persistent volume creation so that my PVC is there so that I can cache all my Maven artifacts inside that so that my build is faster, okay? That's what I did. Let me check if I have done that. K get PVC, all right? I have a PVC. The good thing about this again is, again, this is another OpenShift feature. So when I'm on Google Cloud, right? When I create a PVC, then automatically it binds you to the Google persistent disk. When I'm on AWS, it binds you to the AWS EBS volumes. When I'm on Azure, it can create an Azure disk. Those are done automatically by OpenShift when you deploy. So when you specify which cloud you're going to deploy right now, these are the three major clouds which is deployed, supported. Once you say which cloud you're going to deploy, then it automatically creates these configurations for you so that you don't need to do this. In fact, it goes one level up. In this case, I just have only single node where everything is deployed. If you have multiple distribution, then it also creates a load balancer also for you. So you don't need to worry about that as well. So those are something which is automatically read here and it's configurable. There's our Ansible properties. I can configure those properties to make it work. So I've got a PVC here. So let me get K, get build templates. Let me see if I have a build template. I think I created something. I don't have a build template because I cleared everything out. So let's first see what's the build template look like. So this is PVC. Just for storing my Maven artifacts, nothing more than that. I have to go to the templates and Java. How many of you know about Builda? No Red Hatters. So how many of you know that something called as Builda? So Builda is the tool. I could say as a tool. Let me get Builda. So this is a tool which can build. Rather, I can go to this one, which is your Ivo project. It can take you to the... So people know that I can do a build. I need a Docker demo to create a container, right? Container image. So with Builda, what you don't need a Docker container. So it's just like that. I can take an existing container, mount it as a Linux file system, and then copy the files like how you use normal Linux commands and repackage it and push it to your repository. So this is what Builda does. And Builda, in fact, the only thing is that Builda runs only on Linux because obviously I'm going to create only Linux containers. I cannot run it on Windows. I cannot run it on Mac OS. And I have to run it only on Linux system. So it basically creates... You can go read more about Builda here on this site, Builda.io. I think the links are provided in my blogs as well as in my slides. So for example, I'll show you what my script looks like. Before I get down to this, Builda.io search. So I just have a Java... Okay. You see this bash, right? Nothing more than this. There's no Docker commands here, right? It's all typical Linux commands. I have a bash. First thing I'm just assigning, I'm mounting the container, Builda from whichever container you want to mount from. I'm saying mount from Distolus Java. Distolus Java is a very minimalistic image that can run your Java apps. Okay. And once I do this, and then I'm mounting this folder, Java container, which becomes a folder for me, mounted point. And then I'm going to make a DIR. If you see the make DIR, I'm doing it on a mount folder, which means that it creates a deployment folder inside this. And then I'm copying everything from my app workspace. I'll come back to this workspace in a second. Imagine that this is similar to your Builda.io of Jenkins. From there, what I'm trying to do is like, which context DIR, because if you have a multimodal Java project, then I'll have multiple contexts. Target, and then I have a jar name, copying it back to my mount directory deployment jar name. This is what I've created there. I'm just doing a typical Linux copy, making it executable. And then giving some working day or another stuff, which you typically do in a Docker file. And then I'm creating an image by virtue of Builda commit container image name, whatever image name you want, fully qualified image name, with your registry and everything stuff. So with this, I'm pushing it back to my Docker registry. The open shift gives you or Kubernetes, even single node Kubernetes by default gives you a registry. I'm pushing it back to the same registry, the image which I have created. There is no Docker file here. Simple Linux commands, copy paste. So if you want to create containers, this is the most easiest way I've seen. Get into a Linux box, have a real Linux VM, start doing this. So this is what I've done here. So I've created a template of, say, Java Builda, so that I just imagine this. And I have a bunch of parameters, for example, app builder name, which app builder name. In this case, I'm using Maven. So just giving the Maven builder name, there are multiple. So if people are not aware, just search cloud builders. There are a lot of builders available from Google Cloud, so which is used to build a node application, go application, Java application, any kind of application, right? So from that's where I'm taken them. And then I'm giving a jar file name, which I need to give. That's what I'm using there. So if you see this builder image, this is what I use there. This Java name is what the variable I'm using here, right? So all these variables are the environment variables which get pushed inside your script, right? It's available for the script. All these parameters are available for your script as environment variables as well. And then I'm saying that this is my Builda container, which builds my Builda image. So that's what I'm using. This is my custom image. And then what's the image name I need to give? Which context DRS I said. And caching, as I said, I'm mounting a PB so that I need to give which cache volume I need to use for this, right? And with script I need to execute. I just use builder.sh. It could be anything you want, right? That gets automatically executed. If you see this first step, as I said, build has multiple steps. That's what steps means, right? The first step I'm saying, Java builder image, I'm just giving which is Maven. I'm just passing the Maven task, right? Clean package. This is a username for the .m2 folder gets created automatically. And then working DR, this is what the works by default. Your Knative build mounts a volume called a slash workspace. So where all the Builda artifacts are stored, right? When you check out your code, your code is there in a slash workspace, like your Builda of your Jenkins job, right? It's quite similar to that. And then I'm giving a mount volume. If you see, I'll come back to this. Just remember this M2 cache name. I'm just mounting the M2 directory so that my build artifacts are cache so that it's faster, quicker. And then finally, I do the third step. The third step, what I mean after building the app, the second step I do is like push this app into my registry, right? I execute this container and build image and just passing all these parameters which will be needed inside my Builda script, all right? Once it is done, for now I just use an empty DR volume. Let's go back to my service here. Service Java. I said from where I need to check out the source. I'm using a service account here. Obviously you need a service account in case you want to pass secrets. For example, if you're using a private repository, then you want to pass a secret. Then you need to use a service account. So by default here, there's all public repository. But still I use a service account here because OpenShift has some restrictions. Not anybody can push image into registry. So the guys, the account service account should have permissions to push it into registry. This is not available in Rock Kubernetes again. If you're deploying Rock Kubernetes, anybody can push to the default registry, right? So this is something which OpenShift gives you a lot of things on restrictions, which you call SECs, security context. So that is what OpenShift brings as an enterprise feature again for you, right? And then I'm giving an image name, obviously. And then I'm just saying which context DR, for example, I have two directories here. I say go to part one into Java, right? When I check the code, it checks this particular code, something like how we typically do in Jenkins, right? Jenkins also I give a context DR, right? Which from where I need to start running the build. I do the exactly the same thing here, and then I have the cache directory. I map it to the PV volume, right? If you see here, there's a PV volume, which gets PVC, right? M2 cache is a PV volume that gets mapped to this. And don't worry about the sanitation. This is just internal OpenShift stuff. And then I'm using this Docker registry, blah, blah, blah, this particular image, right? Which is where we push the image back, right? So this does end-to-end, right? I have to only code, push it to my GitHub reference, push it to my GitHub reference tree, and then the image starts getting built once I start the build, and then the image gets pushed, so it gets deployed automatically, right? Right now, as you saw earlier, so we're still watching this folder. I don't have anything right now, right? So what I'm going to do right now is, okay, I'll get back to this. This is the one which I need. Let's say K get pods for convenience. I'm going to cd.dot serving blogs, part 2 build templates, right? First thing I have to do is I have to create a template, all right? Let's do that first. K apply-f template, okay? It's Java template. I have one more for Node as well if you're interested in Node. So the template gets created for you. So let's see how we know this. The one of the advantages, the CRD is that the moment you deploy the CRDs, I can look up like any of the get pods or get resources or get services for even for your thing, for your, what do you call it? CRDs, I'm sorry. So build templates is what I deployed. When I say build templates, right now I get the candidate build template for me, Java builder. This is ready for me, all right? So now it's time that I go back out and then one more level up. I just see LS. I just go to Java. I said I'm going to do a Java deployment and then say K apply-f service.yaml. Oh my God. I'm sorry. I need to go one level up. CD dot dot K apply-f service. What is that? Part two services, okay? I need to go to build, right? I'm sorry. I was in a different directory, but don't worry, all are same. I need to go to the build blogs, K native build blogs part one, right? Yeah, there I have. So don't worry about templates. Templates are both on both these things. It's exactly the same order deployed. I say K applied a chef, right? Service Java dot yaml. The moment I see, you see this, there is four in it containers that get created. Okay, how do I watch? I'll introduce you to a new tool, Kale, Kubernetes tail, pod, and I give the pod name, and it takes some time for it to refresh, start reading this. So you see this Git source getting cloned. That's a build step, dash Git source, that's the first step, that's getting executed. So you'll see this, I think you'll see this build container is changing up for you, and then now it starts to do the mounting of volumes and then start to do your build as well, right? Hopefully, I think we have changed the native thing and hope it gets completed within one minute. Otherwise, I have to go change this again, right? So you see this map, a Maven build being done for you. So this is, if you see this build step, build app, that's what you see, right? The other way to see this is pretty easy. All right, let's go here. K, Git, pods, I don't know. So what's the other way you see? It's like, let me copy this. I can say K is one way, it's easiest way. Cube cuttle, K logs, dash dash gritter, dash C, which is a container name, okay? This is the other way to see it, right? So I have to give a pod name, dash C, the container name, right? Rather than that, you can use K, K has a lot of options as well. I can go to deployment, I can check the deployment, I can do anything what I want. For example, if you see this, the build has been completed right now, okay? So I'm just waiting for the pod to be initialized. I was happy that my demos were working today morning. So let me see what happened here. Was the build failed for some reason? Is there any build failure? Okay, it's good that something happened and something was completed, but it's not when to the other state. K, Git, pods, okay? Let's delete it again. So that's what I said right now. If we have to delete, I don't have any other way I have to delete the service and come back again. That's the limitation right now. So I just say K, delete, dash F, service Java, dot YAML, so that you'll see this K, Git, pods, dash W. So you don't have any pods right now. I'll just go K, apply, dash F, service Java, YAML, have this created, and K, I'll see what's the problem. Debugging is a little bit difficult with this kind of thing. I think they are doing away with the need containers soon. So it should be much easier in the next release of the spec. That's going to be much easier for you to find out and read this, right? So let me see, is there any network latency or something? I don't know what happened. Why, after successful completion, I did not see that image getting in. Yeah. That's what I think it should create a container automatically for you. For some reason, I don't know why the container was not created. The build app is being done right here. It's copying the blob. It's downloading the image and then copying the blob, storing the signatures. It's supposed to push now. It's committing the Java image and then storing signatures and then copying the blob. I think build up pushes happening here. Let me see what happens here. It's supposed to push a suppose to get happen and done. Let me see K get evens successfully pushed. The moment is pushed. I think you'll see this happening right now. The build is completed. Okay. Creator resource has failed. I think I don't know what's the reason. Let's find out what's the reason for that. K get ksvc. Ksvc is a committed service. I think it failed. Revision is missing. K get parts. Describe ksvc greater. Got doc registry. Oh my God. I'm sorry. It's my mistake. Signed by unknown authority. Doc or doc registry. Certificate.com. I think it should go with the CTPS. I don't know why suddenly it's failing. So that's the reason if you see that I had an annotation here. Image policy just to say that it resolves every name so that it doesn't fail the image policy. Maybe I would have missed some steps from my thing. I'm just going to my GitHub. Where I have everything here. It's a build blocks where I went in there. Probably I might have missed adding this doc registry to the. I need to add this to the Knative by default has a set of registries. In this case I'm using an internal registry so I have to go tell Knative that ignore this registry for any TLS checks. That is something which I have to tell. Otherwise it will always check for TLS. What has happened in our case as well. So what I'm going to do is like it's good that it happened. So I have to go skip this registry. So let's first get this YAML and see what happened here. So this is config controller. Let's go to console. Go to our Knative serving. Config maps. Config controller. And we have this. So I don't have the registry added here. So because of this what's happened is that I have to make this registry again. So I have to add the... So by default what happens? So if you have the fully qualified name, for example docker.io slash something slash jboss slash jboss EAP. So we have the fully qualified name. Knative expects the fully qualified name for every of your service. And since we're doing a local development we cannot have the complete registry name. We'll keep pushing everything. And then that's the reason why by default ko.local and dev.local has been excluded. So anything you say dev.local slash greeter, for example, right? Then that image will not be checked for TLS checks, right? And also it uses SHA algorithms. Q, if you see this image. So it's not the latest or not the tag. It uses the SHA, which is more secured. So that's the reason why it always supports only v2 versions of the docker registry, right? All right, so let's do this. So how do I do that? So I have the commands again on my blog. I mean on my GitHub repo. So I'm just going to edit this, okay? So let's go back here, okay? So what I'm going to do is I'm just going to apply this again. So if you see this, now I'm doing an OC apply. So as I said earlier, I'm using kubectl and OC. OC is OpenShift client interchangeably, right? OpenShift client has Kubernetes, everything related to Kubernetes plus OpenShift specific objects. All right, I applied this now. So let's go back to my console to see what happens to this. Now I have my docker registry added here, right? Regidockerregister.default.svc added here so that my TLS checks will not be done right now. All right, so how do we go back again? So let's go back again to my project, all right? And then I say I have to obviously delete this. I'm sorry about that. Okay, delete. Okay, get parts again. Then kapply-f.service.java.yaml. All right, so you'll see that getting created. Let's see what happens now. kll-part. Short piece and short form of that, but all right? So you got the problem right now. So I did not do the TLS checks. So because of that, the image was not pushed into my, because it has a custom-generated certificate, so it ignores OpenShift does not allow you to do this. So that's what has happened right now. I'm doing the build again. So as I said, as a recap, so we have to kind of do a delete and create the build again right now because for the current spec, if you use a pipeline, then you can stop and start a task. There will be multiple tasks. I can stop and task a specific task so that it runs again like how we do in a Jenkins pipeline, right? But pipeline builds are not really matured enough. So I did not have a pipeline demo. Maybe next time I could do that. Let's see if the blob is getting pushed properly this time. I hope it does. It's copying the blob. Let's see if it's getting pushed. Push, push, push, push. All right, successfully pushed. And you see the deployment getting created for you, right? So this time we are through. So it's the same app. Everything is the same. Everything is the same. I'm just going to do curl, same call command. For convenience, I had everything as greeter. So it's easier. That's the reason why I have to delete the older one. Now you should guess Java, right? It says Java. That's where we are deployed the app from. Now we did from end to end, right? From end to end build to deployment, all right? Let me do a time check of how much time I have. I just have 10 seconds maybe, all right? So remind me doing one more demo or we are good. Maybe I need it. It's one hour, probably close to one hour. Yeah, I can ask the questions. Probably I can stop with my demo as of now. I have one more demo to show you, but maybe that will take a few more minutes. So I just want to respect your time as well. That's on distribution of traffic between various revisions of your services so that I can have multiple services, revisions deployed. And then I have to, I can jumble with the services deployments as well. I can change how many percentages to go to one, how much percentages goes to two. Okay, so all right. But it takes, maybe it might take 10 minutes or so, if that's okay. Fine, okay. So let me clear this off first. Okay, delete all. Okay, so I deleted everything. So let me go to the serving blogs, cd dot dot. Again, if you missed, don't worry. So everything is there in my repository. All right, so the first thing, what I'm going to show you now is like, so I have two revisions basically to deploy. For example, I'll have Java. This is blog serving part one, right? I'll go to part two. I have config, I have Java. So if you see in the earlier stuff which you have seen, so we had something called a service, right? Service internally creates configuration, internally create routes. Everything done automatically with one holistic object, right? But now in this case, I'm going to do split things up, right? I'm going to do a configuration first, right? Which is again created by service automatically. And then saying which are the things I have a build. I have a combination of everything. This is a little bit complicated to read. But imagine that it has a build component, the same build which you used. And I have a revision template where I have deployed my image. And I also have one more revision. Service one minute. Let me see if I have that as well. I have a revision one. I have a revision two, right? It's going to have just one thing, same image. But only thing is that I have the prefix here, right? So which means that when I deploy this, it's going to create a new revision, all right? So there's going to be two revisions of the same service that is running for you, right? So let's do that quickly as well. So I'm going to go back here. I need to create the bell K, apply, dash F, build template. I could have had the service earlier. So I don't know why I deleted this, okay? All right? So now I'm going to go to config, K, apply, Chef, service, Java, configuration one, dot yama, okay? So if you see K get parts, let's wait for the parts to come. It's going to be similar thing. It's just going to do the same build again, take it all the stuff here, right? While it does the build, so we have one more thing called as routes, right? That's where my application actually reaches inside. So I have a route here. So I'll just show you some examples. This permutation combination which you can show here. I'll take one example here. This is an example where I have a route. I say I have two revisions, greater one and greater two, which is going to be created now. I say that distribute the traffic 75% to V1 and 25% to V2. So when I start pulling it, you will see that there will be a lot of requests going into V1 and V2, right? And it's going to happen dynamically. I'm going to change couple of rules. You can try it by yourself. It will show you like how it can kind of change your rules dynamically without redeployment, okay? Yes, it creates an Istio route behind the scenes. So I'm not touching Istio right now because that digress, that complete topic over to something else, right? So I'm just keeping Istio behind the scenes. So let's see what happened, all right? So you need three, four. Come on, buddy. Make it fast. Okay, it's pushed. So you should see redeployment happening right now. So what I'm going to do right now is I just also do K applied as Chef, Java, okay, this is in build. I just need to do, okay? I'm just going to do the revision two as well. So once I do this, okay, what we have right now, K get pod slash W. So you'll have two deployments right now running for us, right? So I'll just do the first service, what I could call as K, I'll just go one step again. I'll just do the default route K apply, that's cd K apply dash F, routes dash out default, okay? Because without route I cannot reach anything, right? And then bin I say call.sh, right? It's going to keep repeating. This is going to loop for quite some time. Let me see if I have the right thing right there, okay? So let me go here because I keep changing my demo. This time it's on the thing. I just going to be curl my greater dot. So this is going to be one, one, four, I guess, okay? It should come up right now. So because it's done, so it's dead because we have lost 30 seconds. Okay, let's see what happens here. So what is my IP address for this? Okay, it's 25, I'm sorry. So we'll see this, both of these parts come up in a second. Come on, yeah, you see this? So now both of my deployments are coming up. I think it's probably the run latest is a default. So it obviously goes to the run latest one for doing the default one. So let's also keep changing. So keep getting this, just watch this. So what I'm going to do is like, I'm just going to change CD routes. So one is hello, KNATO OpenShift and then that's as latest revision, which is what we have seen. We have passed environment variable called as hello. Right now I'm going to say that pass everything to revision two, right? K apply, if you see that it's going to be applied as chef. Right now what happens is a new part getting created for you. The revision one, revision two, it's all revision two right now. I'm going to change to all to revision one. So now the revision one is getting deployed because it was not running earlier because always it was going to revision two only, which is the latest. So now it's changing now. Now if you see this, if you see on the right-hand side of the stuff, like you'll see, you'll start to see Java KNATIVE, which is revision one, and then there is no hello, right? So let's come back to again. So just to say revision one, rev one dash 50-50, let's put. I'm just going to do this 50-50 now. Now we'll start to see that you'll get hello, couple of followers, couple of Java, not exactly 50-50, but if you see the overall concurrency distribution, you'll start to see 50-50 again, right? So you'll see all these things again. And then again, again, what I'm going to do quickly is like, I'm just going to say, okay, do more of this, of revision one than revision two. And I'm just going to say this 90% of revision one and 10% of revision two. And then once you see this, so we'll start to see this thing more of Java thing coming here than KNATIVE. Once in a blue moon, you get hello, which is revision two, and rest of all comes to Java, right? In this way, I'm kind of shifting even the serverless way of distributing your application, right? Serverless way of making your application run as a canary, for example, right? And this is called what I call a serverless canaries. I can make my serverless application do canary distribution as well. I can change anything I want. I did not do any core rate implement. I did not do anything because it's just behind the scenes, which will quickly change the routes for you, all right? Any questions? So I think I'm done with my demo, probably. Thanks for your extra 10 minutes. Probably we lost 10 minutes earlier, right? So I'm just judging my, okay? So let's allow this to die by itself. So any questions? So there's more magic, but I will stop a few of the magic there because this will be over boarded, so, okay? Okay, right now, I think, right now, I don't see any GRPC applications, you can still deploy. No issues because it's backed by Istio routes. It's all routes that you define end of the day. So if it's going to be over HTTP, behind backed by GRPC protocol, then it's doable. But the only biggest thing I see is with the eventing, which I don't have a demo right now in this session. So eventing is what makes you more interesting, right? I can send an event from somewhere. Right now it uses a cloud event. For example, I can create a cloud machine in AWS and get that cloud event passed to GCP, right? And then start doing something on GCP, right? It's a cloud agnostic messages that can be exchanged with metadata that I can use in any of these serverless applications. That's something which is being done. I don't have a demo as well because I was trying to do a streaming with Kafka and other stuff, which makes it more interesting. That goes itself as a separate session because I cannot be clubbed with this. This is very basic. Probably if you're aware with Kubernetes, then it looks like it's very basic, but otherwise a little bit complicated. But end of the day, these are the very fundamental things you need to know, build, serving, all the things. How do you do a build? How do you change your route? What are the ways to deploy an application either completely as service or configuration separately, route separately, right? In this case, we use two approaches. First, we did service completely because we are not creating routes separately. But in the second case, we did two deployments separately, configuration, then added routes to it, right? Any routes we want. So both are the ways as possible, all right? Then I'm kind of done. I think I have probably nothing. I think the slides, you can just see it offline. Anyways, I said about eventing. I just said about cloud events. I said about events. And then you have the things as well right here. And once you register yourself on the first thing I said, you also can download. You saw the developers.data.link. When you go register yourself, you get the free copies of these eBooks. What is one? It's just a new version of this is getting published. And we have one on microservices databases as well, which you can download and see. And then there are also fundamental Kubernetes for jar developers and reactive applications as well, right? So you can also download all these eBooks for free once you kind of go register yourself at developers.reda.com, right? And that's it. And then you can find the link there, the KN and KN serving, where you can find the same deck. I also have something called as a fast tutorial. I need to update that for Knative. And then you can also go to learn.overshift.com slash serverless to do things by yourself without installing anything. Any further questions, obviously can reach out to me. I'm happy to answer your questions. Okay, thank you. Sure, sure. No worries. It's my pleasure. Hey, thanks a lot. Yeah, thanks. No, I was just thinking about the probably the time I have.