Demystifying Kubernetes Objects: Solving Real-World Problems

Photo by Growtika on Unsplash

Demystifying Kubernetes Objects: Solving Real-World Problems

·

7 min read

Kubernetes, the powerhouse of container orchestration, provides a rich set of objects to manage and scale your applications. Each object serves a specific purpose, addressing a unique challenge in the world of distributed systems. This post tries to delve into the core Kubernetes objects, explaining the problems they solve and providing practical examples.

The Problems Kubernetes Solves

Before diving into individual objects, let's understand the broader issues Kubernetes tackles:

  • Scalability: How do we handle increasing traffic and ensure our applications can handle the load?

  • Availability: How do we ensure our applications remain available even if some nodes or pods fail?

  • Configuration Management: How do we manage application configurations across multiple environments?

  • Secrets Management: How do we securely store and manage sensitive information like passwords and API keys?

  • Persistent Storage: How do we provide persistent storage for stateful applications?

  • Service Discovery and Load Balancing: How do we enable communication between different parts of our application?

  • Node-Level Tasks: How do we run tasks on every node in the cluster?

Kubernetes Objects comes to the rescue.

Let's explore the key Kubernetes objects and the problems they solve:

1. Pods: The Smallest Deployable Unit

  • Running multiple containers directly can quickly become complex. Pods provide an abstraction for running one or more containers together, which can then be managed in a centralized way via K8s (fancy way of saying kubernetes)

  • Pods encapsulate containers, storage, and network resources. They are the fundamental building blocks of Kubernetes applications.

2. ReplicaSets/ReplicaControllers: Ensuring Desired Replica Count

  • Problem: Pods can fail. How do we ensure a desired number of replicas are always running?

  • Solution: ReplicaSets (and ReplicaControllers) maintain a stable set of Pods running at any given time. If any of the pod fails, a centralized server detects that and helps creating new pod with exact replica of what went down.

  • Example Scenario: You want to ensure that at least three instances of your web application are always running. If a pod fails, the ReplicaSet automatically creates a new one. This declarative way of managing all pods centrally is very useful when you have lot of micro-services spread across different environments.

3. Deployments: Managing ReplicaSets and Rolling Updates

  • Problem: Managing ReplicaSets directly can be cumbersome, especially during updates.

  • Solution: Deployments provide declarative updates for Pods and ReplicaSets. They enable rolling updates and rollbacks, simplifying application deployments.

  • Example Scenario: You want to deploy a new version of your application with zero downtime. Deployments handle the rolling update process, gradually replacing old pods with new ones.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image:latest
  • apiVersion: apps/v1: Specifies the API version for Deployments.

  • kind: Deployment: Defines the type of object.

  • metadata: name: my-deployment: Sets the name of the deployment.

  • spec: replicas: 3: Specifies the desired number of replicas.

  • spec: selector: matchLabels: app: my-app: Defines the labels used to select the Pods.

  • spec: template: metadata: labels: app: my-app: Defines the template for creating Pods.

  • spec: template: spec: containers: - name: my-container: image: my-image:latest: Defines the container specification.

4. Services: Abstraction for Pods

  • Problem: Pods are ephemeral. How do we provide a stable endpoint for accessing them?

  • Solution: Services provide an abstraction over a set of Pods. They provide a single DNS name or IP address that can be used to access the Pods. This indirection helps external objects connect with the pods without exactly knowing the details whether some pod went down and got replaced by new pod or not. You can think of a service as an interface to the networking stack of the application/pod. You can configure various load balancing as well.

  • Example Scenario: You have multiple Pods running your web application. Services allow other applications or users to access these Pods without knowing their individual IP addresses.

5. ConfigMaps: Managing Configuration Data

  • Problem: How do we decouple configuration data from application code?

  • Solution: ConfigMaps store configuration data as key-value pairs. They can be mounted as volumes or environment variables in Pods. A better way to provide environment variables or any values that your application might be dependent upon.

  • Example Scenario: You want to manage database connection strings or application settings in a centralized location.

6. Secrets: Managing Sensitive Data

  • Problem: How do we securely store and manage sensitive information?

  • Solution: Secrets store sensitive information like passwords, API keys, and certificates. They can be stored in an encrypted format. By default they are base64 encoded, but it is a best practice to specify that you want to encrypt the passwords at rest.

  • Example Scenario: You need to provide database credentials to your application. Secrets allow you to store these credentials securely.

7. PersistentVolumes and PersistentVolumeClaims: Persistent Storage

  • Problem: Pods are ephemeral. How do we provide persistent storage for stateful applications?

  • Solution: PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs) provide an abstraction for persistent storage. PVs are provisioned by administrators, and PVCs are requested by users. You can think of PVs as total storage on each node, and PVC is the claim you enforce on that storage or part of storage that you want to use.

  • Example Scenario: You are running a database that requires persistent storage. PVs and PVCs allow you to attach persistent storage to your database pods.

  • mountVolumes is the actual mounting of the persistant volume into the pod.

8. DaemonSets: Node-Level Tasks

  • Problem: How do we run a Pod on every node in the cluster?

  • Solution: DaemonSets ensure that a copy of a Pod runs on all (or some) Nodes in a cluster.

  • Example Scenario: You want to run a logging agent or monitoring agent on every node in the cluster. This is actually sometimes required that you want to setup one node monitoring agent on each node. If you deploy them as pod, when k8s try to create those pod on your nodes(virtual/real machines) it may end up creating all the pods on the same node(this process is called scheduling of pods, and the k8s object that does this work is called kube-scheduler)

9. StatefulSets: Managing Stateful Applications

  • Problem: How do we manage stateful applications that require stable network identities and persistent storage?

  • Solution: StatefulSets manage the deployment and scaling of stateful applications. They provide stable network identities and persistent storage for each Pod.

  • Example Scenario: You are running a distributed database like Cassandra or ZooKeeper. StatefulSets ensure that each instance of the database has a unique and stable identity.

10. Kube-Scheduler: Pod Scheduling

  • Problem: How do we decide which node a Pod should run on?

  • Solution: The kube-scheduler watches for newly created Pods with no assigned node and selects a node for them to run on.

  • Usage: It does this by considering resource requirements, node affinity, and other factors.

11. Kube-Proxy: Network Proxy

  • Problem: How do we route traffic to Pods within the cluster?

  • Solution: The kube-proxy maintains network rules on nodes. These network rules allow network communication to your Pods from network sessions inside or outside of your cluster.

  • Usage: It implements part of the Kubernetes Service concept.

Problem Scenarios and Solutions

  1. Scaling a Web Application:

    • Problem: Sudden increase in traffic.

    • Solution: Use Deployments and Horizontal Pod Autoscaling (HPA) to automatically scale the number of Pods.

  2. Managing Database Credentials:

    • Problem: Securely storing and managing database credentials.

    • Solution: Use Secrets to store the credentials and mount them into your application Pods.

  3. Running a Logging Agent:

    • Problem: Collecting logs from all nodes in the cluster.

    • Solution: Use a DaemonSet to run a logging agent on every node.

  4. Deploying a Distributed Database:

    • Problem: Needing stable network identities and persistant storage.

    • Solution: Use StatefulSets to deploy the database.

Conclusion

Kubernetes objects provide a powerful and flexible way to manage containerized applications. By understanding the problems each object solves, you can build robust and scalable applications that can handle the demands of modern workloads.