Ramesh Indrajith's Blog: Cloud Infrastructure and DevOps

website·Indexed 30 days ago

https://blog.rameshindrajith.com/

A resource for cloud infrastructure and DevOps practices, featuring guides on installing and configuring Karpenter on Amazon EKS, and building Model Context Protocol (MCP) servers for AI assistants like Amazon Q.

Tokens
5.6K
Snippets
18
Records
23
Agent score
50%

What's inside Ramesh Indrajith's Blog

  1. Overview of Model Context Protocol (MCP)

    Model Context Protocol (MCP) is an open standard that enables AI assistants to securely connect to data sources and tools. It acts as a universal connector, allowing AI models to interact with external systems (databases, APIs, file systems, or custom logic) to fetch live data and perform actions beyond their static training knowledge.
  2. Install Karpenter using Helm

    To install Karpenter, first update the Helm dependencies for the chart directory, then install the chart into the designated Karpenter namespace using the configured values.yaml file.
    helm dependency update <chart-path>
    helm install karpenter <chart-path> -n "${KARPENTER_NAMESPACE}" -f <chart-path>/values.yaml
  3. Create an OIDC Provider for IRSA

    Karpenter requires an OIDC provider registered in IAM to use IAM Roles for Service Accounts (IRSA) to assume the controller role. This can be achieved using the AWS CLI or eksctl.
    # Option 1: Using AWS CLI
    aws iam create-open-id-connect-provider \
        --url "${OIDC_ENDPOINT}" \
        --client-id-list sts.amazonaws.com \
        --thumbprint-list $(echo | openssl s_client -servername oidc.eks.${AWS_REGION}.amazonaws.com -connect oidc.eks.${AWS_REGION}.amazonaws.com:443 2>/dev/null | openssl x509 -fingerprint -noout | cut -d= -f2 | tr -d :)
    
    # Option 2: Using eksctl
    eksctl utils associate-iam-oidc-provider --cluster "${CLUSTER_NAME}" --region "${AWS_REGION}" --approve
    
    # Verify creation
    aws iam list-open-id-connect-providers
  4. Tag Subnets and Security Groups for Karpenter Discovery

    Karpenter discovers subnets and security groups at runtime using the karpenter.sh/discovery tag. You must tag the subnets and security groups used by your existing node groups so Karpenter can launch new nodes into the same network environment.
    # Tag subnets used by existing node groups
    for NODEGROUP in $(aws eks list-nodegroups --cluster-name "${CLUSTER_NAME}" --query 'nodegroups' --output text); do
        aws ec2 create-tags \
            --tags "Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}" \
            --resources $(aws eks describe-nodegroup --cluster-name "${CLUSTER_NAME}" \
            --nodegroup-name "${NODEGROUP}" --query 'nodegroup.subnets' --output text )
    done
    
    # Tag the cluster security group
    # First, get the security group ID
    SECURITY_GROUPS=$(aws eks describe-cluster --name "${CLUSTER_NAME}" --query "cluster.resourcesVpcConfig.clusterSecurityGroupId" --output text)
    
    # Apply the discovery tag
    aws ec2 create-tags \
        --tags "Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}" \
        --resources "${SECURITY_GROUPS}"
  5. Authorize Karpenter Node Role in aws-auth ConfigMap

    To allow nodes launched by Karpenter to join the cluster, the Karpenter Node Role must be added to the aws-auth ConfigMap in the kube-system namespace.
    # Edit the configmap
    kubectl edit configmap aws-auth -n kube-system

    Add the following block under mapRoles:

    • groups:
      • system:bootstrappers
      • system:nodes rolearn: arn:${AWS_PARTITION}:iam::${AWS_ACCOUNT_ID}:role/KarpenterNodeRole-${CLUSTER_NAME} username: system:node:{{EC2PrivateDNSName}}
  6. Implement MCP Tools using FastMCP @tool decorator

    MCP tools are Python functions exposed to AI models. When an AI identifies a need for external functionality, it calls the tool with specific parameters, the Python function processes the request, and the result is returned to the AI. Use the @mcp.tool() decorator to define these functions, providing a name and description to help the AI discover and execute the tool.
    import docker
    from mcp.server.fastmcp import FastMCP
    
    client = docker.from_env()
    mcp = FastMCP("docker-server")
    
    @mcp.tool(
        name="start_container",
        description="Start a stopped container"
    )
    def start_container(container_id: str) -> str:
        try:
            container = client.containers.get(container_id)
            container.start()
            return f"Container {container.name} started"
        except Exception as e:
            return f"Error: {str(e)}"
    
    if __name__ == "__main__":
        mcp.run()
  7. Create the Karpenter Node IAM Role

    Karpenter-provisioned nodes require a specific IAM role to join the cluster and pull container images. This involves creating a trust policy for EC2 and attaching standard EKS worker node policies.
    # 1. Create trust policy
    echo '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Service": "ec2.amazonaws.com"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }' > node-trust-policy.json
    
    # 2. Create the role
    aws iam create-role --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \
        --assume-role-policy-document file://node-trust-policy.json
    
    # 3. Attach required policies
    aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \
        --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonEKSWorkerNodePolicy"
    
    aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \
        --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonEKS_CNI_Policy"
    
    aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \
        --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonEC2ContainerRegistryPullOnly"
    
    aws iam attach-role-policy --role-name "KarpenterNodeRole-${CLUSTER_NAME}" \
        --policy-arn "arn:${AWS_PARTITION}:iam::aws:policy/AmazonSSMManagedInstanceCore"
  8. Set up environment variables for Karpenter Node Pool configuration

    Before creating Karpenter resources, set the following environment variables. The ALIAS_VERSION is used to pin the AMI to a specific release for consistency across nodes.
    # Set your specific cluster name and region
    export CLUSTER_NAME=<your cluster name>
    export AWS_REGION=<your aws region>
    
    # If using named profiles in ~/.aws/credentials
    export AWS_PROFILE=<your AWS profile>
    
    # Dynamically fetch K8s version and the corresponding AL2023 AMI alias version
    K8S_VERSION=$(aws eks describe-cluster --name "${CLUSTER_NAME}" --query "cluster.version" --output text)
    ALIAS_VERSION="$(aws ssm get-parameter --name "/aws/service/eks/optimized-ami/${K8S_VERSION}/amazon-linux-2023/x86_64/standard/recommended/image_id" --query Parameter.Value --output text | xargs aws ec2 describe-images --query 'Images[0].Name' --output text --image-ids | sed -r 's/^.*(v[[:digit:]]+).*$/\1/')"
    
    # Verify values
    echo "K8S_VERSION: $K8S_VERSION"
    echo "ALIAS_VERSION: $ALIAS_VERSION"
  9. Create the Karpenter Controller IAM Role

    The Karpenter controller uses an IAM role via IRSA (IAM Roles for Service Accounts) to manage EC2 instances. The trust policy restricts access specifically to the karpenter service account within the designated namespace.
    # 1. Create the trust policy for IRSA
    cat << EOF > controller-trust-policy.json
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "Federated": "arn:${AWS_PARTITION}:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_ENDPOINT#*//}"
                },
                "Action": "sts:AssumeRoleWithWebIdentity",
                "Condition": {
                    "StringEquals": {
                        "${OIDC_ENDPOINT#*//}:aud": "sts.amazonaws.com",
                        "${OIDC_ENDPOINT#*//}:sub": "system:serviceaccount:${KARPENTER_NAMESPACE}:karpenter"
                    }
                }
            }
        ]
    }
    EOF
    
    # 2. Create the controller role
    aws iam create-role --role-name "KarpenterControllerRole-${CLUSTER_NAME}" \
        --assume-role-policy-document file://controller-trust-policy.json
  10. Prerequisites for installing Karpenter on EKS

    Before installing Karpenter on an existing EKS cluster with managed node groups, ensure the following are available:

    • An existing EKS cluster with at least one managed node group
    • kubectl configured for cluster access
    • AWS CLI v2 installed and configured
    • helm v3 installed
    • IAM permissions to create roles and policies
  11. Implement MCP Resources and Prompts using FastMCP

    FastMCP provides decorators for data exposure and instruction standardization:

    • Resources (@resource): Act as data providers (endpoints) that expose application data like config files or database records. Resource templates allow dynamic content generation by accepting parameters via the URI.
    • Prompts (@prompt): Reusable, parameterized message templates that standardize how AI models receive instructions, ensuring consistent behavior across different scenarios.