Kubernetes Deployments: A Comprehensive Guide

Kubernetes, a favorite in the developer community, is a widely used platform for running Docker containers in clusters. This powerful platform offers different methods for you to deploy and update applications running in containers, thereby providing a high level of flexibility for different scenarios. In Kubernetes, containers run in pods, and their deployment is defined by Kubernetes Deployments. This blog post covers Kubernetes Deployments, their types, deployment strategies, and best practices.

Try NAKIVO Backup & Replication

Try NAKIVO Backup & Replication

Get a free trial to explore all the solution’s data protection capabilities. 15 days for free. Zero feature or capacity limitations. No credit card required.

What Is a Kubernetes Deployment?

A Deployment in Kubernetes is a resource object that manages the deployment and lifecycle of containerized applications in clusters. It provides updates to applications, ensuring that the needed number of identical pods are running and available at all times. It also provides declarative updates for Pods and ReplicaSets. Deployments are a key feature in Kubernetes for automating scaling, rolling updates, and rollbacks.

Deployment is a Kubernetes object that specifies the desired state for Pods, and it creates and manages ReplicaSets to ensure that this state is maintained. A ReplicaSet manages Pods directly, including their state and number. Deployment tells Kubernetes how to modify or create the Pod instances that hold containers with applications. The state of Pod deployment is described in a manifest.

Administrators can scale the number of replica pods efficiently, perform rollout of updated application code with a high level of control, and roll back to earlier versions of deployments if needed. To manage Kubernetes Deployments, administrators use the command-line kubectl tool on Linux and other supported operating systems. Each pod created with a Deployment has a ReplicaSet related to this pod. A ReplicaSet, in turn, has a pointer to the Deployment which created this ReplicaSet.

Fundamentals of Kubernetes Deployments

Kubernetes Deployments are developed to deploy and scale containerized applications in clusters. Deployments provide a declarative way to define the desired state of your application and automate the process of reaching and maintaining that state. The fundamental concepts and components related to Kubernetes Deployments are:

  • Desired state. The Deployment defines the desired state of an application, such as the number of replicas of a pod, the container images to use, and the resources allocated to each pod.
  • Declarative configuration. Deployments usually use a declarative approach, where administrators specify the state in a JSON or YAML file. While the imperative approach allows administrators to set what to do directly, the declarative approach in Kubernetes allows administrators to define the required result, and Kubernetes will achieve that with its internal mechanisms. The Kubernetes Deployment controller monitors the health of nodes and pods. If there are real-time changes, such as a pod failure, then this pod can be replaced. Thus, Kubernetes monitors the state of the cluster in real time and makes adjustments to match the desired state.
  • ReplicaSet. A Deployment manages a ReplicaSet. The ReplicaSet creates and deletes pods as necessary to maintain the desired number of replicas. This approach allows Kubernetes to ensure that pod replicas that are specified are running at any given time.
  • Rolling updates. Deployments support rolling updates, which allow you to update the application without downtime. Kubernetes gradually replaces old pods with new pods, which helps ensure that the containerized application remains in the available state during the Deployment update process.
  • Rollback. If something goes wrong during an update in Kubernetes, you can roll back to a previous version of the Deployment, restoring the application to a known good state.

Declarative configuration

In Kubernetes, a declarative approach means you specify the desired state of the system, and Kubernetes takes the necessary actions to achieve and maintain that state. You describe the end goal using configuration files (typically written in YAML or JSON), and Kubernetes continuously works to ensure the actual state matches the desired state.

The declarative approach is generally preferred in Kubernetes because it can maintain the desired state consistency, facilitate automation, and support better collaboration and version control. The imperative approach can be useful for quick, ad-hoc tasks but is less suitable for managing complex, long-term application deployments.

How Deployments, Pods, and ReplicaSets work together

In Kubernetes, Deployments, Pods, and ReplicaSets are closely related components that collectively manage the deployment, scaling, and lifecycle of applications. It is important to understand the relationship between them and know how they work together in Kubernetes for proper configuration.

  • A Pod is the simplest and smallest object in a Kubernetes cluster and represents a single instance of a running process. A Pod can contain one or more containers that share the same storage volumes and network namespace. Pods are ephemeral by design because they can be created and destroyed as needed to match the desired state specified by higher-level objects like Deployments.
  • A ReplicaSet ensures that a specified number of identical Pods are running at any given time. It manages the creation and deletion of Pods to maintain the desired number of replicas. Each ReplicaSet uses label selectors to identify and manage the Pods under its control, ensuring the correct Pods are maintained. While you can directly create and manage ReplicaSets, they are typically managed by Deployments, which provide additional functionalities.
  • A Deployment is a higher-level Kubernetes object that manages ReplicaSets and provides declarative updates to applications. Deployments allow administrators to define the needed state of your application and other settings, as explained above.

When you create or update a Deployment, it automatically creates a new ReplicaSet to manage the Pods according to the defined specifications. Each time you update a Deployment, a new ReplicaSet is created to handle the new version of the Pods, while the old ReplicaSet remains until the new Pods are successfully rolled out. This ensures that updates are implemented in a controlled manner, maintaining application availability.

The Deployment manages the lifecycle of Pods indirectly through its ReplicaSets. By defining the desired state in the Deployment, you specify the characteristics and number of Pods you want to run. The Deployment then ensures this state by managing the appropriate ReplicaSets, which in turn manage the Pods.

Thus, Pods are the execution units running containers, ReplicaSets ensure the needed number of Pods are running, and Deployments provide declarative management and updates for applications by controlling ReplicaSets. This hierarchical structure ensures that your applications are scalable, resilient, and easy to manage. Deployments abstract the complexities of directly managing ReplicaSets and pods, offering a powerful way to handle application updates and scaling.

Deployment Configuration Details

Using YAML for Deployment configuration in Kubernetes is a common practice because of its readability and simplicity. Kubernetes supports both YAML and JSON formats for configuration files, but YAML is more widely used due to its human-friendly syntax.

YAML (YAML Ain’t Markup Language) is a data serialization standard that is both human-readable and easy to write. It is commonly used for configuration files and data exchange between languages with different data structures. In Kubernetes, YAML is used to define the desired state of various objects, including Deployments, Services, Pods, and more.

Key components of a YAML Deployment file:

  • apiVersion is used to specify the API version (for example, apps/v1) of the Kubernetes object.
  • kind specifies the type of Kubernetes object (for example, Deployment).
  • metadata contains metadata about the object, such as its name and labels.
  • spec (specification) is used to define the desired state of the Kubernetes object, including:
    • replicas specifies the number of pod replicas to maintain.
    • selector specifies how to identify the pods managed by the Deployment.
    • template defines the pod template, including metadata and specs for the pods.
    • containers lists the containers within the pod, including:
      • name: the name of the container
      • image: the docker image to use
      • ports: the ports to expose

The differences between YAML and JSON for Kubernetes Deployment configuration syntax are:

  • YAML is more human-readable, using indentation and key-value pairs without braces or brackets.
  • JSON uses a more rigid structure with braces ({}) and brackets ([]), making it less readable for complex configurations.

YAML is usually preferred for Kubernetes Deployments.

YAML Deployment Example

Below, you can see a Kubernetes deployment example in the YAML format with detailed configurations for pods and containers.

apiVersion: apps/v1

kind: Deployment

metadata:

  name: deployment-name

spec:

  replicas: 3

  selector:

    matchLabels:

      app: app-name

  template:

    metadata:

      labels:

        app: app-name

    spec:

      containers:

      – name: container-name

        image: image-name:1.0

        ports:

        – containerPort: 80

        resources:

          requests:

            memory: “128Mi”

            cpu: “250m”

          limits:

            memory: “256Mi”

            cpu: “500m”

        env:

        – name: MY_ENV_VAR

          value: “some-value”

        volumeMounts:

        – mountPath: “/path/volume”

          name: volume-name

      volumes:

      – name: volume-name

        persistentVolumeClaim:

          claimName: pvc-name

Let’s explain each section in detail to make it clearer. By configuring these sections, you can define a robust and scalable application deployment in Kubernetes, ensuring that your pods and containers are set up according to your requirements.

Key configuration sections

1. Metadata

metadata:

  name: deployment-name

Where:

name: the name of the Deployment

2. Spec (Deployment specification)

spec:

  replicas: 3

  selector:

    matchLabels:

      app: app-name

Where:

replicas: the number of pod replicas to maintain

selector: defines how to identify the pods managed by the deployment using labels

3. Pod Template (Pod specification)

template:

  metadata:

    labels:

      app: app-name

  spec:

    containers:

    – name: container-name

      image: image-name:1.0

Where:

metadata: labels to identify the pods

spec: configuration for the pods and their containers

Configuring containers

In this part, you can see YAML sections of Deployments to configure containers.

1. Container image

image: image-name:1.0

Where:

image: the container image to use. It can include a tag (e.g., 1.0) to specify the version.

2. Ports.

ports:

– containerPort: 80

Where:

containerPort: the port on which the container will listen for traffic

3. Resource requests and limits

resources:

  requests:

    memory: “128Mi”

    cpu: “250m”

  limits:

    memory: “256Mi”

    cpu: “500m”

Where:

requests: the minimum resources required

limits: the maximum resources the container can use

4. Environment variables

env:

– name: MY_ENV_VAR

  value: “some-value”

Where:

env: defines environment variables for the container

5. Volume mounts

volumeMounts:

– mountPath: “/path/volume”

  name: volume-name

Where:

volumeMounts: specifies volumes to mount inside the container

mountPath: the path inside the container where the volume will be mounted

Configuring volumes

The volumes section is responsible for configuring volumes.

volumes:

– name: volume-name

  persistentVolumeClaim:

    claimName: pvc-name

Where:

volumes: defines the volumes available to be mounted

name: the name of the volume

persistentVolumeClaim: specifies a PersistentVolumeClaim (PVC) to use for the volume

Advanced configurations

1. Liveness and readiness probes

livenessProbe:

  httpGet:

    path: /healthz

    port: 8080

  initialDelaySeconds: 3

  periodSeconds: 3

readinessProbe:

  httpGet:

    path: /ready

    port: 8080

  initialDelaySeconds: 5

  periodSeconds: 10

Where:

livenessProbe: checks if the container is alive

readinessProbe: is used to check whether the current container is ready to accept traffic

2. Command and arguments

command: [“my-command”]

args: [“arg1”, “arg2”]

Where:

command: overrides the default entry point of the container

args: specifies arguments to the command

3. ConfigMaps and secrets

envFrom:

– configMapRef:

  name: my-configmap

– secretRef:

  name: my-secret

Where:

envFrom: imports environment variables from a ConfigMap or secret

The Kubernetes Deployment Strategy

There are multiple Kubernetes deployment strategies (types), and you can select the most effective for your current scenario. Business applications have different requirements for uptime and availability. Selecting the right strategy allows you to avoid downtime and service disruption as well as use resources effectively. Below, you can see the most common Kubernetes deployment types.

Rolling Updates and Rollbacks

A rolling update Deployment presumes migration from one application version to another, the newer version in the defined order. A new ReplicaSet is launched with the new version of the application. The replicas of the old version are terminated. As a result, the old-version pods are replaced with the new ones. The rolling update provides the ability to transition smoothly from old versions to new ones but the operation requires some time to complete.

Recreate Deployment

The pods that are currently running are terminated and then are recreated with a new version. This deployment strategy is commonly used in Kubernetes environments for developers where the user activity is not an issue. There is downtime when the old deployment is shut down, the recreate deployment strategy initiates the new deployment instances, and recreates pods and the application’s state.

Blue-Green Deployments

The Blue-Green deployment is another way to update applications in Kubernetes but with rapid transition. The Kubernetes Blue-Green deployment presumes running two environments: the old (blue) version and the new (green) version. Both of them are deployed “side-by-side” or in parallel. Once the new version is tested and its proper operation is confirmed (it works as designed), then the version label is replaced by updating the Service Selector. This action is performed for a Kubernetes Service object that is performing load balancing in a cluster. After that, the traffic is switched to the new version immediately.

The Kubernetes Blue-Green deployment strategy allows administrators to perform rapid rollout without the issues caused by different versions when making the transition between them. Keep in mind that resource utilization is higher because two environments are running in parallel for a certain period.

Canary Deployments

The Kubernetes canary deployment presumes routing only a small group of users to the new version of a containerized application. The new version runs on a smaller subset of pods than the older version that has been running until that time. The main purpose of canary deployments is to test the functionality of new application versions in a production environment. If errors are missing in the new version, then administrators scale up the new version, and the previous version is replaced in the appropriate order.

If something goes wrong after the deployment of the new version for a small group of users, then administrators can roll back canary deployments to the older version. The advantage is the ability to test the new functionality on a small user group without the risk of negative effects on overall system operation.

Kubernetes Recreate Deployment

When using the Recreate Deployment, all pods are terminated and replaced with the new version. This strategy can be used when the old and new versions cannot run simultaneously. The downtime depends on the time needed to shut down the old application and start the new application in containers. When finished, the application state is completely renewed.

Scaling and Management

Scaling and managing Kubernetes Deployments are crucial to ensure that your containerized apps can work with varying workloads and maintain high availability. Kubernetes provides robust mechanisms for both manual and automated scaling, as well as tools for managing deployments efficiently.

Manual Scaling

Manual scaling is used to adjust the number of replicas (instances) of your application manually using the kubectl command-line tool.

  • Scaling up:

    kubectl scale deployment deployment-name replicas=10

    This command increases the number of replicas for my-deployment to 10.

  • Scaling down:

    kubectl scale deployment deployment-name replicas=2

    This command decreases the number of replicas for my-deployment to 2.

Horizontal Pod Autoscaler (HPA)

The Horizontal Pod Autoscaler (HPA) automatically adjusts the number of pod replicas based on observed CPU utilization or other select metrics.

  1. The command for creating an HPA is:

    kubectl autoscale deployment deployment-name cpu-percent=50 min=2 max=10

    This command sets up an HPA for deployment-name to maintain CPU utilization at around 50%, scaling between 2 and 10 replicas.

  2. HPA configuration in YAML is a more advanced way. An example of an YAML deployment configuration for horizontal autoscaling is explained below.

    apiVersion: autoscaling/v1

    kind: HorizontalPodAutoscaler

    metadata:

      name: deployment-hpa-name

    spec:

      scaleTargetRef:

        apiVersion: apps/v1

        kind: Deployment

        name: deployment-name

      minReplicas: 2

      maxReplicas: 10

      targetCPUUtilizationPercentage: 50

    Apply the YAML configuration with:

    ubectl apply -f hpa.yaml

Vertical Pod Autoscaler (VPA)

The Vertical Pod Autoscaler (VPA) automatically adjusts the resource requests and limits of pods to match the actual usage. VPA Configuration in YAML is as follows:

apiVersion: autoscaling.k8s.io/v1

kind: VerticalPodAutoscaler

metadata:

  name: deployment-vpa-name

spec:

  targetRef:

    apiVersion: “apps/v1”

    kind: Deployment

    name: deployment-name

  updatePolicy:

    updateMode: “Auto”

To apply the YAML configuration, use the command:

kubectl apply -f vpa.yaml

Best Practices for Kubernetes Deployments

The correct configuration of Kubernetes deployments ensures a successful and reliable environment for running containerized applications. Incorrect configuration or an incorrect deployment management strategy can lead to downtimes, data loss, among other issues. The best practices for Kubernetes Deployments help ensure that your applications are resilient, scalable and maintainable.

  • Use declarative configuration. Store your Kubernetes configurations in version-controlled files in the YAML/JSON format. This makes it easier to manage changes and roll back if needed. Use kubectl apply -f to apply these configurations, as it allows for idempotent operations, ensuring that the state of the cluster matches the configuration files.
  • Use namespace isolation. Use namespaces to logically isolate different environments (for example, dev, staging, production) and teams. This helps manage resources and permissions more effectively.
  • Resource requests and limits. Define resource requests and limits for your pods to ensure they have the necessary resources and to prevent resource contention.
  • Liveness and readiness probes. Configure liveness probes to restart unhealthy containers and readiness probes to control traffic to containers.
  • Use labels and selectors to organize and select resources. Labels can be used for grouping resources by application, environment, version, etc.
  • Use ConfigMaps and secrets. Store non-sensitive configuration data in ConfigMaps. Store sensitive data, including passwords and API keys, in Secrets.
  • Monitor and log your environment. Implement monitoring using tools like Grafana and Prometheus to check the performance and health of your containerized applications. Use centralized logging solutions like the ELK stack (Elasticsearch, Logstash, Kibana) or Fluentd to collect and analyze logs.
  • Follow security best practices. Implement Pod Security Policies to enforce security standards on your pods. Use Network Policies for Kubernetes deployments to control traffic between pods.
  • Prepare for backups and disaster recovery. Implement regular backups of your Kubernetes resources and persistent data. Plan and test disaster recovery strategies to ensure that applications and services can be quickly restored in case of a failure.

Conclusion

Kubernetes Deployments play a crucial role in managing the lifecycle of applications within a Kubernetes cluster. They provide a declarative approach to defining the desired state of applications, including the number of replicas, container images, and configuration settings. By orchestrating ReplicaSets, Deployments ensure that the specified number of Pods are running and automatically handle updates and rollbacks in a controlled and seamless manner. This results in enhanced scalability, resilience, and ease of management for applications, making Kubernetes Deployments an essential tool for modern application deployment and operations.

Try NAKIVO Backup & Replication

Try NAKIVO Backup & Replication

Get a free trial to explore all the solution’s data protection capabilities. 15 days for free. Zero feature or capacity limitations. No credit card required.

People also read