Skip to main content

· 6 min read
Juraj Karadža


When you touch on containerized apps today, Kubernetes usually comes up as their orchestrator. Sure, Kubernetes is great for managing your containers on a fleet of servers and ensuring those are running over time. But today, Kubernetes is more than that.

Kubernetes allows you to extend its functionality with your logic. You can build upon existing mechanisms baked into Kubernetes and build dev tooling like never before - enter Custom Resource Definitions (CRDs).

Support us 🙏

We know that Kubernetes can be difficult. That is why we created Cyclops, a truly developer-oriented Kubernetes platform. Abstract the complexities of Kubernetes, and deploy and manage your applications through a UI. Because of its platform nature, the UI itself is highly customizable - you can change it to fit your needs.

We're developing Cyclops as an open-source project. If you're keen to give it a try, here's a quick start guide available on our repository. If you like what you see, consider showing your support by giving us a star ⭐


Kubernetes components

Before diving into CRDs, let's take a step back and look at Kubernetes control plane components, specifically Kubernetes API and its ETCD database. We made a blog on each one of those components previously, so feel free to check it out for more details.

You will likely talk to your Kubernetes cluster using the command-line tool kubectl. This tool allows you to create, read, and delete resources in your Kubernetes clusters. When I say “talk” to a Kubernetes cluster, I mean making requests against the API. Kubernetes API is the only component we, as users, ever interact with.

Each time we create or update a K8s resource, the Kubernetes API stores it in its database — etcd. etcd is a distributed key-value store used to store all of your resource configurations, such as deployments, services, and so on. A neat feature of etcd is that you can subscribe to changes in some keys in the database, which is used by other Kubernetes mechanisms.

Kubernetes control plane

What happens when we create a new K8s resource? Let's go through the flow by creating a service. To create it, we need a file called service.yaml

# service.yaml

apiVersion: v1
kind: Service
name: my-service
selector: MyApp
- protocol: TCP
port: 80
targetPort: 9376

and apply it to the cluster using kubectl:

kubectl apply -f service.yaml

service/my-service created

kubectl read our file and created a request against the Kubernetes API. API then makes sure our service configuration is valid (e.g., all the necessary fields were there, fields were of the correct types, …) and stores it to etcd. Now etcd can utilize its watch feature mentioned previously and notify controllers about a newly created service.

CRDs and how to create one

With the basic flow covered, we can now extend it. We can apply the same process of validating, storing, and watching resources to custom objects. To define those objects, we will use Kubernetes’ Custom Resource Definitions (CRD).

CRD can be a YAML file containing the schema of our new object - which fields does our custom object have, and how do we validate them. It will instruct the Kubernetes API on how to handle a new type of resource.

Let’s say your company is in the fruit business, and you are trusted with the task of automating the deployment of apples to your Kubernetes cluster. The example, of course, has nothing to do with a real-life scenario to show that you can extend the Kubernetes API however you see fit.

Apples have a color that can be either green, red, or yellow, and each apple has its weight. Let’s create a YAML to reflect that on our Kubernetes API:

# apple-crd.yaml

kind: CustomResourceDefinition
kind: Apple
listKind: ApplesList
plural: apples
singular: apple
scope: Namespaced
- name: v1alpha1
type: string
type: string
type: object
- green
- red
- yellow
type: string
type: integer
type: object
type: object
served: true
storage: true

We defined two properties for version v1alpha1 under .properties.spec:

  • color (which can take one of the values in the enum)
  • weightInGrams

To tell the Kubernetes API, there is a new type of object, we can just apply the previous file to the cluster:

kubectl apply -f apple-crd.yaml created

Kubernetes API is now ready to receive Apples, validate them, and store them to etcd.

Don’t take my word for it, you can create a Kubernetes object that satisfies the schema from the CRD above:

# green-apple.yaml

kind: Apple
name: green-apple
color: green
weightInGrams: 200

and apply it to the cluster:

kubectl apply -f green-apple.yaml created

Now, your cluster can handle one more type of resource, and you can store and handle your custom data inside the same Kubernetes cluster. This is now a completely valid command:

kubectl get apples

green-apple 6s

Can I then use Kubernetes as a database?

Now that we know we can store any type of object in our Kubernetes database and manage it through the K8s API, we should probably draw a line on how far we want to abuse this concept.

Obviously, your application data (like fruits in the example) would fall into the misuse category when talking about CRDs. You should develop stand-alone APIs with separate databases for such cases.

CRDs are a great fit if you need your objects to be accessible through kubectl and the API to the object is declarative. Also, another great use case for extending the Kubernetes API is when you are implementing the Kubernetes Operator pattern, but more on that in future blog posts 😄

On the other hand, if you decide to go the CRD route, you are very much dependent on how K8s API works with resources, and you can get restricted because of its API groups and namespaces.

Kubernetes CRDs are a powerful tool and can help you build new developer platforms and tools. We at Cyclops develop on top of our CRDs so feel free to check them out on our repository.

· 4 min read
Juraj Karadža


Kubernetes has risen to fame over the past couple of years, transforming from a geeky buzzword into a cornerstone of modern software development.

Yet, with its rise to fame, Kubernetes has also become shrouded in myths and misconceptions, which can often deter potential users - “Kubernetes is only for large companies” or “I need microservices for Kubernetes”…

While most of these misconceptions can be said about other container orchestrators, in this article, I focused on Kubernetes as it is the most popular and the first one that comes to mind when people think of container orchestration.

That being said, let’s dive into five of the most common misconceptions about Kubernetes and set the record straight!

Support us 🙏

We know that Kubernetes can be difficult. That is why we created Cyclops, a truly developer-oriented Kubernetes platform. Abstract the complexities of Kubernetes, and deploy and manage your applications through a UI. Because of its platform nature, the UI itself is highly customizable - you can change it to fit your needs.

We're developing Cyclops as an open-source project. If you're keen to give it a try, here's a quick start guide available on our repository. If you like what you see, consider showing your support by giving us a star ⭐


1. Kubernetes is Only for Large Enterprises

💨 Misconception: Kubernetes is too complex and resource-intensive for small to medium-sized businesses and is only practical for large enterprises.

🔍  Reality: Kubernetes is highly scalable and can be used by organizations of any size. With managed services like EKS, GKE, and AKS, even small teams can set up and manage Kubernetes clusters. These services take care of much of the heavy lifting, so smaller organizations can easily benefit from the features Kubernetes provides without needing a ton of infrastructure or a big DevOps team.

For example, a startup can easily set up a Kubernetes cluster on AWS using EKS. This takes advantage of AWS’s infrastructure and managed services, making it simpler and more cost-effective to manage.

2. Kubernetes Replaces Docker

💨 Misconception: Kubernetes is a replacement for Docker.

🔍  Reality: Kubernetes and Docker serve different, yet complementary, purposes. Docker is a platform for containerizing applications, while Kubernetes is an orchestration system for managing those containers across multiple hosts/servers. Docker handles the creation and running of containers, but Kubernetes takes on the orchestration tasks, such as scaling, load balancing, and self-healing.

In practice, Docker containers are often used as the building blocks that Kubernetes orchestrates. For instance, developers use Docker to create container images, which are then deployed and managed by Kubernetes.


3. Kubernetes Manages Everything Automatically

💨 Misconception: Kubernetes fully automates all aspects of container management without the need for manual intervention.

🔍 Reality: Kubernetes takes care of many tasks like container deployment, scaling, and failover, but it still needs proper setup and ongoing management. You’ll have to configure things like network policies, resource limits, and storage. Plus, keeping an eye on the cluster with regular monitoring and updates is crucial for its health and security.

For example, deploying applications requires configuration files in which you describe declaratively what you want Kubernetes to do with your application. Tools like Cyclops help manage these configurations by providing a user-friendly interface.

4. Kubernetes is Only for Microservices

💨 Misconception: Kubernetes is not suitable for monolithic applications.

🔍  Reality: While Kubernetes excels at managing microservices, it is equally capable of handling monolithic applications. Kubernetes provides features like horizontal pod autoscaling (HPA), which can be utilized by both microservices and monolithic applications. HPA allows applications to scale based on the load automatically, ensuring your application will not crash under high pressure.

For example, a monolithic application can be containerized and deployed in a Kubernetes cluster. With proper configuration, Kubernetes can manage the application's scaling, deployment, and monitoring just as effectively as it does with microservices.


5. Kubernetes is Too Complex to Learn and Implement

💨 Misconception: Kubernetes is too complicated for individuals and small teams to learn and implement.

🔍  Reality: While Kubernetes does have a steep learning curve, there are numerous tools, tutorials, and resources available to simplify the learning and implementation process. Platforms like Minikube allow developers to run Kubernetes locally, providing a sandbox environment to experiment and learn.

Online courses, documentation, and community support also significantly contribute to making Kubernetes more accessible. With the right tools, even small teams can effectively use Kubernetes for their projects.

Thanks for reading 🙌

I hope this article clarified some common myths about Kubernetes. If you enjoyed the read, consider supporting us by giving us a star on our repo!

· 6 min read
Juraj Karadža


What started as a frustration with not being able to get in touch with our users, quickly developed into a redesign of the flow of our platform.

My team and I are developing an open-source platform that helps developers deploy and manage their applications in Kubernetes. We have been working hard to expand our user base, and the efforts were starting to show results.

The rising number of installations was satisfying to see. However, that was the only thing we were able to observe. We wanted to know more. We wanted to know what users are doing with our platform and what they are struggling with.

The following short story could be considered a #building-in-public entry of our startup, but I just found it interesting and wanted to share it with you.

Support us 🙏

We know that Kubernetes can be difficult. That is why we created Cyclops, a truly developer-oriented Kubernetes platform. Abstract the complexities of Kubernetes, and deploy and manage your applications through a UI. Because of its platform nature, the UI itself is highly customizable - you can change it to fit your needs.


We're developing Cyclops as an open-source project. If you're keen to give it a try, here's a quick start guide available on our repository. If you like what you see, consider showing your support by giving us a star ⭐

User Feedback 🗣️

Since the beginning, we have been trying to talk to our users and gather as much feedback as we can. However, that turned out to be sort of a problem. We knew that people were downloading Cyclops; on our DockerHub, we could see the number of pulled images getting larger by the day.

The problem was that we had no way of contacting our users. We could only see the number of pulls, not who pulled them.

In an attempt to get in touch with our users, we created a Discord server. Discord is a great way to keep your community close to you, and because of it, we have a way of getting to know our users.

So we started talking to them. The feedback wasn’t always constructive…

Unsatisfied User

… but most of it was really positive. However, there is a caveat; a lot of the positive feedback we were getting was from 1-on-1 meetings with our users. In these meetings, we could demonstrate Cyclops's capabilities better than users could on their own. This turned out to be a bigger issue than we thought.

Recently, we implemented telemetry to better understand how our users utilize Cyclops. As soon as the statistics started to come in, boy, were we surprised.

The Problem ❗

We were really pleased with the number of installations of Cyclops. As it turns out, we were correct in thinking that Cyclops is pretty simple and straightforward to install. But when it came to starting to use it, more than 60% of our users got lost.

So what was the problem?

The thing is, when you want to deploy an application to your Kubernetes cluster, you must provide a template in the form of a Helm chart. We have created a few examples of such charts and published them on our open repository. In all our documentation and blogs, we pointed people toward that repository when starting out with Cyclops. However, it seems that it didn’t catch on. The number of deployed applications was still much lower than the number of started instances of Cyclops.

A Theory 🧑‍🔬

Here is a fun fact for you, dear reader: the majority of online readers spend less than 15 seconds on a web page (source). Knowing this, could it be that most of our users skimmed over the blogs and documentation and missed out on the reference to our template repository?

We wanted to test this theory. In our last blog, we did another tutorial on Cyclops showcasing its benefits. However, for this specific article, we created a special version of Cyclops. What was so special about this version? We added a default value for the template when creating new modules.

Small Change

After gathering statistics for some time, the results were in.

The Results 📊

With a simple change, we saw an improvement in our users' behavior, they no longer got lost at the very first step of using our platform! However, it wasn’t as big of an improvement as we initially hoped for but it was certainly in the right direction. We asked ourselves how to further improve on this issue. And we think we got it 🙌

Since our most recent version (v0.3.0), we have reworked the platform's flow. Choosing a template is no longer an input field but a dropdown. Every instance of Cyclops comes with a couple of premade templates (stored in our templates repository), which you are free to use and abuse. We feel like this will go a long way in showcasing the customizable nature of Cyclops to our users.


But an important part of Cyclops is its ability to use your own templates, and we weren’t ready to compromise on that! That is why we added a new Templates tab where you can add new templates and manage the existing ones. Once added, your new templates will be shown in the dropdown the next time you find yourself deploying an application.

Credits 🦔

We released v0.3.0 earlier this week, so it is still too early to say how much of an impact it had on our users, but we have high expectations! We might share the statistics once enough time passes, so make sure to follow us to find out!

It would be a shame not to mention PostHog as the telemetry provider we are using, since it turned out to be extremely useful. Because it is hard to find people who will talk with you about your product, gathering statistics gave us a much greater insight into our users.

If you are one of the few readers who gave this article more than the previously mentioned 15 seconds, I hope you found it amusing at least 😁

If you are interested in contributing to our project, whether through coding or providing feedback, join our Discord community and come talk to us!

· 6 min read
Juraj Karadža

Developers Perspective

We perceive things by the way we interact with and understand them. To an infrastructure team, Kubernetes is a great way to scale and manage applications, but for a frontend/backend developer, It may seem complicated and stressful.

Kubernetes introduces many concepts and terminologies (deployments, services, pods…) that take time to grasp and even more time to master. But devs sometimes have to interact with them weekly, if not daily.

Through our experience and research, we identified the three most common ways in which developers engage with Kubernetes.

So, what does Kubernetes look like through the lens of a developer?

Support us 🙏

GitHub stars

Before we start, we would love it if you starred our open-source repository and helped us get our tool in front of other developers ⭐


Depending on the structure and development workflow of the company, developers either do not interact with Kubernetes at all because automated processes and scripts are doing it, or they interact with Kubernetes through three touchpoints:

  1. 1. configuration files of their application
  2. 2. deploying their application in the K8s cluster
  3. 3. monitoring their applications

Configuration files


Configuration files tell Kubernetes how to handle an application. They are declarative, meaning you write the result you want to see rather than the steps to get there.

Most commonly written in YAML, these files are large and complex to read and understand. And being written in YAML comes with its challenges (and quirks) since it is an additional programming language that devs need to learn.

Mistakes in configurations are hard to spot and rectify but are a BIG deal. Even if you coded your app perfectly with no bugs whatsoever (hypothetically 😅), a mistake in the config could mean that your app just won't run.


Deploying your application is the process of starting your app in the Kubernetes cluster. The native way of doing this is with kubectl.

kubectl is the command line tool for Kubernetes. Being a command line tool/interface is something we should take into consideration. Senior devs should be accustomed to CLIs, but junior devs still might be timid. Getting accustomed to kubectl adds a new layer to the learning curve.

However, deploying requires more than knowledge of the available commands of kubectl; it also requires an understanding of the context and how it manipulates Kubernetes objects.


Now that our devs have configured and deployed their application, they are done, right? Well, no. The application probably has its fair share of bugs and issues, and they are expected to be able to monitor them and fix them when needed.

Finding out what is wrong with your app inside the Kubernetes cluster is not straightforward. Devs need to understand the objects that are in the cluster and how they interact with each other.

For instance, to fetch your app's logs, you need to know that it is run in a Pod. That Pod is located in a Replica Set, which itself is located inside a Deployment. You must understand these relationships while rummaging through your K8s resources with kubectl.

Developer Platforms

This is just the tip of the iceberg when it comes to Kubernetes. Its complexity drastically elongates onboarding time for new devs, and all the additional steps introduced slow down development cycles.

Companies usually have a dedicated team to deal with infrastructure and Kubernetes. When developers encounter issues or need help, they turn to these teams. But you can imagine that when dealing with something as complex as Kubernetes, needing help is a common occurrence.

This is why we are seeing the rise of developer platforms, which reduce friction between developer and infrastructure teams. A good platform makes the development cycle of creating, updating, and deploying as smooth and straightforward as possible.

Cyclops - Kubernetes platform made for developers

Cyclops is a fantastic open-source developer tool that abstracts Kubernetes's complexities behind a simple graphical user interface. We call it a platform because your infrastructure teams can customize the UI to suit your specific needs and wants.

So, how does Cyclops solve the issues mentioned above?

  1. 1. With Cyclops, your developers never directly interact with configuration files. You create a template, which is then rendered for the developers as a form. This avoids the need to learn languages like YAML and has the added benefit of allowing you to add validations to their input, making it harder for developers to make mistakes.
  2. 2. Once the developers have specified what they need with Cyclops' help, deploying their application is as simple as clicking a button.
  3. 3. Now that they have deployed their app, Cyclops makes it easy to monitor its state via its user interface. The application's details are easily accessible and include all the resources (and logs) it uses.

Let's see it in action!

The installation is just a two-step process, but there are a few prerequisites, with the main thing being a Kubernetes cluster.

So once you have your cluster up and running, you can install Cyclops with the command below:

kubectl apply -f

And once it's successfully installed (which could take a minute or two), you can access it with:

kubectl port-forward svc/cyclops-ui 3000:3000 -n cyclops

Cyclops should now be accessible in your browser at http://localhost:3000.

Now, by clicking on the Add Module button, you will be taken to this screen:

New Module in Cyclops

We created a default template for you, but this screen is highly customizable (you can try out your own Helm charts!). Now, instead of reading and writing YAML, developers can fill out these fields by clicking the save button, and their application will be deployed!

App Overview in Cyclops

This next screen represents the detailed view of your newly deployed application. Here, you can see all the specified resources (and easily access the logs 😉). If anything goes wrong, it will be visible here!

If you wish to change something in the configuration (like adding more replicas of your app), click on the Edit button. You will be taken to a screen similar to the first one, where you can make those changes, again not even knowing that you are dealing with YAML underneath.

Wrapping up

We hope this article did a good job of showcasing some of the ways developers are struggling with Kubernetes and a potential solution that you could consider next time you or your devs engage with it.

If you are running into issues with Kubernetes or have devs who are pestering you with K8s-related questions, consider supporting us by giving us a star on our GitHub repository

· 6 min read
Juraj Karadža


Have you ever thought of contributing to open source? If you are here, you probably did 😄

For a beginner, it might seem confusing, and I can relate - I've been there myself. However, you found the willpower to push onwards and learn more about this process and I hope this article will show you that it is not as complicated as it may seem.

Most repositories that are accepting contributions usually have a CONTRIBUTING.MD file that you should look out for. Since not all repositories are the same, this file will tell you more about the process of contributing to that specific repository.

However, some general rules can be applied to most repositories, and we will go over them in this article.

Support us 🙏🏻

GitHub stars

Before we start, we would love it if you starred our open-source repository and helped us get our tool in front of other developers ⭐

Where to contribute?

The first question that comes to mind is: Where to contribute?

Well, you should start with the projects you are already using. Maybe some library needs updating, or some tool has a bug?

You may want to contribute to some project within your domain of expertise or a project that uses the tech stack you are comfortable with.

These are great contenders, and you should look into them.

If you don't know any projects but still want to contribute, browse on GitHub or go to sites like Quine, where many open-source repositories are looking for contributors.

For this article, we will use our open-source repository - Cyclops.

How to know what needs improving?

Whether you are looking for something to do or already know of a bug that needs fixing, all contributions start in the same place - the Issues tab.


If you are new to the project, you can look for the “good first issue” label that most repositories have. As the name suggests, they are a good entry point to get involved in a project. All of the issues should have a description of the problem.

If you know of a problem or bug that is not listed here or you want to see a new feature get introduced, open a new issue! Once you open the issue, the maintainers will decide what to do next, and you should wait for their response before you start coding.

Pro Tip: If you are opening a bug issue, be sure to write down the steps on how to reproduce the bug!

How to contribute?

Okay, we found a repo, an issue we want to work on, talked with the maintainers, and were given the green light to work on the issue. Let's finally start coding!

1. Fork the repo

The first step is forking the repository. This will make a copy of the project and add it to your GitHub account.


2. Clone the repo

Now go to your repositories and find the forked repo. Click on the < > Code button and select one of the options (HTTPS / SSH / GitHub CLI).


Copy the content in the box. Now open your terminal and position yourself where you want to save the project locally. Once you have positioned yourself, type the following command in your terminal:

git clone <paste the copied content>

After a few moments, you should have the project locally on your PC!

3. Create a new branch

Now, go to your local folder and create a new branch. Be sure to check out the of the project to see if the maintainers want you to follow some rules for the naming of branches!

4. Commit and push your changes

Once you have your branch ready, you can start changing the codebase. After you finish, commit your changes and push them to your forked repository. Be sure to follow the commit message conventions if the repository has them in place (check the

5. Open a pull request

Now that you have pushed your changes and want to merge them to the main repository, it is time to create a pull request! Once again, you should check the rules to see if the maintainers would like you to stick to a naming convention when creating PRs and what they like to see in the description.

opening a PR.png

❗Be sure to set the base repository to the original repository you forked from❗

I created a PR, now what?

You are satisfied with your changes and successfully created a pull request to the main repository. What now? Now, you wait.

Depending on the urgency of the problem your PR is fixing and the schedule of the maintainers, you will have to wait for somebody to review your pull request. Be prepared to explain why and what you did (if you didn't do a good job in the PR description) and to make changes if necessary.

Don't take any requests for changes personally. All of you are here for the betterment of the project and nobody is ill-willed. If you disagree with the opinions of the reviewers, tell them! A healthy discussion has never been a bad thing.

Why fork? 🍴

You are probably wondering why we had to fork the repository at all. Why not just clone the original and work on a separate branch? Basically, remove the #1 step and isn't the rest the same?

Well, you could try, but once you push your changes, you will realize you don't have the authorization to do so! By forking the repo, you become the owner of the copied repository with the rights to change the codebase. This is a neat system to ensure only the changes approved by the original maintainers go through.

Go contribute!

Now that you are armed with this information, you are ready to go and make your mark in the open-source world! Go help the myriad of projects you have and haven't heard of, and join this growing community. Your help will be greatly appreciated, I'm sure of it 😉

· 3 min read
Juraj Karadža


If you have been in the open-source community lately, you know what I am talking about. The story goes something like this: There were loads of videos/blogs/events hyping up open-source contributions, mainly as a good gateway to land your dream software engineering job. And to some extent, it is true.

However, this trend has also brought a flood of pull requests (PRs) that contribute little to nothing or, worse, add clutter to the codebase.

And this is why, lately, you can find a wave of blogs and videos on the theme of “Why you should NOT contribute to Open-Source.”

This article will show how bad it can get with the latest surge of unsavory PRs.

Support us

GitHub stars

Before we start, we would love it if you starred our open-source repository and help us get our tool in front of other developers ⭐
(The irony is not lost on us here... 😄)


The latest drama has happened in the epxressjs GitHub repo. As you can see, there were loads of “Update” pull requests.

List of closed PRs

This doesn’t immediately sound bad; perhaps the Readme was riddled with typos? It's a long shot, but let's investigate. Unfortunately, that wasn’t the case. Looking closely at some of these PRs, we will see the drama's root cause.

So let us take a look… PR-hello

Maybe it’s just one bad apple? Well, let’s look at some others… PR-hehe PR-demo-collage

As you can see, these PRs are not trying to better the project they contribute to. Although somewhat comedic, having lots and lots of such PRs is a nightmare for the project's maintainers.

And the last one, I think, tells the bigger picture in this story. It seems that lots of these PRs were a learning experience (assuming “Collage” was a mistype of “College”). Although, that is an assumption made in good faith.

Some of them could have been done as a sort of shortcut for bolstering resumes, which is a far more alarming intent.

The missing puzzle piece

Newcomers don’t understand that contributing is not all about the code. It is about investing your time in understanding the project and the issues it is trying to solve, being a part of the community and the discussion, and wanting to better the project because you want it to thrive.

And that is what is praised about open source contributions, the will to learn and the will to help. In the process, you demonstrate that you can be proactive and solve complex issues. That is what employers are really looking for.

One look at contributions like these, and you can be sure that you will be ignored by potential employers.

Final thoughts

Now, there were some external actors in the latest PR nightmare that I won’t be naming here because I doubt that they acted with ill intent. It’s the latest buzz, and I am sure that you can find them with a single Google search if you wanted to.

It’s important to mention that when considering contributing to open-source, start by looking at the projects you already use and are familiar with.

Alternatively, focus on projects where you have domain expertise, as sharing that knowledge can be a valuable resource for the maintainers.

Have you had any bad experiences contributing to open-source?

· 10 min read
Juraj Karad�ža

Docker Ship

If you are using Kubernetes, there's a fair chance you are using Helm or at least considered to. This article will guide you on how to publish your Helm charts in a less conventional way - using OCI-based registries.

First of all, we will briefly cover what OCI-based registries are and how they can help us, and after some theory, we will create a Helm chart, push it to the OCI registry, and actually deploy something using it.

Show us your support 🙏🏻

ProductHunt Launch

Before we start, we want to mention that we scheduled ourfirst release on Product Hunt! Click the notify me button to be alerted when we are out and ready to receive your feedback 🔔

We would love it if you starred our repository and helped us get our tool in front of other developers ⭐

Helm OCI-based registries

Helm repositories are used to store Helm charts. Using them, we can publish and version our applications as packaged Helm charts others can install into their cluster. They also allow for easier versioning and rollback of resources. All in all, a single, centralized place to store your Helm charts.

Under the hood, a Helm repository is a simple HTTP server that serves an index.yaml file that contains information about charts stored in that repository, like versions, descriptions, and URLs on where to download chart contents (usually on the same server). Read more about index.yaml file here.

OCI stands for Open Container Initiative, and its goal as an organization is to define a specification for container formats and runtime.

At first glance, it does not seem related to the Helm repositories we just mentioned; at least for me it wasn’t. OCI registries mostly host container images, but we can store different types of content there. One of the types we can host is Helm charts!

With such a registry, you can host all your images and Helm charts in the same place. On top of that, you don’t need to maintain a Helm repository index.yaml file, which makes the management of your chart easier.

You can serve the exact same chart on a Helm repository and a container (OCI) registry; the only difference between those two approaches is how you maintain the charts.

You can use multiple different container registries to store Helm charts:

Getting our hands dirty

Now that we have our basics down, let's see those OCI charts in practice and use them to deploy our applications. We will create a chart, push it to DockerHub, and then use it to deploy our apps in a Kubernetes cluster. In order to deploy resources from the chart we defined into a Kubernetes cluster, we are going to use Cyclops.

Creating a Helm chart on OCI registry

Firstly, we are going to create a Helm chart. To create a chart, create a new directory

mkdir oci-demo

and add the files listed below to the created directory. Feel free to customize the chart to fit your needs, but for the sake of this demo, we are going to create a basic one with the following structure:

└── oci-demo
├── Chart.yaml # YAML file containing information about the chart
├── templates # Directory of templates that, when combined with values, will generate valid Kubernetes manifest files.
│ ├── deployment.yaml # K8s resources are separated into multiple files. Feel free to add more or change existing
│ └── service.yaml
├── values.schema.json # JSON Schema for imposing a structure on the values.yaml file
└── values.yaml # The default configuration values for this chart

You can find out more about each of those files/directories on Helm's official docs.


Let's start with Chart.yaml:

# Chart.yaml

apiVersion: v1
name: oci-demo
version: 0.0.0

Not to go into detail, I'm going to 302 you to the Helm docs.

Templates folder

The next step is defining what Kubernetes resources our packaged application need. We define those in the /templates folder. As seen in the chart structure from earlier, we are going to add only a deployment and a service to our application.

Contents of those files are below:

# templates/deployment.yaml

apiVersion: apps/v1
kind: Deployment
app: {{ }}
name: {{ }}
replicas: {{ .Values.replicas }}
app: {{ }}
app: {{ }}
- image: {{ .Values.image -}}:{{ .Values.version }}
name: {{ }}
- containerPort: 80
name: http


# templates/service.yaml

{{- if .Values.service }}
apiVersion: v1
kind: Service
name: {{ }}
app: {{ }}
type: LoadBalancer
- port: 80
targetPort: 80
protocol: TCP
name: http
app: {{ }}
{{- end }}

Values definition

In the /templates folder we defined, obviously, just the templates. It would be a good idea to define default values for those. We are going to use values.yaml for that:

name: demo
replicas: 3

image: nginx
version: 1.14.2

service: true

These are default values, and anybody using your chart will most probably want to change those. But what happens if someone using your chart messes up values by providing invalid data? For example, setting replicas: two or service: no. Another thing that can get messed up is the name of the value, so somebody might use instance: 3 instead of replicas: 3.

Both of these examples seem pretty obvious and something you wouldn’t mess up, but as your chart grows, so does your values.yaml file. A great example is the Redis chart by Bitnami. I encourage you to scroll through its values file. See you in a minute!

Now that you are back, you probably understand why validating values and defining their structure makes sense. Let’s do the same for our chart.

But first, let’s define what are the rules of this validation:

  • service is type boolean
  • name, image and version are strings
  • replicas is an integer
  • replicas is ≥ 0
  • allow only certain values for version; let those be 1.14.1, 1.14.2, or 1.15.0

There are quite a few rules packed for such short values file! However, having them in place gives us the confidence to deploy the chart without worrying about making mistakes.

Now that we have those defined, our JSON schema will look like the following:

"properties": {
"name": {
"description": "Application name",
"type": "string"
"replicas": {
"description": "Number of replicas",
"type": "integer",
"minimum": 0
"image": {
"description": "Container Image",
"type": "string"
"version": {
"description": "Container image version",
"type": "string",
"enum": ["1.14.1", "1.14.2", "1.15.0"]
"service": {
"description": "Expose your application",
"type": "boolean"
"order": ["name", "replicas", "image", "version", "service"],
"title": "Values",
"type": "object"

You can find more on how to write a JSON schema for a Helm chart in the Helm docs.

Pushing to Docker Hub

If you don’t already have a Docker Hub account, you should create one to host your charts.

To push our chart to an OCI registry, we will need to package the chart into a tarball with the following command:

helm package oci-demo

There should now be a tarball file called oci-demo-0.0.0.tgz .

Next, you will need to sign in to Docker Hub using Helm:

helm registry login -u {username}

And finally, push your chart to the remote registry:

helm push oci-demo-0.0.0.tgz oci://{username}

Check your artifacts on Docker Hub, and you should see your newly created Helm chart. If you click on the chart, you’ll see more info about the chart and its versions.

Docker Hub tags

Using OCI charts

We now have our Helm chart locked and loaded, so let’s use it. First of all, let's spin up a Kubernetes cluster. If you already have a running Kubernetes cluster, feel free to use it and skip this step.

Create a minikube Cluster

When I want to play around with a new Kubernetes tool, I try it out on a minikube cluster. Minikube is basically a Kubernetes cluster you can run on your own machine and easily tear down once you are done.

If you are using a mac, you can install it via brew:

brew install minikube

Check their installation guide here →

To actually run the cluster, just hit:

minikube start

A quick check that everything is ok; let's list all the namespaces:

kubectl get ns

default Active 11s
kube-node-lease Active 13s
kube-public Active 13s
kube-system Active 13s

Deploy OCI chart into a Kubernetes cluster

You can deploy your newly created Helm chart using pure Helm, but let’s take it a step further. Chances are we will want to edit that deployment with our specific values and change those over time, so let's make it more user-friendly.

We can use Cyclops to help us with that! It can help you deploy and visualize your applications by giving you a simple UI where you get your chart deployed in just a couple of clicks. Let’s install Cyclops into our cluster and deploy that newly created chart!

You can install Cyclops with a single command:

kubectl apply -f

It will create a new namespace called cyclops and start a Cyclops deployment inside it.

Check that pods are up and running:

kubectl get pods -n cyclops

cyclops-ctrl-d6fd877d8-tpdqd 1/1 Running 0 62s
cyclops-ui-5c858b44d4-dhn2c 1/1 Running 0 62s

Once those are up, you need to port-forward both deployments:

kubectl port-forward svc/cyclops-ui 3000:3000 -n cyclops

and in a separate window, run:

kubectl port-forward svc/cyclops-ctrl 8080:8080 -n cyclops

You can now access Cyclops at http://localhost:3000

When you open your local Cyclops, you can hit Add module in the upper right corner.

This is where we get to use our OCI chart! You are prompted for the repository, path, and version of the template. You can fill those out with the OCI chart you created earlier, like I did below.

Repository: oci://{username}
Path: oci-demo
Version: 0.0.0

From here, you can just hit load and let Cyclops render a form based on your chart.

Do you remember that schema file we added to our chart earlier? This is what Cyclops uses to render this form for you. All the fields and validations you set in the values.schema.json file are taken into account so you can get a completely custom UI for your applications.

You can now fill those fields out and hit save, and Cyclops will do the rest for you. Firstly, it will inject those form values into the template and then deploy each of the resources into the cluster.

Any last words?

We started from scratch and, in a couple of minutes, deployed an application with our own Helm chart and a custom UI tailored specifically for our application. On top of that, we did it using an OCI-based registry and didn’t go through setting up a Helm repository to serve our chart.

Hope you had fun throughout the article and found the information and steps we did useful. Thank you for checking out our article!

· 7 min read
Juraj Karadža

Kubernetes Enjoyer

For the uninitiated, K8s stands for Kubernetes, with the number 8 representing the eight letters between K and s. Kubernetes has become pretty much unavoidable in the current tech landscape but remains uninviting because of its complexity and steep learning curve.

The terminal-based interaction has a part to play in this story. If you ever had the privilege of watching a seasoned DevOps work his way with a Kubernetes cluster, you might look at him like you would a seasoned martial artist showcasing his fighting skills. That is because everything that is done through a terminal always looks more frightening and seems like it requires years and years of training. 🥋

Now the question stands: how can we make such a complex issue (one that even had its name beautified) more enjoyable? Well, in the same way we make everything more enjoyable → make it easier and make it prettier! 🎀 And how would you do that, you might ask. With a graphical user interface, or GUI for short! Let’s take a look at five tools that provide you with a user interface when dealing with Kubernetes.

Show us your support 🙏🏻

ProductHunt Launch

Before we start, we want to mention that we scheduled our first release on Product Hunt! Click the notify me button to be alerted when we are out and ready to receive your feedback 🔔

And we would love it if you starred our repository and helped us get our tool in front of other developers ⭐

Kubernetes Dashboard

Let's dive into the quintessential tool for Kubernetes managementthe Kubernetes Dashboard. Automatically bundled with your cluster, it delivers a graphical overview of your Kubernetes environment. You can use it to get an overview of applications running on a cluster, deploy containerized applications to a Kubernetes cluster, and manage cluster resources.

The Kubernetes Dashboard not only offers an overview but also helps with troubleshooting. It provides insights into the health of Kubernetes resources, spotlighting any operational errors.

Through it, you can deploy applications as well. You can do it with a manifest that you wrote or through a form that you just fill in. However, it's worth noting that the form, while user-friendly, lacks the flexibility for customization beyond basic examples.

While the K8s dashboard is a jack-of-all-trades, many find it to be a generalist, lacking in-depth features. This limitation encourages us to explore more tools, each designed for specific purposes, and so we embark on our journey through the list of tools we’ve explored.

K8s Dashboard


K9s is your best friend (get it? 🐶) when exploring your cluster via the terminal. It shares commonality with Vim for its interaction style using shortcuts and starting commands with: but don’t let that discourage you. K9s keeps a vigilant eye on Kubernetes activities, providing real-time information and intuitive commands for resource interaction.

It can almost replace the standard kubectl and doesn’t require you to have a “cheat sheet” next to you when interacting with Kubernetes. You traverse through your resources just by selecting them and drilling down to the lowest level. This allows for easy log extraction and access to its shell.

K9s gives you the ability to see the manifest of each of your resources and the ability to edit and apply changes. As I mentioned, it almost replaces the kubectl. One of the differentiators is that you cannot deploy new resources via the K9s.

K9s comes with the ability to filter out your resources and search them with the / command, making it easier to locate the ones you are looking for in the sea of resources or filter through the logs of a specific pod.

A nice touch is the list of commands and shortcuts available to you at any given moment at the top of the screen, and its customization with skins and plugins gives you room for additional utility.

K9s UI


If you are having difficulties fighting with manifest files, Cyclops is the tool for you! Cyclops removes the clutter and complexity when dealing with manifests by transforming them into a structured web-based form, eliminating the need for manual configuration and command-line interactions.

This makes the deployment process more accessible to individuals with varying levels of technical expertise.

Within the architecture of Cyclops, a central component is the Helm engine. Helm is very popular within the Kubernetes community; chances are you have already run into it. The popularity of Helm plays to Cyclops's strength because of its straightforward integration.

Cyclops Form

With Cyclops, you're not boxed into a one-size-fits-all approach. You can customize the form to suit your unique needs. For instance, a team member can generate a Helm chart, allowing others to define necessary values using Cyclops for painless application deployment.

Once you have declared the wanted state of your application, deploying it is as straightforward as clicking a button. Furthermore, once you deploy your application, the wanted state is also easily changeable through Cyclops.

In Cyclops, every application lays out a detailed list of resources it uses - deployments, services, pods, and others, all in plain view. You can easily track their status, helping you quickly spot and fix any hiccups in your application. It's like having a clear roadmap to navigate and troubleshoot any issues that pop up.

Cyclops Resources


Consider the convenience and time saving of your local server refreshing automatically with every code save, providing real-time visualization of your code changes.

Imagine taking this smooth experience a step further into Kubernetes clusters; DevSpace makes that possible. With DevSpace, you can deploy applications in real time during the coding process, facilitating swift iteration.

DevSpace streamlines the process by automatically applying changes to your K8s cluster without needing the entire image building and deployment pipeline. It builds the image locally without pushing it to a registry, although the option to automatically push images is available for those who require it during development.

Moreover, DevSpace features a user interface that, while somewhat limited, offers a quick overview of all pods in your cluster. It allows you to easily access pod logs and even execute commands directly within them, enhancing your development workflow.

Although I have focused on local development, DevSpace is used for creating workflows as well. All your workflows are saved in one file, making it easy to reproduce environments on any machine with a single devspace deploy command.

DevSpace UI


Unlike the other tools mentioned in this post, Kubevious has no way of changing the cluster state. It is intended solely as an observability tool, focusing on potential issues in your cluster. It highlights potential threats and risks for every resource you may run.

The graphical views offer insights into containers, networking, exposure, RBAC, and Helm charts for intuitive troubleshooting.

Kubevious has a rule engine that helps with the detection and prevention of misconfigurations. It comes with rules out of the box, but it allows you to create custom rules as well (for example, “don’t allow images to be on the latest tag”).

It also comes with the cool time machine feature that allows users to travel back in time, audit applications, root cause outages, and recover manifests, ensuring a complete understanding of cluster history.

And I have to mention the full-text search it provides! You can search for any resource without knowing the specific name of it. One great example is searching for any resources that use a specific port by just typing in “port 3000,” and Kubevious will find your resource.

Kubevious Dashboard

Final thoughts

In our quest to enhance the Kubernetes experience, we've unwrapped five delightful tools, each offering its unique charm to make your journey smoother and more enjoyable.

These are not the only tools that provide a UI for Kubernetes, but we wanted to shine a spotlight on some, maybe lesser-known ones.

All of these tools are open-source, so give them a go; they're free!

I want to end this post with a question directed to you, the reader: What are your thoughts on graphical representations of Kubernetes? Is it needed, or does kubectl reign supreme?

· 7 min read
Juraj Karadža

Modules in Cyclops

If you are a developer, the chances are you have heard about Kubernetes. You heard that it is an amazing tool to help you scale your applications and manage your micro-services. But, you probably also heard that it is VERY complex. It is so complex that you were probably scared off. And I don’t blame you; that is the first reaction I got as well.

If you search the top posts with the Kubernetes tags on this website, you will find a myriad of tutorials and people explaining Kubernetes. These posts are the most trending because people WANT to understand Kubernetes because we feel like, in today's software development world, Kubernetes is unavoidable. And this is true, to an extent…

Software developers are often required to understand and work with Kubernetes; if you have ever looked for jobs in this sector, you know this already. But what if there was a tool to minimize your touching points with Kubernetes? A tool that simplifies the process and gives you guidance when trying to deploy applications into Kubernetes clusters. A tool that is highly customizable and lets someone in your organization (who understands Kubernetes, commonly known as a DevOps) create a user interface for you!

Yep, you guessed it, it’s Cyclops! 😄

And just to clarify, Cyclops is not used to create and manage Kubernetes clusters and other infrastructure; rather, Cyclops is used for deploying and managing applications INSIDE the cluster.

Show us your support 🙏🏻

Github Stars

We are building Cyclops to be open-source, and your support would mean the world to us. Consider giving us a star on GitHub and following us on ProductHunt, where we scheduled our very first release!

Before we start

In order to test out Cyclops, you are going to need a few things. If this is not your first time using Kubernetes, the chances are you already have everything ready, but we will still describe each of the components for the newcomers to the Kubernetes space. These tools are not only used for Cyclops, and you can use them for anything Kubernetes-related.

The main thing you are going to need to test out Cyclops is a Kubernetes cluster. If you have one that you can use to play with, great; if not, we will show you how to spin up a cluster on your own computer. So, the three prerequisites for doing this are:

  1. 1. Docker
  2. 2. Minikube
  3. 3. kubectl

Docker is the most popular containerization tool, and we will use it to download and spin up a Minikube image. Downloading Docker is straightforward: go to their webpage and download the Docker Desktop application.

Minikube plays the role of a Kubernetes cluster on your local machine. It is a great tool for developing and testing out your Kubernetes applications, and it is perfect for this scenario. You can find a guide on how to install it here.

The final thing missing is a way of communicating with your Kubernetes cluster, and this is done through the Kubernetes command line tool called kubectl. It can be used to deploy applications, inspect and manage cluster resources, and view logs. In this tutorial, we will use it to install Cyclops into our cluster on Minikube and expose its functionality outside the cluster.

Installing Cyclops

Once you have your Kubernetes cluster ready (check the Before We Start section), installing Cyclops is a straightforward process. Using kubectl, run the following command in your terminal:

kubectl apply -f

It will create a new namespace called cyclops and deploy everything you need for your Cyclops instance to run.

Now, all that is left is to expose the Cyclops server outside the cluster. You will need to expose both the backend and frontend with the commands below.

Expose frontend through:

kubectl port-forward svc/cyclops-ui 3000:3000 -n cyclops

And the backend through:

kubectl port-forward svc/cyclops-ctrl 8080:8080 -n cyclops

And that's it! You can now access Cyclops in your browser at http://localhost:3000. If you are having trouble with the port-forward commands, you probably just need to wait a few of seconds after installing Cyclops into your cluster, it can take a while to start all it’s resources.

It’s Demo Time 💥

Now that you have your Cyclops instance up and running, it’s time to see what it’s capable of.

You should be greeted with an almost empty screen with no deployed modules showing. Module is Cyclops’s slang for application 😎. So, let’s start by creating our first module!

By clicking on the Add module button in the top right corner, you should be taken to a new screen. Here, Cyclops asks us which Helm chart do we want to deploy.

Not to go too deep, but Helm is a very popular open-source package manager for Kubernetes. It helps you create configuration files that are needed for applications running in Kubernetes. These charts let Kubernetes know how to handle your application in the cluster.

Don’t worry; to showcase the basics of Cyclops, we created a simple Helm chart so that anyone can follow along. You can find what it looks like in our GitHub repository, along with a couple of more examples of Helm charts that you can use!

Loaded Chart

As you can see, once you enter the repository of your chart, Cyclops will render a user interface. If you want to find out the magic behind the rendering, check out our previous blog.

You can fill out the fields as you wish, but be mindful of the Kubernetes naming conventions!

If you want to follow along, my input is as follows:

name: demo
replicas: 1
image: nginx
version: 1.14.2
service: true

We will set the module name to demo as well. Click save, and Cyclops will show you the details of your new module.

Single pod Deployment

This screen shows you all the resources your application is using at the moment. It will list all the deployments, services, pods, or any other resource. Here, we can see that Cyclops deployed one pod into your cluster, as we specified in the replicas field. If you want to make sure that it really is running in your cluster, you can check it out by using the following kubectl command:

kubectl get pods

But what if all of a sudden, there was a need to scale up your application or any other resource? Well, don't worry; with Cyclops, it’s really easy!

By clicking the Edit button, you can change the values of your application’s resources. Let’s try to scale our application up to 3 replicas and see what happens.

Three pod Deployment

You should now see two more pods in the Deployment tab; hurray! 🎉

Of course, this works for any other change you might want to make to your application. Like, the service, perhaps? What if we realized we don't really need it anymore? Well, with Cyclops, it's really easy to shut it down if need be.

Click again on the Edit button, and this time, turn off the service toggle.

Service shut down

Cyclops won't delete it automatically but will warn you (via the warning triangle sign) that you shut it down, and it is not in function anymore. This means you can safely delete it!

And if you are sick and tired of your application, you can delete the whole thing as well 🗑️

Click on the Delete button and fill in the name of the module to safely delete it. You can, again, check if it really was deleted with kubectl:

kubectl get pods


And that’s all there really is to it! Cyclops allows people with varying knowledge of Kubernetes to leverage its power. If you followed this tutorial, you should have deployed your very first application using Cyclops; congratz! 🎉 On our webpage, you can find one more tutorial showcasing more features and a more complicated use case, as well as our contact and community info.

If you have any sort of feedback or ideas on how to make Cyclops better, you can fill out our short Google form!

· 9 min read
Juraj Karadža

Image of a Kubernetes cluster based on an image found on

A couple of days ago, I held a talk about Kubernetes and its components at the college I used to go to. My mom said she liked the talk, so I turned it into a blog post.

Many software engineers tend to look away from anything related to Kubernetes, even though they might use it daily. At first glance, it seems complex and like a whole new world to dive into. And yeah, it is, but in this blog post, I will go over all of the main components of a Kubernetes cluster and explain what they do in an example.

By the end of the blog post, you won't be a Kubernetes expert, but you will probably get a good idea of what to look for and how to structure the chaos that Kubernetes seems to be at first.

Show us your support 🙏🏻

Github Stars

Before we start, we would love it if you starred our repository and helped us get our tool in front of other developers. Our GitHub repo is here: ⭐


First of all, we can divide a Kubernetes cluster into two parts: control plane and worker nodes. The control plane takes care of the whole operation and controls the state of our cluster. We’ll get into what that means shortly. On the other side, our worker nodes are essentially just computers listening to what the control plane tells them to do. They are the computing power of our cluster. Any application we run in the cluster will run on those nodes.

Let’s decompose that further.

Control plane

Control Plane

As we said, the control plane is making sure our cluster is running as expected. It does that by communicating with the cluster user, scheduling workloads, managing cluster state and so on.

The control plane is made of four crucial components. Simple by themselves, but together, they create a complex system. These components are:

  1. 1. API
  2. 2. ETCD
  3. 3. Scheduler
  4. 4. Controller Manager

Control plane components can be run on any machine in the cluster, but are usually run on a separate set of machines, often called master nodes. Those machines are not used to run any other container or application and are reserved for the Kubernetes control plane.


The Kubernetes API acts as the cluster's front-end interface, allowing users to interact with the cluster, define desired states, and perform operations such as creating, updating, and deleting resources.

It is the only point of contact we have with the cluster. Also, no other components are talking directly to each other, but all communication is happening through the API.


ETCD is the API’s database; it's as simple as that. When you tell Kubernetes to create a deployment, it gets stored in the ETCD alongside all the other created resources.

One characteristic of ETCD is that its key-value storage is organized as a filesystem. Another great feature of ETCD is that users can subscribe to events and get notified about changes. For example, let me know when a new pod gets created.


As the name suggests, the scheduler decides which node a pod will run on. It does that by a set of rules you can read in the Kubernetes documentation. This is what I meant when I said you won't be an expert, but you will know what to google :)

The Scheduler subscribes to all newly created pods saved in ETCD, but it can only talk with the API to get this update.

When it catches that a pod has been created, it calculates which worker node to run it on. Once it's made up its mind, the scheduler doesn't run anything on any machine; it just tells the API to run the pod on a particular node.

Controller Manager

The last component from the control plane is the controller manager. We can take it as a thermostat for our cluster. Its job is to shift the current state of the cluster to the desired state.

This means that it will create all the needed resources under the hood to satisfy our needs and get our applications up and running.

It runs multiple controller processes subscribed to changes on the ETCD, compiled into the same binary for easier deployment. Controller managers’ roles and what those controllers do will be defined more closely later in the blog.

Worker nodes

Worker nodes

Now that we have concluded what manages the whole cluster, let's dive into where our containers are running and how that is achieved.

There are 3 components running on each node in a Kubernetes cluster. Of course, you can have multiple nodes in a cluster, but each needs these three components to host your applications.

Those being:

  1. 1. container runtime
  2. 2. kubelet
  3. 3. kube proxy

Container runtime

The component that allows Kubernetes to run containers and manages the lifecycle of a container on a node is the container runtime.

Multiple container runtimes are supported, like conatinerd, cri-o, or other CRI compliant runtimes.


Another component subscribed to pod events is Kubelet. Each time a pod is scheduled on a node, the Kubelet running on that node will hear that and start all defined containers. On top of that, Kubelet also performs health checks to ensure everything is running as expected.

Kube proxy

KubeProxy in Kubernetes manages network connectivity between pods across the cluster, handling tasks like load balancing and network routing. It ensures seamless communication among pods by maintaining network rules and translating service abstractions into actionable network policies.

From a deployment to a running container

Now that we have listed all of the components and their role in a Kubernetes cluster, let's tell a story on how a Kubernetes Deployment becomes a set of containers running on various machines across the cluster.

Pods, Replicasets and Deployments

Just a quick reminder on the relation of these three: Pods, Replicasets, and Deployments.

Deployment components

The smallest unit we can deploy in a Kubernetes cluster is a pod. With it, we are going to define our containers.

Most likely, we will need a couple of instances of the same application, and we can define how to replicate our pods with a Replicaset. It will ensure that we have the desired number of pods running by starting and terminating them.

Cool, now we have our application replicated, but we would like to roll out a new version of our application. We have to tear down existing Pods/Replicaset and create new ones. A Deployment will automate this process, allowing us to roll out our feature safely.

The Prestige


Now that we have all our terminology and touched on all Kubernetes components and their role, let's see what happens when we “apply” a Deployment to a Kubernetes cluster.

Let's say that we have created a deployment.yaml file defining our application (you can see how to do that here) and ran kubectl apply -f deployment.yaml. kubectl will now submit our deployment definition to our cluster's only point of contact - the Kubernetes API.

Our simple API will store our deployment in the ETCD database. Each time a Deployment object is saved into ETCD, it will let the API know that there was a change on Deployments and that it should let everybody who is subscribed to such an event know about it.

And there is a component in the control plane that would like to know when a new Deployment spawns, and that's the Controller Manager. When it hears about a new Deployment, it will create a new Replicaset based on the Deployment configuration. To make this Replicaset, it will call the API with a create request.

Creating a Replicaset is much like creating a Deployment. API will receive a Replicaset to create and store into ETCD. This will make ETCD tell the API that somebody created a Replicaset and pass that information to all subscribed components, which is again the Controller Manager.

When the Controller Manager hears about the new Replicaset, it will create all the Pods defined with the Replicaset by, you guessed it, calling the API, which will store all those Pods into ETCD.

 As we said, a lot of things happened, so we decided to create a GIF that might help you understand the whole process under the hood.

As we said, a lot of things happened, so we decided to create a GIF that might help you understand the whole process under the hood.

Here, we include the Scheduler, which is subscribed to the Pod creation event. Each time it hears about a new Pod, it decides on which node it should be run. The Scheduler is not running the Pod but only telling the API which node it chose for it. The API will then save that information.

Another component listening to Pod events is the Kubelet, a component running on each worker node in the Kubernetes cluster. Each time the API tells the Kubelet that the Scheduler decided to run the Pod on its node, the Kubelet will start all the containers defined by the Pod.

Finally, we turned our configuration into an application running on a machine! It is a lengthy process with many moving parts, but this may be my favorite part.

Each component takes just a tiny bit of the responsibility of deploying an application, but they solve a pretty complex problem together.

Final thoughts

Hope this article helped you get a grasp on Kubernetes components and helped you demystify the most popular orchestrator out there. We encourage you to dig around yourself because we enjoyed learning about this.

One book we recommend to learn about Kubernetes is “Kubernetes in action” by Marko Lukša. It is pretty popular and gives an excellent overview of what is going on under the hood of Kubernetes and how to use it.