amazon-eks-ami

repository·main·Indexed 25 days ago

https://github.com/awslabs/amazon-eks-ami

Resources and configuration scripts for building custom Amazon EKS-optimized AMIs using HashiCorp Packer. Includes nodeadm for node initialization and configuration via NodeConfig, as well as tools for collecting EKS logs on Linux and Windows nodes using manual scripts or AWS Systems Manager (SSM).

Tokens
15.4K
Snippets
36
Records
87
Agent score
83%

What's inside amazon-eks-ami

  1. Understand nodeadm API versioning

    main

    The nodeadm API types (under the node.eks.aws API group) follow Kubernetes-style versioning with three stability levels:

    • Alpha (e.g., v1alpha2): Support may be removed at any time. Incompatible changes may occur without migration instructions.
    • Beta (e.g., v3beta4): Support remains for at least one release following deprecation. Incompatible changes in subsequent beta or stable versions will include migration instructions.
    • Stable (e.g., v5): Support aligns with the support lifecycle of the major Amazon Linux version used.
  2. Override configuration with drop-in files

    main

    On EKS AMIs, you can override settings provided in EC2 user data by placing NodeConfig objects (as .yaml, .yml, or .json files) into /etc/eks/nodeadm.d/.

    Drop-in files are evaluated after user data, so they take precedence. A drop-in file only needs to contain the specific fields you wish to override. Note that at least one source (typically user data) must still provide the required cluster fields.

    ### Example drop-in file at `/etc/eks/nodeadm.d/10-rlimits.yaml`
    ```yaml
    ---
    apiVersion: node.eks.aws/v1alpha1
    kind: NodeConfig
    spec:
      containerd:
        baseRuntimeSpec:
          process:
            rlimits:
              - type: RLIMIT_NOFILE
                soft: 65536
                hard: 65536
  3. Merge multiple configuration objects in nodeadm

    main

    When using the IMDS configuration source (--config-source=imds://user-data), nodeadm merges all configuration objects found in a MIME multi-part document. Objects are merged in the order they appear; values in later objects take precedence over earlier ones.

    MIME-Version: 1.0
    Content-Type: multipart/mixed; boundary="BOUNDARY"
    
    --BOUNDARY
    Content-Type: application/node.eks.aws
    
    ---
    apiVersion: node.eks.aws/v1alpha1
    kind: NodeConfig
    spec:
      cluster:
        name: my-cluster
        ...
    
    --BOUNDARY
    Content-Type: application/node.eks.aws
    
    ---
    apiVersion: node.eks.aws/v1alpha1
    kind: NodeConfig
    spec:
      kubelet:
        config:
          shutdownGracePeriod: 30s
    
    --BOUNDARY--
  4. Generate max pod values resource file

    main

    The maximum number of pods schedulable on a node is determined by the number of ENIs available for an instance type. To optimize performance, default values for known instance types are cached in a resource file. If an instance type is missing from this cache, the system falls back to calling the ec2:DescribeInstanceTypes API at runtime.

    You can regenerate this resource file by running the generate-instance-info target within the nodeadm directory.

    cd nodeadm
    make generate-instance-info
  5. Build an AMI with a specific Kubernetes version

    main

    To build an AMI using specific Kubernetes versions and build dates, you must first locate the correct paths in the amazon-eks S3 bucket. You can use the AWS CLI to list versions, build dates, platforms, architectures, and binaries.

    Once you have identified the values, pass them to the make k8s command.

    # Example build command
    make k8s \
      kubernetes_version=1.23.9 \
      kubernetes_build_date=2022-07-27 \
      arch=x86_64
  6. Build a custom EKS-optimized AMI for G7 instances

    main

    G7 instances require NVIDIA driver version 595 or later. Because the default EKS-optimized accelerated AMI ships with driver version 580, you must build a custom AMI to support G7 instances.

    Warning: Driver version 595 is not compatible with P3, P3dn, and G6f instance types. Do not use this AMI for those instances.

    Prerequisites

    • Packer installed
    • AWS credentials configured with permissions to create AMIs (EC2, S3 read access)
    • Clone the repository:
    git clone https://github.com/awslabs/amazon-eks-ami.git
    cd amazon-eks-ami
  7. Collect EKS logs using AWS SSM Agent

    main

    You can automate log collection across multiple Worker Nodes and upload the resulting bundle to an S3 bucket using AWS Systems Manager (SSM).

    Prerequisites

    1. IAM Permissions: The IAM entity running the commands must have:
      • ssm:CreateDocument
      • ssm:GetCommandInvocation
      • ssm:SendCommand
    2. Worker Node Permissions: The EC2 instances must have the AmazonSSMManagedInstanceCore managed policy and S3:PutObject permission for the target bucket.
    3. SSM Agent: Must be installed and running on the target Worker Nodes.
    4. S3 Bucket: A destination bucket must be available to receive the logs.

    Execution Steps

    1. Create the SSM Document: Register the EKSLogCollectorWindows document.
    2. Send the Command: Execute the document on specific instance IDs, providing the target S3 bucket name as a parameter.
    3. Monitor Status: Check the invocation status using the Command ID.
    # 1. Create the SSM document
    aws ssm create-document \
      --name "EKSLogCollectorWindows" \
      --document-type "Command" \
      --content https://raw.githubusercontent.com/awslabs/amazon-eks-ami/main/log-collector-script/windows/eks-ssm-content.json
    
    # 2. Execute the command on an instance
    aws ssm send-command \
      --instance-ids <EC2 Instance ID> \
      --document-name "EKSLogCollectorWindows" \
      --parameters "bucketName=<S3 bucket name to push the logs>" \
      --output json
    
    # 3. Check command status
    aws ssm get-command-invocation \
      --command-id "<SSM command ID>" \
      --instance-id "<EC2 Instance ID>" \
      --output text
  8. Pre-requisites for building Amazon EKS AMIs

    main

    Before building an AMI, ensure you have the following requirements met:

    1. Packer: Version 1.8.0 or later must be installed on your local system.
    2. AWS Credentials: You must have AWS account credentials configured so that Packer can perform AWS API operations on your behalf.
  9. Modify container RLIMITs

    main

    To override default container RLIMITs, use the containerd.baseRuntimeSpec.process.rlimits path in your NodeConfig. This can be applied via user data or a drop-in file in /etc/eks/nodeadm.d/.

    ---
    apiVersion: node.eks.aws/v1alpha1
    kind: NodeConfig
    spec:
      cluster: ...
      containerd:
        baseRuntimeSpec:
          process:
            rlimits:
              - type: RLIMIT_NOFILE
                soft: 1024
                hard: 1024
  10. Enable Container Image Caching during AMI build

    main

    To reduce the latency of nodes reaching a Ready state, you can cache specific container images (like kube-proxy and amazon-k8s-cni) during the AMI build process. This is done by setting the cache_container_images variable to true when running the make command.

    cache_container_images=true make 1.23
  11. Collect EKS logs using SSM agent and upload to S3

    main

    You can use the AWS Systems Manager (SSM) agent to run the log collector on worker nodes and automatically upload the resulting bundle to an S3 bucket.

    Prerequisites

    • IAM Permissions: The entity running the commands needs ssm:CreateDocument, ssm:GetCommandInvocation, and ssm:SendCommand. The Worker Node must have AmazonSSMManagedInstanceCore and S3:PutObject permissions for the target bucket.
    • SSM Agent: Must be installed and running on the Worker Node(s).
    • S3 Bucket: A destination bucket must be available to receive the logs.

    Steps

    1. Create the SSM Document: Download the content and create the EKSLogCollectorLinux document.
    2. Execute Command: Use aws ssm send-command targeting the specific instance ID and providing the bucketName parameter.
    3. Monitor Status: Use aws ssm get-command-invocation to track progress.
    # 1. Create the SSM document
    curl -O https://amazon-eks.s3.amazonaws.com/support/log-collector-script/linux/eks-ssm-content.json
    aws ssm create-document \
      --name "EKSLogCollectorLinux" \
      --document-type "Command" \
      --content file://eks-ssm-content.json
    
    # 2. Execute the script on a worker node
    aws ssm send-command \
      --instance-ids <EC2 Instance ID> \
      --document-name "EKSLogCollectorLinux" \
      --parameters "bucketName=<S3 bucket name to push the logs>" \
      --output json
    
    # 3. Check status
    aws ssm get-command-invocation \
      --command-id "<SSM command ID>" \
      --instance-id "<EC2 Instance ID>" \
      --output text
  12. Configure containerd settings

    main

    You can provide additional containerd configuration using an inline TOML document within the NodeConfig. These values will overwrite any defaults set by nodeadm.

    ---
    apiVersion: node.eks.aws/v1alpha1
    kind: NodeConfig
    spec:
      cluster: ...
      containerd:
        config: |
          [plugins."io.containerd.grpc.v1.cri".containerd]
          discard_unpacked_layers = false