 Thank you. I'm not going to start yet. We're just trying to get the volume right here. Is that okay? Is that loud enough? Should I get it closer? Can you all hear me? Good? Okay. Thanks, Landon. I'm going to be pressing space and arrows. Yeah. Space arrows. Hand over to me. It's the same. I'll stop there. Yeah, for sure. If you're going to stand over here. I have this question. I can be here when introducing Landon. Stand over here. Is that a few of these arrows? Yeah. You need some press enter because if you want to walk and switch the slides it's... Ah, that's not good. Yeah. There might be some. It's for projects, I guess. If you don't mind, definitely not that much. It's fine. It's fine. You've got laptops. What kind of projects? Just in case. Are you prepared for the adults? I hope so. I think so. It's also 40 minutes. Yeah. Right after my mission. Yeah. I cleaned up my slides and printed out a PDF and put it into the repository. I guess there were two kind of slots, like the long one and the short one and we had the short one because I think Marcel had more than one hour. Oh, wow. I didn't realize that. Okay. I mean, 45 minutes is fine. You can make questions and everything. It's a lot of time. Was there a break in this workshop or were you given my will and something? Yeah, they took like a 5-10 hour break. Just one? I think so. Yeah. I stuck around for the beginning and then I went to do some work on the terrace. Yeah, on the terrace. And I saw that midway through the whole group kind of came outside to get off. On one side or something. Yeah. So I think they took one break after the first hour. It was a little bit of a long time, like three and a half hours. Yeah. So they took like a 5-10 hour break or something. The tough part about taking a break that is like how do you get everybody back in the workshop? People go wandering around. And I just said like, let's meet the year in 5 minutes. Yeah, I know all these people coming outside. Still getting a call? Yeah. They're going to the bathroom. Yeah, for sure. So are you happy with the demo? Did you get a community out there? Yeah, we basically showed what I showed them in the practice talk. Okay. Rafe, I guess. We're here to talk. Yeah. I mean, you said Eric dropped. Eric is a customer towards the end there. He will say like, shit. Really? That'll be good. Yeah. Language. Yeah. Brain half, you know. Language. You can just say this language here. The strange of people at Armandet is figures in English. Consider like swearing in the second language is not swearing. Well, it doesn't have the same kind of way. Yeah. Yeah. Because I see English in all those movies and they use it the more a lot, right? Right. Right. In English, especially, a lot of that stuff has become pretty common. Yeah. Just that much. I mean, what's it like in Czech? Are there swear words that people don't use all the time? Yeah, yeah. Especially in different parts of the cities they use. Oh, really? Different words. Okay. Okay. It's strange that in Poland they use Urla, which is like pretty nasty in our country, but in their country it's like they use it all the time. Really? It's like lose the weight. Inflation. Right. Right. Exactly. Yeah. That's funny. Well, I can imagine too, like from what I understand about Czech and kind of Slavic languages, there's a lot of dominions, right? So I can imagine there's probably tons of swear words that all kind of sound similar, but they have different endings. Is that the case? Yeah. Okay. You can just kind of change it a little bit depending on how you feel over here. That's right. Yeah. But it's interesting that a lot of those swear words are in it, because it's really good. Is that the R with the hook of the word? No, no. It's the one word. Oh, wow. Yeah. We have a zic, something like that. But it's not that common. Okay. Prdl is us. This is nice word. I like prdl. It does sound nice. Prdl, prdl. So what's the R noise? What does that character look like for that? Prdl? Yeah. Prdl. Prdl. Okay. Prdl. And the R and the D, do they have anything? No, no, no. Just without any. Yeah. But see, that's what throws me out. When I see like prdl, it's like that word like prdl. Prdl. Yeah. Stranger. I'm supposed to say the H or what? Like, how do I say, you know, yeah. Oh, and I've added one slide today. It was this one. Just to sum up the demo because... Don't know. You put the brain fuck in there. I was looking for the logo of the language, but apparently it is not. Okay. I think it's like, it simulates the language. If anybody knows it, like, yeah, you know immediately what it is. You know what it is? It's hella low in brain fuck. Hella low. Yeah. I mean, I cannot read very far. I understand it. What it means, but yeah, I can't mentally figure it out. We started in 50 or 40? 40. Yeah, 40. I think it's 50. I don't know. So are you prepared for, like, how hot it's going to be in Washington DC? Yeah, so that's like, yeah, it's pretty hot. I don't know if you know it or not, but Washington DC is basically built on top of a swamp. Uh-huh. So it's really humid down here? It's all the time? Not all the time. Like in the winter time it snows and stuff like that. But in the summertime it gets hot and it gets really humid there too. Because it's warm. Right, because of the swamp. Exactly. Smell it out? No. No. I mean, no more than you ever see. Just cars and stuff like that. But it's, but you won't, you don't know that you're on a swamp. Right? I can't tell. But that, it'll just be really muddy there. It'll be really humid. Oh, Jesus. Yeah, the temperature is pretty high. And if it's cold, so humid, yeah, we'll die. Yes, we'll just, like, spend a lot of time in the museums. They're nice and air-conditioned. Yeah, exactly. But you know, if you want to go see the Washington Monument and stuff like that. It's closed. Oh, it's closed? I saw it in the news in the morning. In the morning? It's on my TV and they said, like, it's very open amounts. What about the Lincoln Memorial? Can you see that? The big statue of Abraham Lincoln? I think so. That's, like, sitting Lincoln, right? Yeah, yeah. I'll check the Capitol. That's a class man, I think. You should be able to, you should be able to see the Washington Monument from there, but maybe you can't go out and see it. The park is pretty huge. Yeah. I don't know if you're allowed to go there, because it's pretty, pretty big. Yeah, these are the points I would like to visit. Yeah, that's fine. And there's a grave of Goura Cordero in Princeton, so I want to take a photo for him. Yeah, this is pretty good, actually. I don't know if people are allowed to go there or walk in the park. Yes, okay. Yeah, yeah. The reflecting pool. You can definitely, you may not be able to get, well, yeah, you go from the Lincoln Memorial, you can walk along, and you'll be able to see the, you know, the memorial there. And there was the scene for his gun, right? Yes, yeah. Yeah, exactly. That's where they had the big rally. And yeah, he comes running across the water. Now, did you, have you read anything about how the streets are laid out? No. Did you look at it? So like, go to where they wind. If you go to where they wind. Hey, not bad. How about yourself? Ah, yeah, pretty much. Okay, cool. We're just goofing around at this point, sorry. You want the light left on for now? You can turn it off, that's fine. Okay. If you see like, if you see how the, how there's like a circle over here and these lines go out and everything. Look on line about conspiracy theories about that. Yeah. Because there's, people say the masons, they, all the guys who founded the city were free masons, right? And so they drew out the lines of the city and people draw like an owl and stuff. Well, if you say the lines make an owl or like a, or like a star shape and stuff like that. So read about it. It's really nice. If you've gone to all the streets, it will get like 660. Right, exactly. Exactly. But if you, if you see like this. Yeah, right, right. And if you look at where the White House is, it's all kind of centered around there. Yeah, so there's, there's the White House and then you see like there's this circle here and you see how like, and then these things go out. And so people have like taken the streets and they, they, they draw lines over it. Here's the owl. It's a lot of crazy. It's fun. It's fun. Turn it off. Oh, so we can have like one, one browser with the presentation and the other one for, because I will need the browser as well. It will be easier to like switch between. Yeah, I won't need to switch it off. So do whatever it's convenient for you. Oh, and Control 5 makes it full screen. If you, if you lost this full screen, Control 5 and Control is FM, I will have to switch it. Okay, okay. So Control 5 makes it full screen. Okay, cool. But if you want to leave the full screen off, you don't have to put like, turn it on again. Yeah. I don't know, I don't know, I swear to God. I think I can switch it to that. 89, man. It's low. It's low level, surely. I'm sure I'm ready to answer that. If so, few left-hand people. I think there are like 17 attendees that confirm that they've moved here. Okay, so, I'm 50% sure. Yeah, I could plan two. What's the, is this the one doing? Do you want to turn on the, to turn on the mirroring or whatever? Yes, it's Control F7. Oh, it doesn't work because it's probably behind. Alright, it's not Control, it's FM, sorry. So, so, it's actually FM. Oh, you switched the button? Yeah, yeah. We can turn it on like this. Okay, so it should be a mirror. Presenter. Yeah. I think I could take my phone. My own and take your phone. I was expecting there will be some. We can ask. Yeah, it's coming down. I'll take your word if you want. In case I get a turn emergency situation. It was my next idea. Turn on the notification. And mode is turning off, I think. See, I used the spreadsheet feature. Lighting. Yeah, yeah. So, it's turning off. Five, six, seven, eight, nine, 10, 11, 19. Oh, yeah, I see. We're doing better. We're all set to get started. Yep, we're all set. Keep going. All right, cool. All right, great. So, my name is Michael McEwen, and I'm joining Yerka Kremser today to talk about polyglot operators and in specific, the spark operator. We're both engineers at Red Hat. This is based on a lot of the work that we've been doing over the last few years. All right, so just a little outline. I'm going to start with kind of a history lesson of how we got here, how we arrived at the operator pattern. Then we'll go into how the operator pattern works and kind of what are the pieces of it. At that point, I'm going to hand it over to Yerka and he's going to talk about the spark operator and how we built it. He'll talk a little bit about an abstract operator library that we've been working on to make these things easier. We'll talk a little bit about different languages that you can write operators in. And then lastly, we'll talk about the OLM, operator lifecycle manager. So to start with, let's just get a quick show of hands. How many people here are familiar with Kubernetes? Okay, so a pretty good chunk of the audience. So I'm not going to go into too deep about Kubernetes, but as most of us know, Kubernetes has all different types of objects in it. These objects represent the resources that exist within a cluster. You have deployments, services, pods. This is just a handful of what's there. And as users, the first patterns that we came across for how you instantiate these objects is making miles of YAML code that you can then inject into your Kubernetes cluster. And this is a portion of a manifest that our team has been working on. And I couldn't, even at 6.font, I can't fit the whole thing on one slide. So this is just obscene, right? Like having to manage something like this. And as a user, the pattern I want to do is I want to take this manifest, I want to tell Kubernetes about it, and then Kubernetes will deploy something for me. Whatever it is I'm trying to do, it will do that. And if I always have to be the one controlling this, it can get very onerous on me to have to continually do this and maintain these manifests, especially when the patterns we use inside the manifest are repeated many times. So early on in the Kubernetes days, there was this idea of what we wanted was a control application that could sit inside of Kubernetes and could do the work of controlling these manifests and creating objects for us. But there's a problem that exists with this. Who's the user who's doing that action? If I run the commands from the command line, I've logged into a cluster that has some sort of authentication on it, and it knows who I am and it allows me to do work. But if I put an application into the cluster, and that application wants to create objects, who is the user who's doing that? Because I'm not logged in at that point, just the application is running. And there's a notion of something called a service account, and this is something that can do work for you inside the cluster. And this is what we used early on to build applications that could do this type of operation. Now, to take things a little further, once we built these control applications, what we wanted was to have other applications that could speak to them and say, I would like some resource to be deployed for me, and I don't want to have to manage the manifest or the objects that are associated with that. I'd like the control application to do it. So now you can imagine we're even one step further removed from what user is running all this. The answer to this came in the form of what we're known as controllers or more recently, operators. So these are kind of the basics of the operator pattern. It gave us a way to extend Kubernetes, so we could start to build custom applications that could control various object life cycles inside Kubernetes. It's also kind of fundamentally tied to the idea of resources and controllers. So in general, a controller is a type of pattern a loop that can watch objects and do things for you. And controller is really the language that is at the heart of this. But where controllers differentiate themselves from operators and an operator is a type of controller, but an operator has the notion of being tied to custom resources, and those custom resources would allow you to describe complex topologies or architectures using something that you can control Now, controllers are able to react on events that occur inside of Kubernetes, and we put crud here, but we kind of crossed out the R because really a controller is watching creation events, it's watching update events, and it's watching deletion events. It's not watching read events because you're not going to watch when everyone's reading an object. It's just out of the scope for what they're doing. And you might see in the Kubernetes documentation these terms get kind of confused sometimes. So if you search for operator, you can find that in the Kubernetes documentation, but you'll also find this term custom controllers. That's another piece of language they use. And a lot of this goes into how these patterns evolved and how they were brought into the Kubernetes community. And this is kind of a historical thing that just has to do with who developed the technology and how these words were differentiated from each other. So in general, and I'm just going to do this from a very high level, I'm not going to get into the internal control loops and whatnot, but this is our pattern. We have an operator that's running that before I might have called the control application, and it wants to tell the Kubernetes API, I want to listen for some sort of resource. And this CRX is, you know, this is our custom resource. This is whatever we've created that we want to monitor. So we tell Kubernetes, all right, I'd like to listen to this object. Especially Kubernetes is just like, yeah, okay, whatever, like, you do you, I'll do me. But what's happening internally in Kubernetes is you set up a watcher so that when Kubernetes gets a new event on the custom resource you're looking for, your operator will get notified about that. And now you can do some sort of action depending on what it is you need to do. So at that point, the operator kind of says, all right, you've asked for some new resource or maybe you've deleted a resource. What do I need to do to clean up for this complex architecture that you've deployed into Kubernetes? And so then the operator can say, all right, well, you know, maybe deploy this many replicas or change the state of something depending on, you know, this would all get into the specifics of what your custom resource was trying to do. Then Kubernetes will say, all right, yeah, you wanted to delete this or maybe a deletion event comes in and Kubernetes is able to inform your operator that, hey, someone just deleted this custom resource that you made, and maybe your custom resource represents several pods and services and your operator can now go through and clean all that stuff up. Like we see, your operator can now send that back. And this is all taking the place of what we used to see in these manifests and running command line operations. This is all happening in the cloud now, so I don't need to be running this from my command line. Now, I mentioned custom resources and this is kind of the representation. This is talking about how we represent these resources. So we create something called a custom resource definition and this is how we inject new object types into Kubernetes. So you saw in the beginning, I had some of the different objects up there, like pods, service, et cetera. In the case of what we're going to talk about specifically, we wanted to make a Spark resource because Spark is a distributed computing platform. It can have many different nodes that get deployed and we wanted one resource to manage that instead of looking at all the different pods that make that up. And so custom resources are what come out of the definition. So once I've defined something, I say I've defined a Spark cluster. Now the custom resource itself is an actual instantiation of that. You know, they bundle in a lot of the same things that you see in the other objects. You can represent the state or the life cycle or what's going on. There's all sorts of information that you can encode in there. Now, the last line here about config maps. You don't have to use custom resource definitions. Those are the most commonly accepted, and I think that's the way you want to extend Kubernetes. But it is possible to create watchers that watch other things. And so config maps are a way to put data into the Kubernetes, you know, store into XCD so Kubernetes can know about it. And you could actually set up a watcher on config maps and have some sort of, you know, complex structure inside there that you could do action on. We have some of that in the abstract operator. And we mainly did it because in platforms like OpenShift where you have a strong role-based authentication set up, creating a custom resource definition is something that only a cluster administrator can do. Whereas a config map, anyone can create one of those. So it makes it much easier for a standard user to come and start, you know, doing whatever activity you'd like them to do. This is a quick example of what a custom resource looks like. This is not the definition. This is actually what the resource would look like. So, you know, you can see we've made a kind here called a Spark cluster. In this case, we're giving it a name. This is for an actual specific deployment. You know, we can tell it how many workers and masters. And this is all specific information to the actual application that we're writing. So, you know, in the case of a Spark cluster, this is information we want to know about. If you were deploying something else, maybe a database of some type or a website or, you know, something along those lines, this information would be specific to whatever it is you're doing basically. So a couple of quick notes here. As I said, custom resource definitions are the main way to extend Kubernetes. This is the community is kind of rallying behind this as the main way to add your own custom extensions into Kubernetes. And then building operators around those. One of the kind of nice things about this is you can imagine the kubectl command, normally when I want to look at an object, I say, you know, kubectl get pods or kubectl get services. It's much nicer if I could say kubectl get Spark cluster and see my Spark cluster as one object as opposed to saying kubectl give me back everything in this project which has all the pods that go with my masters and workers, all the services that are related with them, all the deployments that are associated with that. So you can imagine that for managing these things, it's much easier just to be able to look at one entry than to look at an exploding list of things that make up all the resources. And also, on systems like OpenShift and other distros and vanilla Kubernetes that has RBAC enabled, the role-based authentication, you can now start to put access controls on who can create custom resources. So you can start to get really fine-grained control of how those things can be made. And like I said, in OpenShift, and in other Kubernetes distros where there's a strong role-based authentication, you might be restricted in how many custom resources you can make or how many definitions you can put into the system or even if you can. So it's something to kind of keep in mind as you do this. Now, we might just think, well, all the operator is doing is just deploying manifest for me, right? But it can actually do a lot more than that. And there's a lot of tooling around this, and Yurka's going to talk about some of that tooling, but, you know, manifest are just the beginning. You can use Ansible. There's an Ansible operator where you can just take Ansible playbooks and put all the logic, the conditional and looping logic that goes into those. Those can be encoded inside an operator. If you're familiar with Helm charts, which is a very specific way to deploy things that the Kubernetes community likes, you can also encode those inside of operators, case on it and customize our other methodologies. You can go even further than that and write operators in specific languages, and Yurka's going to show you how we did that with Java. So now we can use Java code to do all sorts of complex tasks that maybe a manifest or an Ansible playbook would not be able to do. Now, this is an example that we pulled out of the O'Reilly Kubernetes patterns book. This is actually Bash. Just to show you how flexible these operators are, this is really all that's happening at the base of an operator. We've got a few pieces up here that's set up kind of how you connect to the Kubernetes cluster. But then all we're doing is setting up a watch and then we just kind of loop continually. And this is what's sometimes referred to as the reconciliation loop. So this loop continually runs, and when new events come in, your application will get notified, that loop will run once every, you know, whatever the cycle you have set up to run on, it will run and see, okay, have new objects been created, is there some work I need to do. So this was just an example to show you really how simply these things can be written. I wouldn't recommend writing them in Bash, but if you feel that way, you could do it. So I'm going to hand it over to Yurka now, and he's going to talk a little bit more about the actual implementation details. Thank you, Mike. First, I'll start the cluster. So thanks for introducing the general information about operators. I will focus more on like one particular instance, which is Spark operator. It's written in Java. For those who don't know Spark, it's a unifying analytics engine for distributed data processing. And this operator supports free custom resources, Spark cluster application, and history server. Spark cluster obviously deploys Spark cluster application. It represents an application that can itself deploy a Spark cluster that's desired or dedicated for this application. And history server is something that can keep track of your running jobs. So it started as a toy project, and now it's adopted by AICOE project called the OpenATAP. And it's compatible with Google's operator on the CRD level. So it's written in different language. It's written in Java. The Google's operator is written in Go. But the CRD's custom resources look the same way. So people can migrate smoothly between those two. Right, so let's look how it looks like. I have the cluster deployed. So first I need to deploy the operator. Is the font visible? So I will show you the manifest of the operator first. It's always Vim, actually. It's a list of yamls that does the deployment of the operator. It contains service account, the role that's assigned for the service account. And the most important part is the deployment where we specify the Docker image or container image that's going to represent the operator. And with this environment variable we are seeing, like, watch in this namespace. Watch for events in this namespace. This convention brought by OLM and also specifying the limits. So let's apply it. I have to look as an admin, sorry. Yeah, because I was required for cluster admin rights because I was also creating CRD's. So now everything passed and I'm watching the pods. So there is a new pod called Spark operator and it's running and listening for events. I can split the screen and show you the logs of the operator. This is an LES for showing the logs of the operator. And I'll make it bigger again. It started and it's already exposed an endpoint. If I open it in a browser this is endpoint with metrics. So the part of the framework is exposing a couple of simple metrics that can be scraped by Prometheus. And I can now deploy or create the custom resource for the Spark cluster and hopefully it will be caused by the operator that will create the actual Spark cluster for us. Again, split the screen. So this is the example of the custom resource for the Spark cluster and when I apply it here we can see in the logs that operator called this event and is creating Spark cluster for us. And we can see three new pods because we asked for one instance of master and two instances for workers. So they are being deployed and now they are ready. We can verify that it's already Spark cluster by exposing the Spark UI. So let's do that. A lot of resources were actually created. There was replication controls involved, pods and services. And if I expose the service for Spark UI it should be responding. So we just created a route for the web UI. Here it is, the web UI for the Spark and I can also create a new notebook for that can attach to the Spark cluster and simulate the client application, the driver. For that I will create simple web and I will also expose the service for the newly created notebook. So this is the new workshop notebook that will try to attach to the cluster. But it needs a token so first I need to grab it from the logs. This is like a security mechanism for Jupyter, it can be turned off. I have the default settings. Here is the token. It contains a couple of notebooks and one of them is a notebook for connecting to Spark application. By default it tries to spin up its own local cluster and local host. But we can provide an external hostname and this should correspond to a service represented by the Spark cluster. Spark is listening on board 7077. So let me put it here. And if I evaluate the cell by pressing control enter we should be able to see in this Spark web UI before it was no connected application but if I refresh the page there is now one Spark shell application connected to it so it works. So it was the Spark operator in a nutshell. It has a lot of more features than the basics. So how it was done. This is basically the implementation that can fit into one slide because of course I'm hiding the complexity by the method calls but in a nutshell it's one class. This is for one watcher. This is for the cluster operator. We extend abstract operator which comes from the library and we have to override methods on edge, on delete and on modify which basically handles the events of the Spark cluster. So and we are using Kubernetes client for this. So this is like the what's happening. I'm showing you the shiny thing but a lot of stuff is happening under cover. And one of those libraries, one of the dependencies is Kubernetes fabricate client. It has full an API. It's a types of client so it works with method calls I don't have to compose strings and call those strings. And what's really convenient about the client that it just works out of the box. It tries to figure out from which environment it was invoked and it grabs the security from either config file or as a mountain secrets from the container. And the other library was the abstract operator and that's something that I've created for other Java people that would like to write operators in Java or JVM languages. Automate the bootstrapping of the application but also creating those watchers for those event loops. And also it supports JSON schema as a single source of truth so you can describe your entity objects as a JSON schema and that will create classes for your bootstrap your application with entity classes. Both approaches are supported custom resource and config maps. As Mike has mentioned custom maps may be useful for testing or when you don't have the cluster admin rights in Kubernetes. Recently Quarkus.io support was added so now it can use the Grail VM compiler for ahead-of-time compilation and it can create similar binary as GoLang does so it's just one binary when everything is technically linked together and it can be added to a container and you can basically use from scratch. I wouldn't recommend it in the local files. Add just this one library and just one binary and run it. It supports also CDI and just context independence injection but it has to sacrifice like big performance for the boot speed because that's what the Grail compiler does. I have examples for other languages which are only the JVM languages currently but Grail VM also supports like really polyglot inter-operation but this is not done yet. So I have example for Java, Scala, Kotlin, Groovy, Haskell, JavaScript and the talk promised that it will be polyglot operators so now I will show another demo which is crazy. First I need to run the VS code and in the behind the Makefile is building the project and deploying the operator so I first go for the code so it's an application written in Groovy and as you can see we are again extending the abstract operator class that is like generic class and where the type parameter is the entity we are watching and in this Groovy class we are statically importing function from a language called Fregge which is an implementation of Haskell on top of JVM so it's three languages Groovy, Java and Haskell and also later on we will also import a feature or function from language called BrainFuck and so what this operator does is it watches for cast config maps and it will basically create another config map with the result so config map will express an input which is a number and it creates a new config map which it's a calculated like n-fibonacci member of the sequence so it should be running by now and it's a config map so now if I create a new config map it started doing something and if I ask for all the config maps in the cluster there is the first one I have created by this ocapply I can show that one online so this is the first this is the input basically for the algorithm and this one was created by the operator so if I show the result I think cm so this is so it says result is this huge number which it happens to be 40 second member of the Fibonacci sequence but what it also did was calculating a Pi it's like really artificial example but it can say the interoperability between multiple more or less esoteric languages and the Pi function Pi approximation was done in this main method so here we have on-head handler which calculates the Fibonacci number but also calls the main method which comes from this statically imported function so if you look into it it's a bf interpreter written in frege and all it does it has three methods Pi approximation hello world and 9 to 0 and this main method calls the Pi approximation so this is the program for approximating Pi in brainfuck it's readable right and as we can see it was written in the log so this is the Pi approximation and here it has a very simple UI or interface that if I put more pluses here it will calculate like the number of digits we want to approximate so it's like unary coding and this is the content of the tape of the simulating machine so just to sum up we had a plan being written in groovy that was extending class from Java the library was added as a normal jar library through Gradle and this is logo for frege which is basically Haskell on the JVM and from frege we firstly called the n-fibonacci number and then we were able to simulate the brainfuck language using the interpreter and which itself approximates the Pi. It's a really artificial demo but it can show you that operators are not only go action so people today write operators a lot in Go which makes sense because all the ecosystem is written in Golang Docker is written in Golang, Kubernetes is written in Golang but Go is not as important is not as popular as Java in those indices and I would argue that a lot of existing infrastructure is still written in Java and it may make sense to use the same language for the operand and the operator itself people complain a lot about startup time when it comes to Java memory footprint but it gets much better with the porcos and Gravian recently and as for the spark operator the memory footprint is under one max and the container is also under one megabytes so yeah as I told it's considered writing the operator in the same language as you write the operands yesterday there was talk about Python SDK for operators from Subin which is another approach and something that allows all this interoperation is tool called OLM operator lifecycle management where you can write describe metadata about your operators by something called cluster service version manifest where you can describe what your operator requires when it comes to writes what reads and what resources it should be able to read and write but also what custom resources it should be created for it so it kind of work around in open shift to overcome this need cluster admin write so you can create this CSV manifest and the open shift itself there is an operator that watches for this CSV files and it will create this custom resources for you there is a operator marketplace these days and also upper registry when you can store these yamls and you can push those yamls using something called operator career so you can have your operator deploy it release it as a docker image and then provide this manifest in a guay.io from which people can use it this is the example of the operator app.io and there is pargo operator right here so this is the java operator the other famous operator written in java is streamz for apache kafka but mostly all of them the others are written in go so how to start new operator first understand what you want to do understand your domain we have examples for the java operators and copy pasting is always good source of information when it's we are in the open source world so here is the point I would like to I wanted to like to make that if you have an existing framework database distributed system whatever written in java consider using the same language because you can maintain the expertise or people don't have to use another language just for writing an operator can be useful for when it comes to money thank you that was it we have questions any questions zac all the way in the back thank you great presentation just had a you mentioned corkis if you can tell us a little bit more about what corkis is can you speak up a little bit you mentioned something about the java footprint and using corkis how that might help maybe if you can explain that a little bit more so corkis is a framework developed in redhead generally and it uses grahlvm which is compiler started in oracle and it provides a way to take your jar file and create like one binary from it one of the functions of grahlvm that contains more features and they call it native image so it takes this jar file and transform it to statically just one binary that has statically linked everything together which is self-contained binary that can be run and how it does it work it in java like the code is interpreted you have the bytecode and jvm tries to interpret the bytecode and after some certain period of time it identifies the hotspots which lines of this bytecode were run frequently and it just in time compiler kicks in and tries to compile the hotspots for the bytecode but in grahlvm they basically compile everything once so they sacrifice the interoperability between different platforms is not right once run anywhere anymore but you get the fast bootstrap because they also have some smart features that it will actually try to evaluate all those static initializers create a heap snapshot and the heap snapshot is part of the image itself so once it's starting it just loads this snapshot of this heap and it's able to start faster because it's not chill any other questions thanks for the talk I'm glad to see things happening in other languages I was wondering though after you've made your operator or while you're making it how difficult are these things to debug when you're when you're building it I imagine like in the reconciliation loop or something like this you might have bugs how hard is that typically in your experience I think it's pretty easy one of the things you didn't see here like what you saw Yirka doing with the example was he started the pod that has the operator in it and the operator is just an application and we could tail the logs from that so we could see the logs coming out but there's actually another way we could run it we could run it locally on the laptop and you could have it connected remotely to the cluster doing the same thing so you could actually run you know like your ID like eclipse or something like that you could have the operator in eclipse and so if you wanted to you could actually go to the level of using a step debugger on the actual operator code and that isn't just JVM you can do that in a lot of different languages so there's an Ansible operator right that comes out of the operator SDK framework you can actually run that locally as well and just tail the logs right there and see what's going on so I think I don't know I think like maybe I'm speaking for Yirka a little bit much but I think we both found it pretty easy to debug these things basically you're running it you know in whatever tooling you wanted to use basically and that's actually the feature that comes for free by using that fabricated client because it can realize in which environment it's running if it is in a Docker environment in Kubernetes or on the local hosts it can take the Kubernetes config file from whatever it has some like rules that takes precedence like precedency rules like from which it takes the config file but if it succeeds it just takes it and runs yeah I was wondering can the OLM be leveraged to make it easier for less privileged users to install these objects or do you still need admin to use that so I have a little trouble here you say using the OLM is it easier for less privileged users to install an operator? yeah that's right you talked about how to have admin privileged to actually do the install I was wondering if the OLM can be a way to get around that problem I think you still need a cluster admin to install the custom resource definitions for you but can that be done through the OLM? yeah I think with OLM the CSV custom resource definitions is already there so you need a right to be able to create the new CSV and then the OLM operator will create those CRDs for you so it kind of shifts the problem somewhere else so you need a different set of privileges to do that basically but presumably it's less than cluster admin still this is when you're getting into Kubernetes and we talked about role-based access for all the different objects it's like this is just one more object you can put a role on is someone privileged enough to install an operator in your cluster the custom resource definition will have to be there in order for the OLM to be able to deploy your operator so someone would have had to install it presumably a cluster administrator actually there are like seven or even more other custom resources just for the OLM to work well there's like subscription and something like that so you can subscribe to a channel of where the OLM operator is published and you can create new versions updates and such things and it's like ideally people don't have to care about the CRDs at all it should be exposed by the console in OpenShift any other questions? alright well thank you very much for your time thank you yeah I look pretty well yeah that was also again too quick can I turn it off? yeah just turn it off I'll turn it off