Things You Shouldn’t Forget When Running Your Cloud-Native Applications on Kubernetes

If you’re even slightly interested in technologies, the definition of cloud computing shouldn’t be a complete surprise to you. However, if you’re starting a career in the IT sector, knowing about Cloud-Native Applications just a little bit isn’t enough as more and more companies are adopting this technology to their daily developers’ lives. This is why the Women Go Tech team decided to interview Olesia Pozdniakova, Senior Product Manager at CAST AI, and delve deeper into the world of Cloud-Native Applications and the most critical aspects of it.  

Olesia has about 15 years of experience in the IT sector, and the company she’s currently working in, CAST AI, is an AI-driven cloud optimization platform for Kubernetes automation and cost optimization for customers running cloud-native applications. 

There are various definitions of what a Cloud-Native Application means. In general, it’s an application specifically designed to run on a cloud and get the most benefits from it, such as cloud elasticity and on-demand resource provisioning. Cloud-Native Applications must be designed following good design practices of distributed systems, such as loose coupling, easy scalability, etc. An application developed using a style of the microservice architecture commonly meets the requirements, and as a result, microservice architecture became popular for Cloud-Native Applications. 

Let’s take a simple example of an e-commerce site to understand a microservice application. You can run it on the cloud as one big program that provides multiple services, like user authorization, order placement, order provisioning, products basket, products catalog, and others, or you can run multiple programs that provide these services. Usage of various small services (microservices) allows you to easily migrate some software components from one cloud service to another. It also minimizes the risk that the e-commerce site will become non-functional; if one of the services fails, it will be easier to scale and, as a result, save cost as you are capable of  providing additional resources on demand – autoscale. 

Kubernetes is a container orchestration platform. A natural question arises – what is a container? Let’s explain everything from the beginning. In simple words, a container allows developers to “ship” an application as a single package (container) to a machine. The container will have all dependencies required for the application to run on a machine without impacting other applications running on the same machine. 

Now imagine the previously mentioned e-commerce application consisting of tens of services. If your website grows and becomes popular, you must replicate your microservices to hundreds or thousands of units to handle more user requests. It would be hard for you to decide on which machine a particular container should be shipped (scheduled), how many containers you need now (scale), track if containers are healthy, and so on. Kubernetes helps solve autoscaling, container scheduling, and container healing problems. It orchestrates where and when containers should be shipped. The exciting thing is that Kubernetes and containerization technologies help minimize developers’ dependency on cloud providers, so it’s easier to change or expand services of the underlying cloud platform if required. 

The above characteristics led to the popularity of Kubernetes and containerization technologies among the developer community. 

Simply put, companies that want to save time or the ones that put resource provisioning and fast operations as a priority. The startup companies or big Software-as-a-Service (SaaS) providers typically implement Cloud-Native Applications.

As mentioned above, Cloud-Native Applications adopt a Microservice Architecture which brings many benefits for running applications on the cloud. However, it also brings complexity. As there are many components, it’s hard to get a holistic view of what’s happening in your application. It’s hard to oversee how components interact with each other, how they impact each other, are they secure, are there any misconfiguration, performance or security issues, etc. So achieving end-to-end observability and security of your application is challenging. 

As multiple components are involved, there’s a bigger attack surface and risk that something is missing or deployed not following good practices. For teams that are new to cloud technologies, it’s normal to assume that cloud providers will take care of all security aspects. As part of managed Kubernetes service, the most popular cloud providers deploy and look after Kubernetes “software” running on the cloud provider’s infrastructure. However, by default, the service doesn’t include periodic security patching of machines running Kubernetes components, antivirus, or other security solutions. Kubernetes is a complex system with multiple components, and it’s hard to configure everything right from the first time. Even cloud providers sometimes might miss something [9].

Misconfigurations or/and vulnerabilities of Kubernetes and applications raise the chance of various types of malicious attacks [3], which can lead to sensitive data leaks, your cloud resources misuse by crypto mining software, botnets, Denial of Service attacks, or malicious entities can simply make your service unavailable. 

Here are just a few examples of recent attacks. In 2019, a misconfiguration in Kubernetes API allowed hackers to steal Capital One customers’ bank account and security numbers information. This breach could potentially cost more than $300 million. A misconfiguration in the Kubeflow access setting allowed the seeding of cryptocurrency mining malware across multiple clusters in Azure [6]. The Tesla company was also a victim of a similar attack [8].

Of course, not only misconfigurations can cause issues. For example, to save some time, instead of building everything for containers from scratch, developers can download available and prebuilt container images from publicly available sources, like the Docker hub repository. Downloading images from public repositories can unintentionally install crypto mining software, which will use your resource for cryptocurrency mining activities. In 2017, attackers mined cryptocurrency worth around 90000 USD over ten months by spreading 17 malicious images through the Docker Hub. The images were downloaded more than 5 million times [1]. The internet is full of many more similar examples. 

In 2021, the Unit 42 team did interesting research by scanning all internet-accessible Kubernetes clusters (APIs)[5]. They’ve found more than 6000 unprotected clusters, and more than half of those were running on the cloud. On average, 15% of opened APIs could be accessed by anyone (had anonymous access enabled). And the sad thing is that other research shows that things are getting worse [7].  

Vulnerabilities in applications or Kubernetes components can lead to sensitive data loss, installation of malicious software, or cluster takeover by attackers [10]. To summarize, the most common attacks on Kubernetes can be categorized as follows:

  1. Attacks to unprotected or poorly protected management plane of Kubernetes, e.g., opened APIs; [4]
  2. Misconfigured Pods (Pod is a Kubernetes component that allows you easily manage and deploy a container or groups of containers on Kubernetes);
  3. Malicious containers;
  4. Vulnerabilities. 

To minimize the risk of previously mentioned attacks, typically, the following best practices are followed:

  • Constantly educate people about security best practices;
  • Verify that the images you’re using are safe; 
  • Verify that you’re following Kubernetes best configuration practices; 
  • Enforce your best practices;
  •  Detect issues before deployment and at runtime. 

Yes, some tools help additionally secure Cloud-Native Applications, such as automated code security engines that work quickly to detect security risks in real-time throughout the development pipeline. I also suggest using vulnerability scanners to verify nodes, Kubernetes, applications, and images prior to deployments and after in runtime to flag vulnerabilities on time.

Simply putting the best practices document in place for users most likely won’t work — it will probably be forgotten or ignored. There are multiple options of what you can do to ensure that at least some good practices are followed. You can create or use tools integrated with your application CI pipeline to validate that infrastructure-as-code artifacts meet specific requirements. You can also use Kubernetes admission controllers to admit only compliant deployments or actively scan every cluster and application running on it using vulnerability scanners.