Skip to main content

Command Palette

Search for a command to run...

Day-3-kubernetes

Understanding Kubernetes Deployments: DaemonSets and StatefulSets Explained

Updated
7 min read
G

Experienced DevOps Engineer with expertise in CI/CD automation, cloud infrastructure, Kubernetes, and GitOps. Provisioned a Jenkins server on AWS EC2 for automated deployments, integrating Terraform to provision VPCs and EKS clusters. Configured a Jump Server for secure Kubernetes access and implemented ArgoCD for GitOps-driven deployments. Integrated SonarQube for static code analysis and enforced quality gates in Jenkins pipelines. Built AWS ECR repositories and automated Docker image management. Ensured security by managing secrets in Jenkins Credentials Manager and implementing IAM policies for AWS resources. Configured Kubernetes Ingress via ArgoCD and deployed MongoDB with persistence strategies. Designed multi-branch Jenkins pipelines for different environments. Installed Prometheus and Grafana for monitoring with automated alerts. Optimized costs using AWS CloudWatch and Lambda for unused resource cleanup. Ensured end-to-end automation, security, and observability.

TLDR: This blog post explores Kubernetes deployments, focusing on DaemonSets and StatefulSets. It explains their purposes, advantages, and practical applications, including deployment strategies, rolling updates, and self-healing features.

Kubernetes is a powerful platform for managing containerized applications, and understanding its deployment strategies is crucial for effective application management. In this post, we will delve into two important types of deployments: DaemonSets and StatefulSets. We will also explore the concept of deployments in Kubernetes, including their advantages and practical applications.

What are Deployments?

Deployments in Kubernetes are a way to manage the lifecycle of applications. They provide a declarative way to ensure that the desired state of an application is maintained. This includes scaling, updating, and rolling back applications as needed. The major advantages of using deployments include:

  • Scalability: Deployments allow you to easily scale applications by adjusting the number of replicas.

  • Automation: Kubernetes automates the management of application updates and rollbacks, ensuring minimal downtime.

  • Self-healing: If a pod fails, Kubernetes automatically replaces or restarts it to maintain the desired state.

  • Load balancing: Deployments distribute network traffic evenly across multiple pods, enhancing application performance.

DaemonSets

What is a DaemonSet?

A DaemonSet ensures that a specific pod runs on all (or a subset of) nodes in a Kubernetes cluster. This is particularly useful for applications that need to run on every node, such as log collectors or monitoring agents. For example, if you have a master node and three worker nodes, a DaemonSet will deploy a pod on each of these nodes to collect metrics or logs.

Use Cases for DaemonSets

DaemonSets are primarily used for:

  • Monitoring: Deploying monitoring agents like Prometheus exporters on each node to collect metrics.

  • Logging: Running log aggregators on all nodes to gather logs for analysis.

StatefulSets

What is a StatefulSet?

StatefulSets are designed for stateful applications, such as databases. Unlike regular deployments, StatefulSets maintain a unique identity for each pod, which is crucial for applications that require stable network identities and persistent storage. For instance, when deploying a SQL database, each instance must retain its identity to ensure data consistency.

Importance of StatefulSets

StatefulSets are essential for:

  • Data Persistence: They ensure that data is not lost when pods are restarted or rescheduled.

  • Stable Network Identities: Each pod in a StatefulSet has a unique hostname and stable network identity, which is vital for database operations.

Deployment Strategies

Replica Sets

A ReplicaSet is a component of a deployment that ensures a specified number of pod replicas are running at any given time. This is crucial for high availability and load balancing. When you scale a deployment, the ReplicaSet manages the distribution of pods across the nodes.

Rolling Updates

Rolling updates allow you to update your application without downtime. You can specify parameters such as:

  • Max Surge: The maximum number of pods that can be created above the desired number during an update.

  • Max Unavailable: The maximum number of pods that can be unavailable during the update process.

This strategy ensures that at least some instances of your application remain available while updates are applied.

Practical Implementation

To illustrate these concepts, let’s walk through a practical example of creating a deployment with a rolling update strategy:

  1. Create a Deployment: Use the kubectl command to create a deployment with a specified number of replicas.

  2. Set Update Strategy: Define the rolling update strategy in the deployment manifest, specifying maxSurge and maxUnavailable.

  3. Monitor Updates: As you update the application version, observe how Kubernetes manages the transition between versions without downtime.

Example Command

kubectl create deployment test-pod --image=myapp:v1 --replicas=6

Exposing Applications

Once your application is running, you may want to expose it to the outside world. This can be done using services, which provide stable endpoints for accessing your applications.

Conclusion

Understanding Kubernetes deployments, including DaemonSets and StatefulSets, is essential for managing containerized applications effectively. By leveraging these deployment strategies, you can ensure high availability, data persistence, and seamless updates for your applications. As you continue to explore Kubernetes, remember to practice these concepts to solidify your understanding and enhance your skills in managing containerized environments.

kubectl create deployment testpod1 --image kiran2361993/kubegame:v1 --replicas 6 --dry-run -o yaml
# copy the deployment code -> paste it to vscode
apiVersion: apps/v1
kind: Deployment
metadata:
  # creationTimestamp: null
  labels:
    app: testpod1
  name: testpod1
spec:
  replicas: 6
  selector:
    matchLabels:
      app: testpod1
  strategy: {}
  template:
    metadata:
      # creationTimestamp: null
      labels:
        app: testpod1
    spec:
      containers:
      - image: kiran2361993/kubegame:v1
        name: kubegame
        # resources: {}
#status: {}
ku get pods  # <deployment-name>-<replicaset-name>-<pod-name> -> 6 replica (labels)
apiVersion: apps/v1
kind: Deployment
metadata:
  # creationTimestamp: null
  labels:
    app: testpod1
  name: testpod1
  annotations:  # for ingress controller -> ALB & NLB
    info : "gokul deployment"
    email: "goku.dev.job"
    owner: "gokul"
spec:
  replicas: 6
  selector:
    matchLabels:
      app: testpod1
  strategy: {}
  template:
    metadata:
      # creationTimestamp: null
      labels:
        app: testpod1
    spec:
      containers:
      - image: kiran2361993/kubegame:v1
        name: kubegame
      - image: kiran2361993/mydb:v1  # for db
        name: mysqldb
        env :                        # for storing env variables
         - name : DB_NAME
           value : "mysqldb"
         - name : DB_PORT
           value : "3306"
         - name : DB_URL
           value : ""
      # resources: {}
#status: {}

# crtl+shift+p -> format
echo '<paste ymal>'  | ku apply -f -

# to see env variables - 1st way
ku describe pod # to see port no and url of db

# to see env variables - 2nd way
ku get pods # to see names 
ku get pods -o wide # to see ip-add
ku exec -it <deployment-name>-<replicaset-name>-<pod-name> --bash
env
exit
# expose app - 1st container
kubectl expose deployment testpod1 --name svc1 --port 8000 --target-port 80 --type NodePort

#expose db - 2nd container
kubectl expose deployment testpod1 --name svc2 --port 5000 --target-port 5000 --type NodePort

ku get svc -o wide # to see ip-add  (svc1->8000:32501, svc2->5000:31058)

# add inbould rules of this port in security group (control-plane -> security group ->edit inbound rules)
# TCP, 32501 , anywhere
# TCP, 31058 , anywhere

# copy control-plane -> dns-ip
# <dns-ip>:32501 -> can be opened in browser
apiVersion: apps/v1
kind: Deployment
metadata:
  # creationTimestamp: null
  labels:
    app: testpod1
  name: testpod1
spec:
  replicas: 6
  selector:
    matchLabels:
      app: testpod1
  strategy: {}
  template:
    metadata:
      # creationTimestamp: null
      labels:
        app: testpod1
    spec:
      containers:
      - image: kiran2361993/kubegame:v1
        name: kubegame
        # resources: {}
#status: {}
kubectl delete deployment.app testpod1

kubectl explain deployment.spec.strategy
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: testpod1
  name: testpod1
spec:
  strategy:     # rollingUpdate strategy
   rollingUpdate:
     maxSurge: 1
     maxUnavailable: 0%
  replicas: 6
  selector:
    matchLabels:
      app: testpod1
  template:
    metadata:
      labels:
        app: testpod1
    spec:
      containers:
      - image: kiran2361993/kubegame:v1
        name: kubegame
echo '<paste ymal>'  | ku apply -f -
watch kubectl get pods

# management server -> connect 
sudo su -
kubectl edit deployment.app testpod1
# change image version v1->v2 
# ctrl+x -> to exit
# y -> to save file
ku get pods -o wide   # multiple pods deployed to same instance -> 2pod on same instance

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: testpod1
  name: testpod1
spec:
  minReadySeconds: 10   # after every 10 sec
  strategy:    
   rollingUpdate:   # rollingUpdate strategy
     maxSurge: 1    # 1 image of v1 will terminated -> 1 image of v2 will be created 
     maxUnavailable: 0%   # all 6 replica should be available
  replicas: 6
  selector:
    matchLabels:
      app: testpod1
  template:
    metadata:
      labels:
        app: testpod1
    spec:
      containers:
      - image: kiran2361993/kubegame:v2
        name: kubegame
echo '<paste ymal>'  | ku apply -f -
ku get pods -o wide   # multiple pods deployed to same instance -> 2pod on same instance
kubectl delete deployment.app testpod1

apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: testpod1
  name: testpod1
spec:
  #minReadySeconds: 10   # after every 10 sec
  #strategy:    
   #rollingUpdate:   # rollingUpdate strategy
     #maxSurge: 1    # 1 image of v1 will terminated -> 1 image of v2 will be created 
     #maxUnavailable: 0%   # all 6 replica should be available
  #replicas: 6
  selector:
    matchLabels:
      app: testpod1
  template:
    metadata:
      labels:
        app: testpod1
    spec:
      containers:
      - image: kiran2361993/kubegame:v2
        name: kubegame
echo '<paste ymal>'  | ku apply -f -
ku get pods -o wide   # single pods deployed to same instance