Skip to content

2.3 Deployments

3.1 Understanding Nodes and Pods in Kubernetes

Kubernetes, often referred to as K8s, is a powerful system for automating the deployment, scaling, and management of containerized applications. Two of the most fundamental concepts in Kubernetes are nodes and pods. Let’s break these down to understand their roles and how they work together within a Kubernetes cluster.

1. What is a Node in Kubernetes?

A node is a worker machine in Kubernetes. It can be either a physical server or a virtual machine, depending on the environment in which Kubernetes is running. Each node in a Kubernetes cluster runs the services necessary to manage the networking between the containers, the communication with the master, and the assigned workloads.

Key components of a node include:

  • Kubelet: An agent that runs on each node and ensures that the containers are running in a pod.
  • Kube-proxy: A network proxy that runs on each node, maintaining network rules and enabling communication between different parts of the cluster.
  • Container Runtime: The software responsible for running containers. Docker is the most commonly used runtime, but alternatives like containerd or CRI-O can also be used.

Example: Imagine you have a Kubernetes cluster running on three virtual machines (VMs). Each VM represents a node in the cluster. When you deploy an application, Kubernetes schedules the application’s components (containers) to run on one or more of these nodes.

2. What is a Pod in Kubernetes?

A pod is the smallest and simplest Kubernetes object. It represents a single instance of a running process in your cluster. Pods are the unit of deployment in Kubernetes and can contain one or more tightly coupled containers. All containers in a pod share the same network namespace (IP address and port space) and can communicate with each other directly using localhost.

Key characteristics of a pod:

  • Single or Multiple Containers: A pod can run a single container, but it can also run multiple containers that need to work together (e.g., a web server container and a logging container).
  • Shared Resources: Containers within a pod share storage volumes and a network IP, allowing them to communicate easily and efficiently.
  • Lifecycle Management: Pods are ephemeral, meaning they can be created and destroyed as needed. Kubernetes ensures that the desired number of pods are running at all times.

Example: Consider an e-commerce application where you have a web server and a Redis cache. You might deploy both the web server and Redis in a single pod. Since they share the same IP address, the web server can easily connect to Redis using localhost. If the web server fails, Kubernetes can restart the pod to ensure that the application remains available.

3. How Nodes and Pods Work Together

When you deploy an application in Kubernetes, the platform schedules pods to run on nodes. For example, if you have three nodes and deploy an application that requires five instances (pods), Kubernetes might place two pods on the first node, two on the second node, and one on the third node, depending on resource availability and other factors like load balancing.

Example Scenario: Suppose you have a Kubernetes cluster with three nodes. You want to deploy a microservice-based application that has the following components:

  • Frontend (web server)
  • Backend (API server)
  • Database (PostgreSQL)

You define each of these components as a separate pod. Kubernetes schedules these pods across the available nodes. If one of the nodes goes down, Kubernetes can reschedule the pods to run on the remaining healthy nodes, ensuring the application remains up and running.

4. Keypoints

  • Nodes are the worker machines in a Kubernetes cluster that run your applications.
  • Pods are the smallest deployable units in Kubernetes, representing a single instance of a running process.

Nodes and pods are the building blocks that Kubernetes uses to manage, scale, and ensure the high availability of applications. Understanding these concepts is crucial for anyone working with Kubernetes, as they are fundamental to how the platform operates and handles containerized workloads.

3.2 Kubernetes Deployment

https://youtu.be/DMpEZEakYVc

In the ever-evolving landscape of software development and deployment, Kubernetes has become a cornerstone for managing containerized applications at scale. In this guide, we will dive into the basics of Kubernetes deployments, exploring how they enable the management of desired states and how to effectively use Kubernetes tools to ensure smooth operations.

1. Introduction to Kubernetes Deployments

Kubernetes is a powerful tool for automating the deployment, scaling, and management of containerized applications. In previous discussions, we explored setting up Kubernetes on Docker for Windows and using the command-line utility kubectl to interact with Kubernetes clusters. Now, with Kubernetes running and kubectl at our disposal, we’ll focus on the Kubernetes deployment object—a key component that allows us to configure and manage application deployments effectively.

2. What is a Kubernetes Deployment?

A Kubernetes deployment is an object that defines the desired state of your application and the deployment strategy to achieve that state. The deployment controller in Kubernetes ensures that the actual state of your application aligns with the desired state, adjusting the infrastructure as needed.

To understand the concept of deployment in Kubernetes, consider the traditional approach to managing production servers. Typically, this involves load-balanced servers running various scripts to maintain health and functionality. However, scripts are inherently fragile—they execute steps sequentially, and failure at any point can leave the system in an unstable state.

3. The Power of Desired State

Kubernetes addresses the shortcomings of traditional scripting by leveraging the concept of desired state. Instead of relying on scripts to set up and manage servers, Kubernetes allows you to define the desired state of your application in a deployment file. For example, you might specify that version 1 of your application should always have at least two instances running for high availability and load balancing. Kubernetes then takes on the responsibility of ensuring that this desired state is maintained.

This approach offers numerous advantages, including automatic handling of updates, seamless rollouts, and infrastructure resilience. Kubernetes can gracefully upgrade your application by draining traffic from the old version before introducing the new one. It can also automatically recover from infrastructure failures by redeploying your application on healthy nodes. Moreover, Kubernetes allows you to scale your application up or down to meet demand without worrying about port conflicts or underlying infrastructure.

4. Defining a Kubernetes Deployment

A Kubernetes deployment is defined using a YAML file that specifies the desired state of your application. Key elements of a deployment YAML file include:

  • Application Version: The version of your application to deploy.
  • Replicas: The number of instances (pods) to run for high availability.
  • Strategy: The deployment strategy, such as a rolling update, which ensures a smooth transition between application versions.
  • Ports: The ports to expose for your application.
  • Liveliness Probe: A health check that allows Kubernetes to monitor the application and restart it if necessary.
  • Resource Limits: The CPU and memory limits that Kubernetes uses to make intelligent scheduling decisions and manage resources effectively.

5. Understanding Pods in Kubernetes

At the core of Kubernetes is the concept of a pod. A pod is the smallest deployable unit in Kubernetes and can be thought of as a virtual machine hosting your application. A pod can contain one or more containers, which run the actual processes (applications) you want to deploy. For example, a pod might contain your main application along with a Redis cache and a monitoring agent, all working together in the same environment.

6. Deploying with kubectl

To deploy your application using Kubernetes, you use the kubectl command-line tool. The basic process involves applying your deployment YAML file with the command:

Terminal window
kubectl apply -f <path-to-deployment-yaml>

This command sends your desired state to Kubernetes, which then manages the deployment process, ensuring that your application is running as specified.

You can also monitor and troubleshoot deployments using commands like:

  • kubectl get deployments to check the status of your deployment.
  • kubectl describe deployment <deployment-name> to get detailed information about your deployment, including statuses, resource usage, and events.
  • kubectl get pods to view the status of individual pods.
  • kubectl logs <pod-name> to view logs for troubleshooting application errors.

3.3 Example

Here’s an example of a simple Kubernetes Deployment YAML file that defines a deployment for an Nginx web server. This YAML file describes how Kubernetes should create and manage the pods running the Nginx container.

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # Number of desired pods
selector:
matchLabels:
app: nginx # Label selector for pods
template:
metadata:
labels:
app: nginx # Label applied to pods
spec:
containers:
- name: nginx
image: nginx:1.21.6 # Image version
ports:
- containerPort: 80 # Exposing port 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"

Breakdown of the Deployment YAML File

  • apiVersion: Specifies the API version of the Kubernetes object (in this case, apps/v1 is used for Deployments).
  • kind: Defines the type of Kubernetes object (Deployment).
  • metadata: Contains information about the deployment, including its name (nginx-deployment) and labels (app: nginx).
  • spec: Describes the desired state of the deployment.
    • replicas: The number of pod replicas (3) that should be running.
    • selector: A label selector to identify the pods managed by this deployment.
    • template: The pod template that describes the pods to be created.
      • metadata: Contains labels for the pods.
      • spec: Defines the containers to run inside the pod.
        • containers: Specifies the container to run:
          • name: The name of the container.
          • image: The container image to use (nginx:1.21.6).
          • ports: The ports to expose (containerPort: 80).
          • livenessProbe: Defines a probe that checks if the container is healthy. If the probe fails, Kubernetes will restart the container.
          • resources: Specifies resource requests and limits:
            • limits: The maximum resources the container can use.
            • requests: The minimum resources the container needs.

How to Apply This Deployment

To deploy this YAML file, save it as nginx-deployment.yaml and use the following command:

Terminal window
kubectl apply -f nginx-deployment.yaml

This command will create the deployment, and Kubernetes will start managing the pods as specified.

3.4 Example Redis Client Server

To set up a Redis client and server using Kubernetes Deployments, you can define two separate Deployment YAML files: one for the Redis server and another for a simple Redis client. Here’s how to do it:

1. Redis Server Deployment

This Deployment creates a Redis server that listens on port 6379.

apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-server
labels:
app: redis
spec:
replicas: 1
selector:
matchLabels:
app: redis
tier: backend
template:
metadata:
labels:
app: redis
tier: backend
spec:
containers:
- name: redis
image: redis:6.2.6 # Redis image version
ports:
- containerPort: 6379 # Exposing Redis port
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
labels:
app: redis
spec:
selector:
app: redis
tier: backend
ports:
- protocol: TCP
port: 6379
targetPort: 6379
type: ClusterIP # Internal access only

2. Redis Client Deployment

This Deployment creates a simple Redis client that can connect to the Redis server.

apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-client
labels:
app: redis-client
spec:
replicas: 1
selector:
matchLabels:
app: redis-client
template:
metadata:
labels:
app: redis-client
spec:
containers:
- name: redis-client
image: redis:6.2.6 # Using the Redis image to access the Redis CLI
command: [ "sh", "-c", "while true; do sleep 30; done;" ] # Keeps the pod running

3. How to Connect the Client to the Server

After deploying both the Redis server and client, you can connect to the Redis client pod and use the Redis CLI to connect to the Redis server. Here’s how:

  1. Get the name of the Redis client pod:

    Terminal window
    kubectl get pods -l app=redis-client
  2. Use kubectl exec to open a shell in the Redis client pod:

    Terminal window
    kubectl exec -it <redis-client-pod-name> -- /bin/sh
  3. From within the client pod, use the Redis CLI to connect to the Redis server:

    Terminal window
    redis-cli -h redis-service

    The -h redis-service flag tells the Redis client to connect to the Redis server using the service name redis-service.

Breakdown of the YAML Files

  • Redis Server Deployment:

    • The Redis server is deployed with one replica.
    • The server is exposed internally within the cluster using a ClusterIP service.
  • Redis Client Deployment:

    • The Redis client is deployed with one replica.
    • The client pod contains the Redis CLI, which can be used to connect to the Redis server.

By running these Deployments, you’ll have a Redis server and a client running in your Kubernetes cluster, allowing you to test Redis interactions within the cluster.