 Hello, KubeCon. We are super excited to be here today, and today we'll be talking about Kubernetes package management using UNIX philosophy with Carval. A quick introduction of ourselves. My name is Helen George. I'm a product manager at VMware. I've been with VMware for a little over a year now. Before that, I worked at Pivotal Labs, which was acquired by VMware, and worked at ThoughtWorks, which is a software consultancy. I've built products for a variety of customers from healthcare, travel, finance, and retail. I'm an engineer on the Carval team. I'm also in VMware for roughly a year. I came from Pivotal software, where I work with cloud native build packs, and I help build products like K-Build and Pack. Okay, so let's see our agenda for today. We will start with talking about the problem statement that brings us here today. Afterwards, we'll introduce Carval, our tool suite. Afterwards, we'll see a demo of how might Carval help with the problem that we see today, and then we'll be opening for some questions. Do you want to take it away? Yeah, so today's problem statement is as follow. Getting software installed and keeping it updated on a Kubernetes cluster in a secure, scalable, and automated way is cumbersome. Before we dive into solving this problem, Drow, could you tell us why this is a cumbersome task? Yes, definitely. So Kubernetes ecosystem has a lot of tools that help people do all the tasks needed. And a lot of these tools do more or less the same things. So you have multiple tools for templating, multiple tools for installing software and so on. And if you are a person that is producing your software, you want to have access to all these tools and use the ones that make more sense for you. But if you're someone that is consuming software, and if you have, let's imagine, 100 applications, you'd have to know all the tools from the ecosystem in order to manage your clusters. So this can be a very cumbersome task. And also, another problem that we saw that is very cumbersome is that the person that is consuming software will have to know somehow and have to download newer versions of the software. And we're trying to address this with Carvel. So what is Carvel? Let's talk a little bit about Carvel. Carvel is a set of tools, suite of tools that do very targeted operations. And so they are very small, but they do one thing and they do it in a good way. What we're trying to do with Carvel is that you can, using the unique philosophy, you can swap tools if you want to use Carvel tools from, if you want to use the Carvel tools, or if you want to use other tools, we want to allow you to do that. So all the tools are pipeable between themselves and they are self-sufficient. So let's see, let's talk about which tools are we going to see here today. Yeah, there are multiple tools within Carvel, as Drow mentioned, and we highlighted five of them here. At the top, starting with Cat Controller, which is our package management tool, YTT, which stands for YAML Templating Tool, is for templating and overlaying. K-Build is used for building out container images, and it also does image resolution into their digest format. Image package is used for packaging image and configurations, and it also relocates those package image and configurations. And finally, Cap is our deployment tool. But our focus today is Cap Controller, and as the diagram suggests, Cap Controller allows software producers to choose a variety of underlying tools, whether that may be Carvel or any other Kubernetes tools for managing the lifecycle of the clusters. You can easily swap and pick and choose tools there. But for the consumer, software consumer, it only exposes Cap Controller, which simplifies the cumbersome task of using multiple tools for lifecycle management, as we stated in the problem statement. So we're going to solve our problem statement in three steps. We will start by showing you how an individual can install a software that he or she developed onto their own Kubernetes cluster and keep the software up to date. Next, in scenario two, we will show you how software producer can create a distributable artifact so that the consumer can install it to their Kubernetes cluster, because oftentimes you're not just using the software that you build, but what others have built. Lastly, we will go through a more complex scenario where the software producer produces multiple various applications and different versions, and the software consumer can decide which application and version to consume. So starting with scenario one where, again, the software producer is developing for their own and installing on their own Kubernetes cluster. To solve this, in Carvel, one of the ways to solve this is by using Cap Controller and a custom resource called AppCR. AppCR is built on top of Kubernetes API, so you might see some familiar YAML statements here, and it specifies how to fetch, configure, and deploy software to Kubernetes cluster. Let's take a look at these three keys in AppCR, fetch, template, and deploy. First, the fetch key is defining which content you can get from where, and the composability aspect of Carvel lets you choose from either Carvel's image package, helm, or Git. In our demo, we'll show you how to do it with Git, and the template key defines which template tools you would like to use. Currently, we use helm, support helm, and YTT. In the future, we would like to support other tools like customize or JSON it, and the demo will be using helm as a templating tool. And the deploy key defines the deployment tools. We currently only support Cap to install an application, but we are open to adding other deployment tools as well, so if there's a tool you would like us to support, please let us know. Now, let's take a look at these in action. Yes, so let's take a look at our application. So we have one application here that we created some in the world that basically just writes to the pod. It creates a pod and writes on to the logs just a message that is passed as part of the attributes here. So we do have a AppCR that Ellen explained before. We're going to use a Git repository where we have our helm chart, and then we're just going to use helm template to create the manifest and then just install it. So what would it look like if instead of using Git here, if we could use other tools like image package, could you show us what that looks like? Yes, definitely. So I do have an example here of using an image package bundle and how this looks like. But before we dive into what it looks like, let's talk a little bit about what is an image package bundle. So an image package bundle is an OCI image that contains two sets of files, distinct sets of files. So they are represented here in blue and in yellow. The yellow files are configuration files. So you can have in your OCI image on your bundle, you can have, for example, in our case, we'll have our helm chart and it will contain like our charts YAML, the values YAML, our templates and so on. You can add whatever you want. There's no real structure here that you need to follow, except if, for example, you use helm, you need to use the helm structure. If you use YTT, you can use, there's some structure on YTT, but it's up to you how you organize this. So the other portion is those two files there that tell image package that this is a bundle. And what is a bundle? A bundle, it is a graph of software. What does that mean? You can tell that one particular image, like in this case our bundle, requires other OCI images as well. So your software will be running in an OCI image and you can point it from this bundle and everything gets tied together and you can share this bundle altogether. The images that contain the configuration plus the images that contain the software. So now that we talked a little bit and we saw what an image package bundle is, we can just look at this and basically the major difference between these two here, between the app CR that uses Git and the app CR that uses image package bundle is just the fetch parameter where we're just defining where to get this information. So let's try to apply this to our cluster and see what happens. Just so you know beforehand, I created, I installed cap controller on this cluster and I also created some namespaces and some service accounts. So we're just going to deploy this app CR into our demo one namespace and it is reconciling. So cap controller is reading our app CR and it's trying to bootstrap the application. So it is, looks like it is finished. So we are expecting to see a pod running in that particular namespace that we saw up there. So if we take a look at it, yes, it is running, it is ready. Everything looks okay. So if we look at the logs for this particular, for this particular application, we'll be able to see that we have a log line that's comes from our help chart. Okay, so let's, let's take a look at our next scenario. Yeah, in scenario two, the software producer wants to share the application with the software consumer. And this time we'll be introducing a different set of custom resources called package CR and installed package CR. But before we dive in, let's clarify what we mean by a package. A package is a combination of configuration metadata and OCI images. It makes it easier for the software producer to share the software with someone else and it informs the software consumer what software it holds and how to install it into a Kubernetes cluster. Now back to package CR. Package CR wraps app CR and adds additional metadata like public name and the version of the software. App CR was designed for a use case where I write the software and I deploy it. Whereas package CR and installed package CR were designed with I write the software and you deploy use case in mind. And as you can see in the diagram, package CR is created by the software producer and acts as a definition of your application. And the installed package CR on the other hand, is created by the software consumer and is used to instantiate the application. Ellen, can you explain us why there's this division between package CR and the installed CR? Yeah, there's a division between package CR and installed package CR because we want to separate out the definition and the instantiation. And we think the benefits is that it abstracts away the details of what and how to install an application for the software consumer. The software consumer does not need to worry about how to fetch, what from where, and doesn't need to know the deep, doesn't have to have that deep knowledge of what he or she is installing. All you need to do is create an installed package CR, which references the package that you would like to install by specifying the public key here. Then the rest of actual fetching, templating and installing will be taken care by CAP controller based on the spec defined by the producer in the package CR. And the consumer can further customize this. You can also specify a version of the software that you would like to install, or the consumer can provide data values for them to perform more granular customization of configuration. So let's take a look at these in action. So let's take a look at our package custom resource and see, as Ellen mentioned, it's basically an app CR with a little bit more information to it. So this is what we're going to be applying to our cluster. And let's see what happens. So when we run, again, the command to deploy to the cluster, our package, our package, this is going to create a custom resource that is cluster wide, because you'll be able, you'll be, you'll be needing this access to this resource in order to install it to different namespaces. So now that we created it, if we look at what is like the most relevant information for this package, we'll see that we'll have a public name on it, and we have a version on it. So these are the two things that we're going to need in order to instantiate this package. So let's take a look at how might we instantiate this package. So we do have an installed package custom resource here, and it is pointing to our hello world.carvel.dev in the version 1.00, as we defined in this package bundle. And as Ellen mentioned, you can customize the, you can customize this instantiation. So in this case, we're providing a secret that contains values that we want to have that customization, and we will want to change the message that is printed by our hello world application to say message from the installed package. So let's try to instantiate this application and see what happens. So we're going to deploy the application in our installed application into our demo two namespace. And this is pretty quick, but right now cap controller should be trying to do all the fetching and the templating. So we should have a pod. Oh, it's already running. That's good. So our pod is already running. So if we look at the logs, it should say our new message, it was installed from an image package from an installed image package. So in this demo here, we are showing how the software consumer's workflow can be simplified if you leverage the installed package, this out package custom resource, because cap controller will take care of the fetching, the templating and installing for you without you ever knowing that all that is happening. And that is very powerful. So let's take a look and what can we do more here? Yeah, so the third scenario is where the software producer publishes various applications in different versions. And the consumer can decide which application and version to consume. Also, if there are any updates made available by the producer, the consumer wants to be made aware of those changes automatically. Here we're going to solve this problem using two new things package repository and package repository CR. It's important to note the difference between the two package repository is an artifact that the producer creates to group various packages together. While a package repository CR is a custom resource created by the consumer to let cat controller know where the package repository is located. A simple workflow here is that the producer pushes the package repository to an either OCI image, HTTP server or Git repository, and the consumer references that package repository in the package repository CR, which then the cat controller will watch for any update made to the packages within the package repository. So let's take a look at this together. Cool. So let's see. So prior to prior to this demo, I created a package repository. And I have the sample of it in my disk. So this is our repository if you want. And the only you can store the package repository as an OCI image, as an image package bundle, or in a Git repository, or as an artifact can be downloaded like a TARGZ from an HTTP server. But the only thing that they need to have is a folder called packages as we have as we can see right here. And inside of it, you will add all the custom resources, all package custom resources that you want to make available to through this package repository. So in this case, we want to make two new package custom resources available, the yellow world version 1.1.0, pretty similar to the prior one, and also the other different apps. So you can mix and match applications and versions. It's up to you. There's no real requirement from the cap controller side. So as I said, I already pre-pushed this as an image package bundle. Again, I did this because you can have bundles that contain that point to other bundles, making this a graph of software and bringing all this software to whatever you want. So before we do anything in our cluster, let's take a look and see what are the packages that we currently have available in our cluster. So if you remember correctly on the previous step, we did create a package custom resource. So here we go. It has version 1.0.0. So let's create now a package repository that points to the custom resource that points to our package repository. So what does that look like? It is a very simple thing where you just define where to find it, and then cap controller will be able to just look at it. So in our case, we have an image package bundle, and it is in this particular repository. And it is tagged because if you do any change, it should be updated. So let's deploy this particular custom resource here. Let me just pick up here. So yes. And now if we try to find out which packages we have, so cap controller is going to, you see like there's already two new packages here. So cap controller will process this custom resource, and it will try to find what are the package custom resources that are part of this package repository. So two new applications, two new packages are shown up here. What if the consumer wants these updates made aware automatically instead of manually checking and pinging? How can we do that? That's a good question. So like in here also, I have in my disk, I do have another repository here, another package repository that contains two more versions of the software that we had before. So we contain the version 2.0.0 of the Yellow World and 0.0.2 of the other app. And what I'm going to do is I'm going to create an image package bundle. I'm going to push it to this location and to this tag, and we'll be able to see that cap controller is able to process that information. So basically now I'm just picking up that folder in my disk, and then I'm just creating a bundle with it and pushing it to the registry. So now image package when it is time again to check to see if there's a new, if there's something new on this package repository, and this happens roughly every 30 seconds. It should give us all the new packages that we are looking for. So we need to win a little bit. And there we go. So now we saw that our consumers can just rely on cap controller to get updates when new versions are added to the package repositories. So this concludes our demo of this scenario. And we are showing exactly that it is much easier and it's much more automated for the package consumers to be notified and to start using new versions of these applications. So what did we learn here today? Yeah, today we learned by demonstrating that package management workflow is much simplified for the consumers. There's this consistency for consumers because he or she doesn't need to know the underlying tools that the producers used while it provides flexibility for producers because you can still pick and choose whichever tools that you would like. And we've also showed how various custom resources and concepts that we introduced today on how it leverages standard APIs like Kubernetes API and registry API. And it comes, the benefits of leveraging standard APIs is that because they're well known, standard APIs is easier for new users to learn how cap controller works and also reach the benefit of standard APIs reliability. Finally, we saw how different custom resources and concepts follow UNIX philosophy and they have well defined boundaries and separations of concerns. So to recap all the different resources and concepts that we learned today, image package bundle is a packaging format that is not tied to the type of the content and it acts as a shareable unit. Package is a combination of configuration metadata and OCI images where it's represented by the package CR and it tells cap controller where to find the Kubernetes manifest and how to template and install those manifests. We've also learned in scenario three package repository is a collection of packages that are grouped together that helps distribution of multiple software and versions and package repository CR is used to point cap controller to a package repository so that the consumer could get that automated update. And finally installed package CR is used to install a particular package which ultimately results in installation of a package resources onto a cluster. So that wraps our talks today. Thank you for joining our session. You can find more information about our tools on our website carvo.dev and you can ask questions or share your thoughts or opinions and feedback to us by just messaging us on our Slack channel called Carvo within the Kubernetes workspace. So thank you. We'll see you at the Q&A.