Thinking of going cloud native and looking for the best way to do it? In this Unscripted episode, Lars Jensen talks with cloud specialists Thomas Vitale and Lasse Højgaard about their day-to-day work and experience with cloud native, Kubernetes and all things related.
Thinking of going cloud native and looking for the best way to do it? In this Unscripted episode, Lars Jensen talks with cloud specialists Thomas Vitale and Lasse Højgaard about their day-to-day work and experience with cloud native, Kubernetes and all things related.
Lars Jensen: Hi, my name is Lars. I'm from the GOTO team. We're doing a GOTO unscripted episode here at GOTO Copenhagen. We're here in-person finally again, and it's great to see our speakers. I am joined today by Thomas Vitale and Lasse Højgaard. If you wouldn't mind just saying a few words about yourselves so that people reading know who you are, Thomas, maybe you go first.
Thomas Vitale: Hi, I'm Thomas. I work as a senior software engineer at Systematic, a Danish software company. I'm really passionate about anything in cloud native technology, like working with Spring and contributing to open-source projects.
Lars Jensen: Okay, and you, Lasse?
Application or infrastructure?
Lars Jensen: The topic today, as people might hear from your descriptions, is cloud native, Kubernetes and all things related. My first question is, do you think Kubernetes and cloud native is a concern for application developers, or is that more of an infrastructure concern?
Lasse Højgaard: Ideally they shouldn't have to worry too much about the underlying runtime. If you're running an old-school Java project, you may be running on a JBoss, or you may be running on Tomcat, or wherever. You know that you're running on it but you're not really concerned with it unless you're actually configuring it, right? I think that we should strive for getting the same level of experience in Kubernetes. So I think a key term is to have an internal platform, a platform-as-a-service, either a real platform-as-a-service from one of the cloud providers or you build one yourself if your company is big enough to do that. Take away the complexity and then just let the app developers do whatever they need to do to fulfill their jobs. I think that's the key.
Thomas Vitale: I totally agree. I think developers should have a nice developer experience. This is one of the territories where a lot of vendors are really fighting each other to provide the best developer experience. Because now Kubernetes is a given, it's more of an operational concern. Developers want to focus on business logic. We really should strive to provide the best experience to developers by hiding a lot of complexity. And in that regard, for example, Knative built on top of Kubernetes already provides a nicer abstraction for developers, without considering a lot of different concerns that are still good to know, like the main concepts about Kubernetes because it's a different environment. But then in the daily job, it's really important that we can focus on what provides value, the product, and not on infrastructure.
Lasse Højgaard: I agree. You need to know the constraint of the platform that you're running on. If you're on Kubernetes, then parts can be rescheduled. You can have multiple replicas of them. You need to provide a health check and that kind of things. You need to set aside memory, request limits. So those are the constraints that you're working within, and that gives you some challenges when you're doing an app. You can't rely on just writing things to a file and then your part restarts and everything is gone. You need to know the constraints of the environment, but other than that, you shouldn't be too concerned about it. What are you doing in Systematic? Are you building an internal platform?
Thomas Vitale: Yes, we are doing that. As we are a large company we have different projects, at different level of what we can call a cloud native transformation. And particularly, in my project, we are really aiming at moving to use a platform that provides a great developer experience. Because, of course, we want to be able to focus on the business logic, so in the company, we are working on such a platform with also that capability in mind. So not just aimed at operators but also the interface part, the user interface, which is really critical, I think, for having a successful platform.
Lasse Højgaard: And the developer experience is like the next big thing. We have Kubernetes, which was a given, and we have multiple vendors coming up with different ways of enhancing that developer experience. You have something like Backstage from Spotify that's now open source. That's like an internal backstage where you can deploy your app, and you can monitor your apps, and have templates, and that kind of things. Then the next thing is, how, if I'm going to Kubernetes, do I run a Kubernetes cluster locally when I'm doing my development and orchestrating my services in there? What are you doing there? And I think that depends on the size of the project.
Thomas Vitale: Yeah, that's also an interesting aspect, the inner loop for developers. Do we really want to run Kubernetes? If we do then we need that knowledge also spread out across developers. Sometimes it's not really worth it if we have big infrastructures, big architectures. So a tool like Telepresence, for example, allows us to get the whole application running on a cluster somewhere, and then on our computers we can just run the components we're working on. And the traffic is routed and proxied through the cluster, so we don't have to install Kubernetes and not even think about it. I think that's a really cool tool that we have.
Lasse Højgaard: Yeah, it is, and it routes the traffic from your live cluster down to your local machine, so you can attach a debugger.
Thomas Vitale: Yeah, and that's the ultimate experience with the environment parity. We are really using that real thing. We are not simulating a local cluster with different features, but we have the real thing. We have all the nice features from the platform as well, like observability, for example. We can check tracing and monitoring.
Lasse Højgaard: And it's like you said, when we're running on a platform like this it kind of becomes a challenge. If you're doing DevOps, and I think you should, then the app developers will also be running it in production. They will be reacting to alerts, and they will be on call for that application. And that forces you to have at least a tiny amount of knowledge about Kubernetes, like, is this problem that we're seeing, related to Kubernetes or is it related to my application? And maybe you should also have a platform developer on call as well, but you need a cursory knowledge of Kubernetes as well.
Thomas Vitale: What are your thoughts on having or maybe designing a self-service API for developers? So to make things even clearer, what is the responsibility of the product team? And what is the platform team responsible for? And having also a better understanding of if I get a call, is it me? Can I fix it, or do I need someone else with a different set of skills to help me figure out what's going wrong?
Lasse Højgaard: Yeah, that's an interesting question because I think that everybody right now is running towards Kubernetes. We have Kubernetes and it's all great, and now we're building abstractions on top of it. So you and Systematic, you're building an abstraction on top of it. We are building another abstraction, and Backstage is another abstraction. What is an app? What's the deployable execution? And we see this plethora of different definitions of abstractions, of different levels of abstractions. I'm all for having an internal API to have a self-service platform-as-a-service in your company, but I think we should be aware of what is outside of your own company because you may be reinventing the wheel.
In my company, we're doing something slightly different. We are moving closer to a hosting provider actually, the ones that set up a cluster because I'm not setting up a cluster. I have an infrastructure guy who knows more about networks than I do and knows more about disks, and RAM, and all of that. And we are actually moving those closer to the app team so that, for instance, people sitting in a network operating center, can react to an alert, like saying, "Okay, this application is now returning 500 and it used to not do 500. We haven't done a deployment in a month so something is off here." And they can see that alert and have to determine, "Is this platform related or is this application related?"
It's the same dashboard for platform metrics, platform alerts as application alerts, application metrics. I think that's where we want to go because Kubernetes is so complex, super complex, that you could spend your entire career just focusing on that, right? And at the same time, application development is also super complex and you need to focus on that. So quite quickly, we have this dev and ops parity, again, and we don't want that. We want those guys to be the same guy ideally and if that is not possible, at least they should be in the same room. That's my viewpoint.
Thomas Vitale: I think that's really important. The whole DevOps philosophy of combining people with different skills, different roles, and together collaborating to the same goal is really important. There's always the risk to end up having these silos. We used to have development and operations. Now we define product or platform silos, but we really don't want to do that. And I think that's also why it's important having this API between the two teams. But I like what you said about not reinventing the wheel. We have it out there the cloud native landscape. It can be scary the first time we look at it, but there are so many great open-source tools out there we can use.
I think it's important to adopt some standards that are starting to be used a lot. As I mentioned earlier, Knative, for example, is used a lot by Red Hat, by VMware, by Google to build their serverless platforms. I think that's also a nice abstraction to have in a more standardized way so we're not reinventing the wheel. And then maybe on top of that some other tools that we can really embrace. Of course, customizing a bit, but if we keep the interface based on open-source projects then we really make things easier for everyone. When we then have a problem we have a large community available all over the world we can talk to. We can even be part of the solution in contributing to the open-source projects that we use to build the platforms.
Lasse Højgaard: I sometimes think of the cloud native landscape as an App Store for off-the-shelf software. It used to be that if you wanted to set up a database you could just go to that vendor and ask them, "Could you please help me set up a database?" And it has specific requirements for network, and memory, and CPU, and it has its own configuration language, and it had its own requirements. I need multiple replicas, I need a reverse proxy, or whatever it was. And all of those different applications, whatever it might be, had their own configuration language, had their own specialized needs.
I think a tool like Helm, which is often criticized for obvious reasons, it really unionizes configuration. With Helm, you can template a configuration file, for instance, whether that be JSON, or it be YAML, or it's a Java properties file, you can use that. So the interface becomes the Helm values file. That's the same configuration language that you're using. And now you're just building small pieces of adapters around your configuration file, and then you have the same interface for all of them. I think that's really, really cool, and it's the same way you deploy Helm Install.
The interface becomes better and the developer experience becomes better, and you can do that for almost all the tools in the cloud native landscape. I think that's really cool, and it lowers the barrier to entry, too. If I wanted to run a highly available NATS cluster on my Kubernetes cluster, that's Helm Install, and then set replicas to three. Then it's highly available it’s sharded and all those things. If I wanted to do that in the old days, oh boy. I needed to set up three different VMs and connect the network between them, and then I needed to start the service on all of them. And they needed to join in some way over the network with a token, I don't know.
Thomas Vitale: It's a whole new world now and it feels natural for developers because we used to install tools from our operating system using APT, and Linux, or maybe Homebrew on macOS. With Helm, we get the same experience so we don't have to learn a new approach, but the result is just so powerful. It's just a command then you get maybe a high available Redis cluster. It's great.
Lasse Højgaard: It is great, and it's also zero downtime deployment, and you can do rolling operations. You can do all of that kind of things that, before time, before Kubernetes, they were kinda hard. And all of the servers needed to be patched, and I hope you remembered your patch windows. They were always in the middle of the night, from midnight to 12 on the 31st of whatever month you had the patch window. And now you can just do it because things can react to that.
Thomas Vitale: Yeah, that's great.
Lasse Højgaard: It is.
Migration and transformation
Lars Jensen: I'd like to touch a little bit on the migration story. So if you're not really doing Kubernetes, cloud native yet, you've mentioned that there's a lot of complexity involved, and you've also mentioned that there's a lot of benefits. What kind of tradeoffs do we think should be considered before you do that? And do you have any, sort of, good advice for people wanting to take their old-school Rails monolith into that kind of ecosystem?
Thomas Vitale: First I'd like to say that usually, of course, we associate cloud native with Kubernetes, but we can be cloud native even without Kubernetes. Of course, that's the most popular choice, but in a lot of situations, we are really good with platform-as-a-service provided by cloud vendors instead of working with Kubernetes. Because maybe the use case is not that complex, so maybe adding Kubernetes might be too much. And I like what Cornelia Davis CTO of Weaveworks says about cloud and cloud native. Cloud is where the computation happens, and cloud native is about how we build software that runs on the cloud and takes advantage of the features.
So I think the first part, or at least from a developer's point of view, the first part of the migration would be focusing on making the application cloud native. So the 12-factor methodology, for example, comes to mind. That's the first step, being sure that we work with stateless applications, that we have externalized configurations so we don't have problems with files, and all those traditional ways that really don't play nice in a cloud environment. Even without moving directly to the cloud, just by doing that I think we can make deployments and operations easier because now we have a full set of standardized practices to build with cloud native applications, that's already just by doing that.
Changing the way that we build applications can help. And after that, of course, once we start with a cloud native application or future-to-be cloud native application, then migrating to Kubernetes involves the platform a lot, and help from the platform team. And being sure that the interface is clear for developers, so how to take advantage of these new technologies and new ways of managing applications.
Lasse Højgaard: I agree. If you're not cloud native, you have a monolith. Fix the basics first. Fix your configuration. Fix your logging. Fix your metrics, those kinds of things, and you can do that in your current environment and get a better running application. And another thing I want to mention is that you should also take a look at your test suites. If you have no tests, then I wouldn’t recomment moving to Kubernetes. It's often mentioned as an afterthought, like, "Oh, right, we need to write some tests." But it's crucial if you want to go for cloud native and you want to go to Kubernetes and to continuous delivery, and want to go faster. But you need the test to prove that you're not breaking things all the time.
Chances are, if you have a monolith, maybe your tests are not that good. Maybe you have highly coupled stuff that interacts in strange, strange ways. And that application is not suitable to be moved to Kubernetes, because that just adds more complexity. Now you're doing network calls to do methods, for instance. Or you are now at the mercy of the Kubernetes Scheduler. Okay, so now you have a running application. It gets sent a kill, it gets sent a SIGTERM on Kubernetes because it's going to be relocated to another worker node. If your application can't handle that then don't go to Kubernetes because you'll just add more problems.
Thomas Vitale: Yeah, exactly.
Lasse Højgaard: It will.
Thomas Vitale: When talking about cloud native migration, we usually talk about splitting the monolith into microservices. Maybe that's not a requirement, I would say. Sometimes we think that we can solve some problems by moving to microservices, but as you said, if we have this really cobbled monolith where we are not thinking about the domain but everything is just entangled together, moving to microservices really won't help because we would end up having a distributed monolith. And that would be even more difficult to handle in Kubernetes because then you have problems that some applications need to start before others. You have all this coupling, also deployment time, and it's not really suitable for Kubernetes. So I think it's really important to understand when it's a good idea to move to Kubernetes.
Lasse Højgaard: Yeah, and I think if nothing else the one benefit that microservices give you is that they are independently deployable. That's the one thing that microservices gives you, that you can make a change in one part of the system and you only need to deploy that one thing. So my point is that if you've gone to microservices, let's say that, and all of your qualifications need to be deployed at the same time because they need to have the same version of whatever, XML Parser, or whatever, that's not microservices. That's a distributed monolith.
Thomas Vitale: Yes, and it's a mess.
Lasse Højgaard: It is a mess. And one, I would say, anti-pattern that I often see is that you add this common library that has common business logic that goes across all of your microservices. And now you're dealing with versioning of that library in 20 different microservices, and quite soon it becomes that you need to deploy all those microservices at the same time because you have some business logic in your common library, and that's not good. And it becomes too tightly coupled again.
Thomas Vitale: Yeah, I think sometimes the don't-repeat-yourself principle becomes anti-pattern because we want to follow it completely, but then with microservices really, sometimes it's not that bad to duplicate code. Because then we have coupling, and that's not how things work in Kubernetes.
Lasse Højgaard: Yeah, I think it was a Danish company that made a tool for actually copying and pasting code into different repos for each microservice. That may be a little bit overboard, but the idea is that the common library that they were injecting into those services, didn't prevent one microservice from being deployed before another one. And there was no hard copy between them. I think that's the point.
Thomas Vitale: Yeah, so migration tip, I would say that it's important to start small, especially if it's something new in the team, at least technologies. Start with a small component, consider the 12-factor methodology and principles to make the application cloud native, and then maybe start moving that application to Kubernetes as an experiment, maybe on an internal environment, and see how it goes, and learn, get feedback. I think that's really critical before committing to moving everything to be cloud native and to Kubernetes. We might learn something that we didn't know at the beginning that might say, "Maybe Kubernetes, not the best idea in our case, or maybe too expensive."
Lasse Højgaard: Yeah, I'd totally agree, because what we want to avoid at all costs, all of us, is to have a big bang rewrite. Management has decided that Kubernetes and microservices is the greatest thing ever. So now we're going to re-factor and rewrite all of our services. Our old monolith that actually has value, we rewrite that in a microservices pattern, and we can't deliver any new features for the next six months or a year. We don't want to do that. We want to deliver value as soon as we possibly can, and that could be taking the one thing that is actually the least coupled to the rest of the system, moving that into Kubernetes, and having the old system call into that.
Because then you have that one service that you have more flexibility in. You can do rolling upgrades. You can do experimentation on that one service. And then you can slowly chip away at the monolith and move it over. But you want to deliver value as fast as possible because there are people who are paying you and giving you a budget. They expect results, and you can't say, "Oh, you'll get results in 12 months." That's a recipe for disaster, it is.
Thomas Vitale: Yeah, I think value should be the first thing we discuss. It's not like, should we move to Kubernetes, but what is the value that we want to provide to customers through the business? And then at that point, we can see if Kubernetes matches that kind of value that you want to deliver, because if we don't need to scale, or we don't need specific resilience requirements that Kubernetes provides, then maybe it doesn't make sense to move to Kubernetes. I think starting with the value proposition really helps focusing on the actual value that we're providing with the software, rather than the technology. And sometimes it's easy to get caught into the technology discussion, especially in cloud native with all those tools that we have in the landscape. But at the end of the day, we want to provide value, of course.
Lasse Højgaard: Yeah.
Kubernetes for greenfield projects?
Lars Jensen: Do you think those tips, do they apply to greenfield projects as well? We've just been talking about moving existing code and migrating that into a Kubernetes cluster, for instance. What would your tips be around greenfield projects? Is it worth spending the time upfront to get a cluster up and running and start from there? Or would you also start with something small and then later see if it makes sense to move it into Kubernetes?
Thomas Vitale: That's an interesting question.
Lasse Højgaard: I have done the Kubernetes-first approach before, and that's because that's what I know, so that's easy for me to do. That's a low-hanging fruit. Running a Kubernetes cluster, for me, is easy and developing on Kubernetes is also easy for me, so I can do it immediately. You could also just go for a serverless application running on Cloud Run, or Lambda, or whatever, and get the value out. That's what you want. But if you base your application, greenfield or not, on the 12-factor app, you're in a better position to move to Kubernetes in the near future.
Thomas Vitale: I would also embrace the cloud native principles for building the application, but of course, if the team already has knowledge about Kubernetes, already has a platform that can be used, then it's okay to go with that. But I'm thinking about startups. Starting a new product, you really want to get the product out there. Time to market is critical, so probably if you don't already have a platform and an established process to using it, it's not a good idea. There's already platform-as-a-services down there from Azure, from VMware, from Google, Red Hat. So just by following the cloud native principles, 12-factor, you can use that platform directly. That way you can focus on the new thing that the startup is working on, the business logic, and then maybe at some point, you decide to move to Kubernetes. But at that point, the migration is seamless because you already followed all the principles that are required in order to play nice in a Kubernetes environment.
Tools in the cloud native environment
Lars Jensen: Another thing I was wondering is, you've mentioned before just the number of tools available in the ecosystem, and I think that's seen explosive growth over the last couple of years. Do you think that's stabilizing? Are we still in a period of rapid expansion, or are things evening out a little bit?
Lasse Højgaard: I think we see some stabilization. I think if you go to the "TechRadar" from...I can't remember.
Thomas Vitale: Thoughtworks.
Lasse Højgaard: Thoughtworks, yeah, there are some technologies that you can adopt right now and they are stable, and well defined, and we know what they do. For instance, Kubernetes, it's stable and we know what it does. And Terraform, we know what that does, and it has business value as well. So we see some stabilization but it's also rapidly expanding. We have competing message queues. We have competing standards for tracing, and metrics, and all those things. I would take a look at the "TechRadar" and see a solid foundation that I can build my platform on and then we don't want to stagnate either. So we need to have and plan for experimentation. Okay, maybe we build our app in whatever language. There's a new language, a new framework, let's try that out in one microservice as an experiment.
And if you just say, "Okay, let's build the one platform to rule them all and just build that one and forget about it," that's not going to work because things get deprecated. You will have vulnerabilities that come out, and you have people leaving the team, all those kind of things. You need to prepare for constant change in your platform as well, constant experimentation. That's my take on it anyway.
Thomas Vitale: So handling the platform like a product that evolves just like any application that we build. I think that's important because now that more and more companies are moving to Kubernetes, I think we are learning also more about the experience of working with Kubernetes. There are new tools that are developed in order to maybe solve some issues that we might experience today or to make the experience both for developers and operators better. It’s definitely good to look into the CNCF landscape, the "TechRadar" also to know what is out there so that we have a stable foundation that we can build our business on. But we can take also an advantage of new technologies if they provide some additional value to the business.
Lars Jensen: So where do you think things are moving? Is there anything out on the horizon that really excites you that you wanna talk about?
Thomas Vitale: We didn't mention GitOps and delivery process. That's one of those that sounds a lot like a buzzword, but I think it really provides value. Having this approach we decouple the continuous delivery part, where we take the application, we run the autotest, we package it as a container image, and the deployment part that happens via pull request. We get all the nice properties that we have in traditional application development so we can do peer reviews. We can have a pull request. We have traceability, also auditing of the changes. And then, when a pull request is approved, automatically from the cluster we have a component like FluxCD or ArgoCD that realizes, "Oh, there's a new change, so let's make sure that the new change is applied to Kubernetes."
I think that's a really powerful concept that I think, more than technological change, it's a cultural change. Because maybe we're not used to doing that. We're used to having different steps with different also governance approval along the way. I think that the mindset for using GitOps needs to change a bit. But once you embrace that approach I think it becomes really powerful. It improves the quality. What do you think?
Lasse Højgaard: I think this as well, I'm adopting GitHub a lot at my projects and I think it's the way to go. I've personally chosen Flux because I think that's the simplest one for me to grasp. And like infrastructure as code was the revolution for infrastructure, GitHub is the same for application deployment. I totally agree on Flux and GitOps in general. I'm also curious to see what kind of higher-level abstractions people are now building. We have a framework coming out with Microsoft called Dapper. What is that good for in the microservice setting? We have something called Temporal from some people from Uber and another company, some higher-level microservices frameworks that are now becoming more prevalent.
There's also something called wasmCloud that is high-level abstractions for microservices. I think that's the next thing. You mentioned, what is the application and how do we deploy it? They come with built-in features in the framework, for instance, traceability, and maybe message queue, or message passing for remote procedure calls. And I think that’s really, really exciting. Right now, it's in that exploratory phase. We have all of those different ideas popping up and now we just have to wait and see what sticks.
Thomas Vitale: Another thing that I'm really excited to see how it will develop is serverless because so far we usually associate serverless with Lambda functions. So that's a very different way of thinking and designing applications, but we can take advantage of serverless technologies even with more standard container application. For example, Knative offers that capability. You don't have to use a specific framework provided by a cloud vendor, but you have a neutral interface, for example, the scaling to see the real feature. If there's no request, there's no reason to keep the application alive. I think I'd like to see how that will evolve also to be embraced for more standard applications, not just functions.
Lasse Højgaard: Serverless is also super exciting. I haven't used it that much, to be honest, and it is a different paradigm to work in. It's going from imperative to functional programming or going from HTTP synchronous communication to message-based communication. Serverless is fun. Let's see where it takes us.
Thomas Vitale: Yeah.
Do’s and don’ts
Lars Jensen: I think we're getting close to the end here, but just before we finish, I was wondering if you have any definite dos and don'ts you really would like to share, or any final war stories?
Lasse Højgaard: Yes, war stories. When you've built platforms yourself and you build applications at the same time, you sometimes get into difficult situations that you weren't expecting, as a consequence of running on Kubernetes. For instance, I had a problem a couple of months ago where one of my services was not resolving a DNS name in my cluster. And it was my log on service that couldn't talk to my IdP. That was problem for me, and I didn't realise that the problem was that the version of CoreDNS that we were running had a bug. We upgraded CoreDNS and we had a bug, and the bug was actually inside DNS, and those kinds of problems were new to me. Before Kubernetes, I never really cared about DNS. It's something that we have, but it always works, right?
Thomas Vitale: It's there.
Lasse Højgaard: It's there, it works. But now, because of the high complexity of running a service inside of Kubernetes that is talking to CoreDNS inside of Kubernetes that is actually talking to another DNS resolver outside of Kubernetes, there are new communication pathways there and caching at different levels that can actually impact your service. So that's a war story for me. I found the bug and reported it, and the guy from CoreDNS, was, like, "Huh, that's impossible." It wasn't impossible, but it was really, really, really unlikely.
Lars Jensen: That sounds like fun. I mean, even Facebook has troubles with DNS, right?
Thomas Vitale: Oh yeah.
Lasse Højgaard: BDP, but yeah.
Lars Jensen: What about you?
Thomas Vitale: Some dos and don'ts. One initial step when moving to the cloud, specifically, to Kubernetes, is containerizing applications. My advice in that regard is not to try to containerize whatever you have at the moment, depending on where it is. If you have maybe ten applications deployed on one WildFly server, don't try to containerize the whole thing because you will regret it soon. It's important to keep mapping one application, one container. I think that's extremely important. And maybe another tip, when moving to the cloud, try to embrace the culture and the practices around cloud native, like DevOps.
Because the risk is to end up having these silos where if you need something from the cloud, even if you switch to the cloud, you still have to go into Jira and open a ticket, and wait for someone to do something about it. That's not really the cloud, because one of the features of the cloud is the self-service capabilities. I think it's important to clarify which is the API and having a self-service experience for developers.
Lasse Højgaard: And also embracing the community in general. Participate in meet-ups, participate in conferences, participate in open-source because that's where you really get the benefit. Everybody else is kind of doing the same thing that you are and have maybe solved a problem that you're trying to solve. So look around you in your community and participate. I think that's also key.
Thomas Vitale: I totally agree. I'm really excited about all the open-source initiatives that are out there. Reason one, for example, is VMware open-source. Kubernetes's platform is called VMware Tanzu Community Edition, totally open source and free. It was great and it worked really well. I remember the day that they announced it, I installed it, and they used it the next day for a presentation demonstrating deploying Spring Boot applications with Kubernetes. So it just worked without problems and I was really impressed.
Lars Jensen: That's great.
Thomas Vitale: The open source community is also contributing back. I think it's really a key factor.
Lasse Højgaard: It is, yes.
Lars Jensen: Okay, that's it. Thank you very much for spending some time with me. It was a lot of fun chatting with you. I hope you enjoyed it as well.
Thomas Vitale: Yeah, it was nice.
Lasse Højgaard: Thank you for having us.
Thomas Vitale: Thank you.