EKS

How to ensure high availability for pods in Kubernetes

I was thinking the other day about these Kubernetes pods, and how they’re like little spaceships floating around in the cluster. But what happens if one of those spaceships suddenly vanishes? Poof! Gone! That’s a real problem. So I started wondering, how can we ensure our pods are always there, ready to do their job, even if things go wrong? It’s like trying to keep a juggling act going while someone’s moving the floor around you…

Let me tell you about this tool called Karpenter. It’s like a super-efficient hotel manager for our Kubernetes worker nodes, always trying to arrange the “guests” (our applications) most cost-effectively. Sometimes, this means moving guests from one room to another to save on operating costs. In Kubernetes terminology, we call this “consolidation.”

The dancing pods challenge

Here’s the thing: We have this wonderful hotel manager (Karpenter) who’s doing a fantastic job, keeping costs down by constantly optimizing room assignments. But what about our guests (the applications)? They might get a bit dizzy with all this moving around, and sometimes, their important work gets disrupted.

So, the question is: How do we keep our applications running smoothly while still allowing Karpenter to do its magic? It’s like trying to keep a circus performance going while the stage crew rearranges the set in the middle of the act.

Understanding the moving parts

Before we explore the solutions, let’s take a peek behind the scenes and see what happens when Karpenter decides to relocate our applications. It’s quite a fascinating process:

First, Karpenter puts up a “Do Not Disturb” sign (technically called a taint) on the node it wants to clear. Then, it finds new accommodations for all the applications. Finally, it carefully moves each application to its new location.

Think of it as a well-choreographed dance where each step must be perfectly timed to avoid any missteps.

The art of high availability

Now, for the exciting part, we have some clever tricks up our sleeves to ensure our applications keep running smoothly:

  1. The buddy system: The first rule of high availability is simple: never go it alone! Instead of running a single instance of your application, run at least two. It’s like having a backup singer, if one voice falters, the show goes on. In Kubernetes, we do this by setting replicas: 2 in our deployment configuration.
  2. Strategic placement: Here’s a neat trick: we can tell Kubernetes to spread our application copies across different physical machines. It’s like not putting all your eggs in one basket. We use something called “Pod Topology Spread Constraints” for this. Here’s how it looks in practice:
topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: kubernetes.io/hostname
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: your-app
  1. Setting boundaries: Remember when your parents set rules about how many cookies you could eat? We do something similar in Kubernetes with PodDisruptionBudgets (PDB). We tell Kubernetes, “Hey, you must always keep at least 50% of my application instances running.” This prevents our hotel manager from getting too enthusiastic about rearranging things.
  2. The “Do Not Disturb” sign: For those special cases where we absolutely don’t want an application to be moved, we can put up a permanent “Do Not Disturb” sign using the karpenter.sh/do-not-disrupt: “true” annotation. It’s like having a VIP guest who gets to keep their room no matter what.

The complete picture

The beauty of this system lies in how all the pieces work together. Think of it as a safety net with multiple layers:

  • Multiple instances ensure basic redundancy.
  • Strategic placement keeps instances separated.
  • PodDisruptionBudgets prevent too many moves at once.
  • And when necessary, we can completely prevent disruption.

A real example

Let me paint you a picture. Imagine you’re running a critical web service. Here’s how you might set it up:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: critical-web-service
spec:
  replicas: 2
  template:
    metadata:
      annotations:
        karpenter.sh/do-not-disrupt: "false"  # We allow movement, but with controls
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: DoNotSchedule
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: critical-web-service-pdb
spec:
  minAvailable: 50%
  selector:
    matchLabels:
      app: critical-web-service

The result

With these patterns in place, our applications become incredibly resilient. They can handle node failures, scale smoothly, and even survive Karpenter’s optimization efforts without any downtime. It’s like having a self-healing system that keeps your services running no matter what happens behind the scenes.

High availability isn’t just about having multiple copies of our application, it’s about thoughtfully designing how those copies are managed and maintained. By understanding and implementing these patterns, we are not just running applications in Kubernetes; we are crafting reliable, resilient services that can weather any storm.

The next time you deploy an application to Kubernetes, think about these patterns. They might just save you from that dreaded 3 AM wake-up call about your service being down!

How to mount AWS EFS on EKS for scalable storage solutions

Suppose you need multiple applications to share files seamlessly, without worrying about running out of storage space or struggling with complex configurations. That’s where AWS Elastic File System (EFS) comes in. EFS is a fully managed, scalable file system that multiple AWS services or containers can access. In this guide, we’ll take a simple yet comprehensive journey through the process of mounting AWS EFS to an Amazon Elastic Kubernetes Service (EKS) cluster. I’ll make sure to keep it straightforward, so you can follow along regardless of your Kubernetes experience.

Why use EFS with EKS?

Before we go into the details, let’s consider why using EFS in a Kubernetes environment is beneficial. Imagine you have multiple applications (pods) that all need to access the same data—like a shared directory of documents. Instead of replicating data for each application, EFS provides a centralized storage solution that can be accessed by all pods, regardless of which node they’re running on.

Here’s what makes EFS a great choice for EKS:

  • Shared Storage: Multiple pods across different nodes can access the same files at the same time, making it perfect for workloads that require shared access.
  • Scalability: EFS automatically scales up or down as your data needs change, so you never have to worry about manually managing storage limits.
  • Durability and Availability: AWS ensures that your data is highly durable and accessible across multiple Availability Zones (AZs), which means your applications stay resilient even if there are hardware failures.

Typical use cases for using EFS with EKS include machine learning workloads, content management systems, or shared file storage for collaborative environments like JupyterHub.

Prerequisites

Before we start, make sure you have the following:

  1. EKS Cluster: You need a running EKS cluster, and kubectl should be configured to access it.
  2. EFS File System: An existing EFS file system in the same AWS region as your EKS cluster.
  3. IAM Roles: Correct IAM roles and policies for your EKS nodes to interact with EFS.
  4. Amazon EFS CSI Driver: This driver must be installed in your EKS cluster.

How to mount AWS EFS on EKS

Let’s take it step by step, so by the end, you’ll have a working setup where your Kubernetes pods can use EFS for shared, scalable storage.

Create an EFS file system

To begin, navigate to the EFS Management Console:

  1. Create a New File System: Select the appropriate VPC and subnets—they should be in the same region as your EKS cluster.
  2. File System ID: Note the File System ID; you’ll use it later.
  3. Networking: Ensure that your security group allows inbound traffic from the EKS worker nodes. Think of this as permitting EKS to access your storage safely.

Set up IAM role for the EFS CSI driver

The Amazon EFS CSI driver manages the integration between EFS and Kubernetes. For this driver to work, you need to create an IAM role. It’s a bit like giving the CSI driver its set of keys to interact with EFS securely.

To create the role:

  1. Log in to the AWS Management Console and navigate to IAM.
  2. Create a new role and set up a custom trust policy:
{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Principal": {
               "Federated": "arn:aws:iam::<account-id>:oidc-provider/oidc.eks.<region>.amazonaws.com/id/<oidc-provider-id>"
           },
           "Action": "sts:AssumeRoleWithWebIdentity",
           "Condition": {
               "StringLike": {
                   "oidc.eks.<region>.amazonaws.com/id/<oidc-provider-id>:sub": "system:serviceaccount:kube-system:efs-csi-*"
               }
           }
       }
   ]
}

Make sure to attach the AmazonEFSCSIDriverPolicy to this role. This step ensures that the CSI driver has the necessary permissions to manage EFS volumes.

Install the Amazon EFS CSI driver

You can install the EFS CSI driver using either the EKS Add-ons feature or via Helm charts. I recommend the EKS Add-on method because it’s easier to manage and stays updated automatically.

Attach the IAM role you created to the EFS CSI add-on in your cluster.

(Optional) Create an EFS access point

Access points provide a way to manage and segregate access within an EFS file system. It’s like having different doors to different parts of the same warehouse, each with its key and permissions.

  • Go to the EFS Console and select your file system.
  • Create a new Access Point and note its ID for use in upcoming steps.

Configure an IAM Policy for worker nodes

To make sure your EKS worker nodes can access EFS, attach an IAM policy to their role. Here’s an example policy:

{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Effect": "Allow",
           "Action": [
               "elasticfilesystem:DescribeAccessPoints",
               "elasticfilesystem:DescribeFileSystems",
               "elasticfilesystem:ClientMount",
               "elasticfilesystem:ClientWrite"
           ],
           "Resource": "*"
       }
   ]
}

This ensures your nodes can create and interact with the necessary resources.

Create a storage class for EFS

Next, create a Kubernetes StorageClass to provision Persistent Volumes (PVs) dynamically. Here’s an example YAML file:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com
parameters:
  fileSystemId: <file-system-id>
  directoryPerms: "700"
  basePath: "/dynamic_provisioning"
  ensureUniqueDirectory: "true"

Replace <file-system-id> with your EFS File System ID.

Apply the file:

kubectl apply -f efs-storage-class.yaml

Create a persistent volume claim (PVC)

Now, let’s request some storage by creating a PersistentVolumeClaim (PVC):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: efs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  storageClassName: efs-sc

Apply the PVC:

kubectl apply -f efs-pvc.yaml

Use the EFS PVC in a pod

With the PVC created, you can now mount the EFS storage into a pod. Here’s a sample pod configuration:

apiVersion: v1
kind: Pod
metadata:
  name: efs-app
spec:
  containers:
  - name: app
    image: nginx
    volumeMounts:
    - mountPath: "/data"
      name: efs-volume
  volumes:
  - name: efs-volume
    persistentVolumeClaim:
      claimName: efs-pvc

Apply the configuration:

kubectl apply -f efs-pod.yaml

You can verify the setup by checking if the pod can access the mounted storage:

kubectl exec -it efs-app -- ls /data

A note on direct EFS mounting

You can mount EFS directly into pods without using a Persistent Volume (PV) or Persistent Volume Claim (PVC) by referencing the EFS file system directly in the pod’s configuration. This approach simplifies the setup but offers less flexibility compared to using dynamic provisioning with a StorageClass. Here’s how you can do it:

apiVersion: v1
kind: Pod
metadata:
  name: efs-mounted-app
  labels:
    app: efs-example
spec:
  containers:
  - name: nginx-container
    image: nginx:latest
    volumeMounts:
    - name: efs-storage
      mountPath: "/shared-data"
  volumes:
  - name: efs-storage
    csi:
      driver: efs.csi.aws.com
      volumeHandle: <file-system-id>
      readOnly: false

Replace <file-system-id> with your EFS File System ID. This method works well for simpler scenarios where direct access is all you need.

Final remarks

Mounting EFS to an EKS cluster gives you a powerful, shared storage solution for Kubernetes workloads. By following these steps, you can ensure that your applications have access to scalable, durable, and highly available storage without needing to worry about complex management or capacity issues.

As you can see, EFS acts like a giant, shared repository that all your applications can tap into. Whether you’re working on machine learning projects, collaborative tools, or any workload needing shared data, EFS and EKS together simplify the whole process.

Now that you’ve walked through mounting EFS on EKS, think about what other applications could benefit from this setup. It’s always fascinating to see how managed services can help reduce the time you spend on the nitty-gritty details, letting you focus on building great solutions.

How many pods fit on an AWS EKS node?

Managing Kubernetes workloads on AWS EKS (Elastic Kubernetes Service) is much like managing a city, you need to know how many “tenants” (Pods) you can fit into your “buildings” (EC2 instances). This might sound straightforward, but a bit more is happening behind the scenes. Each type of instance has its characteristics, and understanding the limits is key to optimizing your deployments and avoiding resource headaches.

Why Is there a pod limit per node in AWS EKS?

Imagine you want to deploy several applications as Pods across several instances in AWS EKS. You might think, “Why not cram as many as possible onto each node?” Well, there’s a catch. Every EC2 instance in AWS has a limit on networking resources, which ultimately determines how many Pods it can support.

Each EC2 instance has a certain number of Elastic Network Interfaces (ENIs), and each ENI can hold a certain number of IPv4 addresses. But not all these IP addresses are available for Pods, AWS reserves some for essential services like the AWS CNI (Container Network Interface) and kube-proxy, which helps maintain connectivity and communication across your cluster.

Think of each ENI like an apartment building, and the IPv4 addresses as individual apartments. Not every apartment is available to your “tenants” (Pods), because AWS keeps some for maintenance. So, when calculating the maximum number of Pods for a specific instance type, you need to take this into account.

For example, a t3.medium instance has a maximum capacity of 17 Pods. A slightly bigger t3.large can handle up to 35 Pods. The difference depends on the number of ENIs and how many apartments (IPv4 addresses) each ENI can hold.

Formula to calculate Max pods per EC2 instance

To determine the maximum number of Pods that an instance type can support, you can use the following formula:

Max Pods = (Number of ENIs × IPv4 addresses per ENI) – Reserved IPs

Let’s apply this to a t2.medium instance:

  • Number of ENIs: 3
  • IPv4 addresses per ENI: 6

Using these values, we get:

Max Pods = (3 × 6) – 1

Max Pods = 18 – 1

Max Pods = 17

So, a t2.medium instance in EKS can support up to 17 Pods. It’s important to understand that this number isn’t arbitrary, it reflects the way AWS manages networking to keep your cluster running smoothly.

Why does this matter?

Knowing the limits of your EC2 instances can be crucial when planning your Kubernetes workloads. If you exceed the maximum number of Pods, some of your applications might fail to deploy, leading to errors and downtime. On the other hand, choosing an instance that’s too large might waste resources, costing you more than necessary.

Suppose you’re running a city, and you need to decide how many tenants each building can support comfortably. You don’t want buildings overcrowded with tenants, nor do you want them half-empty. Similarly, you need to find the sweet spot in AWS EKS, enough Pods to maximize efficiency, but not so many that your node runs out of resources.

The apartment analogy

Consider an m5.large instance. Let’s say it has 4 ENIs, and each ENI can support 10 IP addresses. But, AWS reserves a few apartments (IPv4 addresses) in each building (ENI) for maintenance staff (essential services). Using our formula, we can estimate how many Pods (tenants) we can fit.

  • Number of ENIs: 4
  • IPv4 addresses per ENI: 10

Max Pods = (4 × 10) – 1

Max Pods = 40 – 1

Max Pods = 39

So, an m5.large can support 39 Pods. This limit helps ensure that the building (instance) doesn’t get overwhelmed and that the essential services can function without issues.

Automating the Calculation

Manually calculating these limits can be tedious, especially if you’re managing multiple instance types or scaling dynamically. Thankfully, AWS provides tools and scripts to help automate these calculations. You can use the kubectl describe node command to get insights into your node’s capacity or refer to AWS documentation for Pod limits by instance type. Automating this step saves time and helps you avoid deployment issues.

Best practices for scaling

When planning the architecture of your EKS cluster, consider these best practices:

  • Match instance type to workload needs: If your application requires many Pods, opt for an instance type with more ENIs and IPv4 capacity.
  • Consider cost efficiency: Sometimes, using fewer large instances can be more cost-effective than using many smaller ones, depending on your workload.
  • Leverage autoscaling: AWS allows you to set up autoscaling for both your Pods and your nodes. This can help ensure that you have the right amount of capacity during peak and off-peak times without manual intervention.

Key takeaways

Understanding the Pod limits per EC2 instance in AWS EKS is more than just a calculation, it’s about ensuring your Kubernetes workloads run smoothly and efficiently. By thinking of ENIs as buildings and IP addresses as apartments, you can simplify the complexity of AWS networking and better plan your deployments.

Like any good city planner, you want to make sure there’s enough room for everyone, but not so much that you’re wasting space. AWS gives you the tools, you just need to know how to use them.

Container deployment in AWS with ECS, EKS, and Fargate

How do the apps you use daily get built, shipped, and scaled so smoothly? A lot of it has to do with the magic of containers. Think of containers like neat little LEGO blocks, self-contained, portable, and ready to snap together to build something awesome. In the tech world, these blocks hold all the essential bits and pieces of an application, making it super easy to move them around and run them anywhere.

Imagine you’ve got a bunch of these LEGO blocks, each representing a different part of your app. You’ll need a good way to organize them, right? That’s where container orchestration comes in. It’s like having a master builder who knows how to put those blocks together, make sure they’re all playing nicely, and even create more blocks when things get busy.

And guess what? AWS, the cloud superhero, has a whole toolkit to help you with this container adventure. 

AWS container services toolkit

AWS offers a variety of services that work together like a well-oiled machine to help you build, deploy, and manage your containerized applications.

Amazon Elastic Container Registry (ECR) – Your container garage

Think of ECR as your very own garage for storing container images. It’s a fully managed service that allows you to store, share, and deploy your container images securely. ECR is like a safe and organized space where you keep all your valuable LEGO creations. You can easily control who has access to your images, making sure only the right people can use them. Plus, it integrates seamlessly with other AWS services, making it a breeze to include in your workflows.

Amazon Elastic Container Service (ECS) – Your container playground

Once you’ve got your container images stored safely in ECR, what’s next? Meet ECS, your container playground! ECS is a highly scalable and high-performance container orchestration service that allows you to run and manage your containers on a cluster of Amazon EC2 instances. It’s like having a dedicated play area where you can arrange your LEGO blocks, build amazing structures, and even add or remove blocks as needed. ECS takes care of all the heavy lifting, so you can focus on what matters most, building awesome applications.

Amazon Elastic Kubernetes Service (EKS) – Your Kubernetes command center

For those of you who prefer the Kubernetes way of doing things, AWS has you covered with EKS. It’s a managed Kubernetes service that makes it easy to run Kubernetes on AWS without having to worry about managing the underlying infrastructure. Kubernetes is like a super-sophisticated set of instructions for building complex LEGO structures. EKS takes care of all the complexities of managing Kubernetes so that you can focus on building and deploying your applications.

EC2 vs. Fargate – Choosing your foundation

Now, let’s talk about the foundation of your container playground. You have two main options: EC2 and Fargate.

EC2-based container deployment – The DIY approach

With EC2, you get full control over the underlying infrastructure. It’s like building your own LEGO table from scratch. You choose the size, shape, and color of the table, and you’re responsible for keeping it clean and tidy. This gives you a lot of flexibility, but it also means you have more responsibilities.

AWS Fargate – The hassle-free option

Fargate, on the other hand, is like having a magical LEGO table that appears whenever you need it. You don’t have to worry about building or maintaining the table; you just focus on playing with your LEGOs. Fargate is a serverless compute engine for containers, meaning you don’t have to manage any servers. It’s a great option if you want to simplify your operations and reduce your overhead.

Making the right choice

So, which option is right for you? Well, it depends on your specific needs and preferences. If you need full control over your infrastructure and want to optimize costs by managing your own servers, EC2 might be a good choice. But if you prefer a serverless approach and want to avoid the hassle of managing servers, Fargate is the way to go.

AWS Container Services Compared

To make things easier, here’s a quick comparison of ECS, EKS, and Fargate:

ServiceDescriptionUse Case
ECSManaged container orchestration for EC2 instancesGreat for full control over infrastructure
EKSManaged Kubernetes serviceIdeal for teams with Kubernetes expertise
FargateServerless compute engine for ECS or EKSSimplifies operations, no infrastructure management

Best practices and security for building a secure and reliable playground

Just like any playground, your container environment needs to be safe and secure. AWS provides a range of tools and best practices to help you build a reliable and secure container playground.

Security best practices for keeping your LEGOs safe

AWS offers a variety of security features to help you protect your container environment. You can use IAM to control access to your resources, implement network security measures (like Security Groups and NACLs) to protect your containers from unauthorized access, and scan your container images for vulnerabilities with tools like Amazon Inspector.

High availability for ensuring your playground is always open

To ensure your applications are always available, you can use AWS’s high-availability features. This includes deploying your containers across multiple availability zones, configuring load balancing to distribute traffic across your containers, and implementing disaster recovery measures to protect your applications from unexpected events.

Monitoring and troubleshooting for keeping an eye on your playground

AWS provides comprehensive monitoring and troubleshooting tools to help you keep your container environment running smoothly. You can use CloudWatch to monitor your containers’ performance, set up detailed alarms to catch issues before they escalate, and use CloudWatch Logs to dive deep into the activity of your applications. Additionally, AWS X-Ray helps you trace requests as they travel through your application, giving you a granular view of where bottlenecks or failures may occur. These tools together allow for proactive monitoring, quick detection of anomalies, and effective root-cause analysis, ensuring that your container environment is always optimized and functioning properly.

DevOps integration for automating your LEGO creations

AWS container services integrate seamlessly with your DevOps workflows, allowing you to automate deployments, ensure consistent environments, and streamline the entire development lifecycle. By integrating services like CodeBuild, CodeDeploy, and CodePipeline, AWS enables you to create end-to-end CI/CD pipelines that automate testing, building, and releasing your containerized applications. This integration helps teams release features faster, reduce errors due to manual processes, and maintain a high level of consistency across different environments.

CI/CD pipeline integration for building and deploying automatically

You can use AWS CodePipeline to create a continuous integration and continuous delivery (CI/CD) pipeline that automatically builds, tests, and deploys your containerized applications. This allows you to release new features and updates quickly and efficiently. Imagine using CodePipeline as an automated assembly line for your LEGO creations.

Cost optimization for saving money on your LEGOs

AWS offers a variety of cost optimization tools to help you save money on your container deployments. You can use ECR lifecycle policies to manage your container images efficiently, choose the right instance types for your workloads, and leverage AWS’s pricing models to optimize your costs. Additionally, AWS provides Savings Plans and Spot Instances, which allow you to significantly reduce costs when running containerized workloads with flexible scheduling. Utilizing the AWS Compute Optimizer can also help identify opportunities to downsize or modify your infrastructure to be more cost-effective, ensuring you’re always operating in a lean and optimized manner.

Real-world implementation for bringing your LEGO creations to life

Deploying containerized applications in a production environment requires careful planning and execution. This involves assessing your infrastructure, understanding resource requirements, and preparing for potential scaling needs. AWS provides a range of tools and best practices, such as infrastructure templates, automated deployment scripts, and monitoring solutions, to help ensure that your applications are deployed successfully. Additionally, AWS recommends using blue-green deployments to minimize downtime and risk, as well as leveraging autoscaling to maintain performance under varying loads.

Production deployment checklist for your Pre-flight check

Before deploying your applications, it’s important to consider a few key factors, such as your application’s requirements, your infrastructure needs, and your security and compliance requirements. AWS provides a comprehensive checklist to help you ensure your applications are ready for production.

Common challenges and solutions for troubleshooting your LEGO creations

Deploying and managing containerized applications can present some challenges, such as dealing with scaling complexities, managing network configurations, or troubleshooting performance bottlenecks. However, AWS provides a wealth of resources and support to help you overcome these challenges. You can find solutions to common problems, troubleshooting tips, and best practices in the AWS documentation, community forums, and even through AWS Support Plans, which offer access to technical experts. Additionally, tools like AWS Trusted Advisor can help identify potential issues before they impact your applications, while AWS Well-Architected Framework guides optimizing your container deployments for reliability, performance, and cost-efficiency.

Choosing the right tools for the job

AWS offers a comprehensive suite of container services to help you build, deploy, and manage your applications. By understanding the different services and their capabilities, you can choose the right tools for your specific needs and build a secure, reliable, and cost-effective container environment.

The key is to choose the right tools for the job and follow best practices to ensure your applications are secure, reliable, and scalable.