ecs to eks

From ECS to EKS: A Complete Migration Guide

Amazon ECS (Elastic Container Service) and EKS (Elastic Kubernetes Service) are two powerful container orchestration solutions provided by AWS. While ECS simplifies container management with tight AWS integration, EKS leverages Kubernetes, an industry-standard open-source orchestration tool.

Why Consider Migrating from ECS to EKS?
Many organizations choose EKS to harness Kubernetes’ advanced features like multi-cluster management, flexibility in choosing tools, and a robust open-source ecosystem. Migrating to EKS provides better scalability, portability, and compatibility with multi-cloud and hybrid environments.


Preparing for the Migration

Assessing Your ECS Workloads
Before starting, evaluate your ECS tasks. Document task definitions, resource requirements, environment variables, secrets, and network configurations. Identify which workloads are suited for Kubernetes and any potential challenges in migrating them.

Tools and Prerequisites for Migration
Ensure the following prerequisites are in place:

  • Terraform for infrastructure as code.
  • AWS CLI configured with appropriate permissions.
  • kubectl installed and configured for Kubernetes.
  • Helm, a Kubernetes package manager.
  • Argo CD for CI/CD automation.

Setting Up Your EKS Cluster with Terraform

To set up an EKS cluster, we will use Terraform to create the infrastructure required, including VPC, subnets, IAM roles, and other essential components.

Terraform Code for EKS Setup

Below is a comprehensive Terraform configuration to create an EKS cluster:

# Provider
provider "aws" {
  region = "us-west-2"  # Replace with your desired AWS region
}

# VPC
resource "aws_vpc" "eks_vpc" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = {
    Name = "eks-vpc"
  }
}

# Subnets
resource "aws_subnet" "eks_subnet" {
  count                   = 2  # Two subnets for HA
  vpc_id                  = aws_vpc.eks_vpc.id
  cidr_block              = cidrsubnet(aws_vpc.eks_vpc.cidr_block, 8, count.index)
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true

  tags = {
    Name = "eks-subnet-${count.index}"
  }
}

# Internet Gateway
resource "aws_internet_gateway" "eks_igw" {
  vpc_id = aws_vpc.eks_vpc.id

  tags = {
    Name = "eks-igw"
  }
}

# Route Table
resource "aws_route_table" "eks_rt" {
  vpc_id = aws_vpc.eks_vpc.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.eks_igw.id
  }

  tags = {
    Name = "eks-rt"
  }
}

# Route Table Association
resource "aws_route_table_association" "eks_rta" {
  count          = 2
  subnet_id      = aws_subnet.eks_subnet[count.index].id
  route_table_id = aws_route_table.eks_rt.id
}

# Security Group
resource "aws_security_group" "eks_sg" {
  name_prefix = "eks-sg"
  vpc_id      = aws_vpc.eks_vpc.id

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "eks-sg"
  }
}

# IAM Role for EKS
resource "aws_iam_role" "eks_role" {
  name = "eks-cluster-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Service = "eks.amazonaws.com"
        },
        Action = "sts:AssumeRole"
      }
    ]
  })

  tags = {
    Name = "eks-role"
  }
}

# IAM Policy Attachment
resource "aws_iam_role_policy_attachment" "eks_policy" {
  role       = aws_iam_role.eks_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
}

# EKS Cluster
resource "aws_eks_cluster" "eks_cluster" {
  name     = "eks-cluster"
  role_arn = aws_iam_role.eks_role.arn

  vpc_config {
    subnet_ids         = aws_subnet.eks_subnet[*].id
    security_group_ids = [aws_security_group.eks_sg.id]
  }

  tags = {
    Name = "eks-cluster"
  }
}

# Output
output "cluster_endpoint" {
  value = aws_eks_cluster.eks_cluster.endpoint
}

output "cluster_arn" {
  value = aws_eks_cluster.eks_cluster.arn
}

Applying the Terraform Configuration

Initialize Terraform:

      terraform init

Validate and apply the configuration:

terraform apply

Retrieve the EKS cluster endpoint and ARN from the outputs.

    See also  What is Grafana and How It Turns Data into Art?

    Converting ECS Task Definitions to Helm Charts

    Breaking Down ECS Task Definitions\
    ECS task definitions encapsulate container configurations, including:

    • Container image and version.
    • CPU and memory allocation.
    • Networking and port mappings.
    • Environment variables and secrets.

    Writing Your First Helm Chart

    1. Create a new Helm chart:
       helm create my-application
    1. Map ECS configurations to Kubernetes resources in the Helm chart files. For example:
    • Define a Deployment for the container image.
    • Use ConfigMap and Secret for environment variables and secrets.
    • Set Service definitions for network configurations.

    Automating the Conversion Process\
    To streamline migration, consider writing a script to translate ECS task definitions to Helm templates. Tools like eksctl and kube2iam can help with IAM role mappings.


    Implementing CI/CD with Argo CD

    Introduction to Argo CD and ApplicationSets\
    Argo CD is a declarative GitOps tool for Kubernetes. ApplicationSets allow dynamic application deployments based on Helm charts or other templates, making it ideal for managing EKS workloads.

    Setting Up Argo CD for Your EKS Environment

    1. Install Argo CD in the EKS cluster:
       kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
    1. Access the Argo CD UI and connect it to your Git repository.

    Automating Helm Chart Deployments with ApplicationSets

    1. Define an ApplicationSet template for your Helm chart:
       apiVersion: argoproj.io/v1alpha1
       kind: ApplicationSet
       metadata:
         name: my-application-set
       spec:
         generators:
           - git:
               repoURL: https://github.com/your-repo.git
               revision: main
               directories:
                 - path: helm/my-application
         template:
           metadata:
             name: '{{appName}}'
           spec:
             project: default
             source:
               repoURL: https://github.com/your-repo.git
               targetRevision: main
               path: helm/my-application
             destination:
               server: https://kubernetes.default.svc
               namespace: my-namespace
    1. Apply the ApplicationSet YAML:
       kubectl apply -f applicationset.yaml

    Also read about Probes for Implementing Robust Health Checks in Kubernetes Here

    See also  Why Companies Are Quitting Kubernetes

    Deploying and Testing Applications on EKS

    Deploying Your Converted ECS Workloads to EKS\
    Deploy the Helm chart using Argo CD. Once synced, the workload will run in the EKS cluster. Verify the deployment:

    kubectl get pods -n my-namespace

    Validating the Migration\
    Ensure the application behaves as expected by:

    • Testing API endpoints.
    • Monitoring logs with kubectl logs.
    • Verifying external access using Kubernetes Ingress or LoadBalancer services.

    Example Application Migration: Nginx Web Server

    Step 1: ECS Setup

    1. Create an ECS task definition for Nginx:
       {
         "family": "nginx-task",
         "containerDefinitions": [
           {
             "name": "nginx",
             "image": "nginx:latest",
             "memory": 512,
             "cpu": 256,
             "portMappings": [
               {
                 "containerPort": 80,
                 "hostPort": 80
               }
             ]
           }
         ]
       }
    1. Deploy the task to ECS and verify its functionality.

    Step 2: Convert ECS Task Definition to Helm Chart

    1. Translate the ECS configurations to a Helm template:
    • Define a Deployment in templates/deployment.yaml:
      yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: – name: nginx image: nginx:latest ports: – containerPort: 80
    • Define a Service in templates/service.yaml: “`yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx ports:
      • protocol: TCP
        port: 80
        targetPort: 80
        type: LoadBalancer
        “`
    1. Package the Helm chart:
       helm package .

    Step 3: Deploy Using AWS Console and CLI

    1. AWS Console:
    • Upload and deploy the Helm chart via Argo CD’s UI.
    1. AWS CLI:
      Deploy the Helm chart manually:
       helm install nginx ./nginx-chart
    1. Verify the deployment:
       kubectl get svc

    Note the external IP of the LoadBalancer and access it in your browser.


    Post-Migration Best Practices

    Monitoring and Scaling Applications on EKS\
    Leverage Kubernetes-native tools like:

    • Kubernetes Metrics Server for resource monitoring.
    • Horizontal Pod Autoscaler (HPA) for scaling based on resource usage.
    • AWS CloudWatch and Prometheus for in-depth insights.
    See also  5 Common AWS VPC Peering Mistakes and How to Avoid Them

    Securing Your EKS Cluster

    • Use Network Policies to restrict pod communication.
    • Enable RBAC for access control.
    • Regularly patch and update Kubernetes and associated tools.

    Challenges and Lessons Learned

    Common Issues During Migration

    • Misconfigurations in Helm charts.
    • Network discrepancies between ECS and Kubernetes.
    • Differences in IAM role handling.

    Tips to Ensure a Smooth Transition

    • Start with non-critical workloads.
    • Automate testing to catch issues early.
    • Document every step to streamline future migrations.

    Conclusion

    Migrating from ECS to EKS unlocks the full potential of Kubernetes, allowing for better scalability, flexibility, and access to a vast ecosystem of tools. By following this guide, you can transition smoothly and start leveraging Kubernetes for your workloads. As you embrace this change, remember to continuously optimize and adapt your infrastructure to maximize the benefits of EKS.

    References

    1. AWS EKS Documentation
    2. Terraform AWS Provider
    3. Helm Documentation
    ayush.mandal11@gmail.com
    ayush.mandal11@gmail.com
    Articles: 26

    Leave a Reply

    Your email address will not be published. Required fields are marked *