This project demonstrates the creation of an AWS EKS (Elastic Kubernetes Service) cluster and the deployment of a sample application. It focuses on:
- Configuring necessary IAM roles.
- Creating a VPC for worker nodes using a CloudFormation template.
- Setting up an EKS cluster (Control Plane nodes).
- Creating and attaching a Node Group to the EKS cluster for worker nodes.
- Configuring auto-scaling for the worker nodes.
- Deploying a sample NGINX application to the EKS cluster.
- Kubernetes
- AWS EKS
AWS Identity and Access Management (IAM) roles are essential to manage access to the AWS resources required by the EKS cluster. Follow these steps to create the necessary role:
- Log in to the AWS Management Console.
- Navigate to the IAM service and select Roles from the sidebar.
- Click Create Role to start creating a new IAM role.
- In the Select Trusted Entity section, choose EKS as the service and select the EKS - Cluster use case.
- Click Next. The system automatically selects the
AmazonEKSClusterPolicy. Expand this policy to review the list of permissions it grants. - Click Next to proceed.
- Provide a name for the role, such as
eks-cluster-role. - Click Create Role. The
eks-cluster-roleis now created and ready to be used during EKS cluster creation.
Refer to Setting up AWS EKS for additional information.
EKS clusters require specific networking configurations that include both Kubernetes-specific and AWS-specific networking rules. The default VPC is not optimized for this purpose. A new VPC is created for the worker nodes to ensure compatibility and security. Worker nodes require a firewall configuration to allow control plane nodes to connect and manage them effectively. Note that the control plane runs on an AWS-managed VPC, while worker nodes operate in the user-created VPC.
Best Practice: Create a mixture of public and private subnets within the VPC.
Follow these steps to create the VPC:
- Go to the AWS Management Console and navigate to the CloudFormation service.
- Click Create Stack.
- Copy the template link from the AWS EKS User Guide's page on Creating a VPC for your Amazon EKS Cluster. Use the following S3 link for the VPC creation template with public and private subnets: amazon-eks-vpc-private-subnets.yaml.
- In the CloudFormation Create Stack page, select Template is ready and Amazon S3 URL as the source. Paste the copied link into the URL field.
- Click Next and provide a stack name, e.g.,
eks-worker-node-vpc-stack. - Review the parameters for IP address ranges of subnets in the worker node network configuration. Adjust if needed.
- Click Next, keep the default settings, and click Next again.
- Review the summary page of the stack to be created, then click Submit.
- Once the stack creation is complete, navigate to the Outputs tab of the stack to retrieve the details such as the security group, subnet IDs, and VPC ID.
The VPC for worker nodes is now ready, with all necessary configurations in place for seamless integration with the EKS cluster.
The Control Plane for the EKS cluster can be set up through the AWS Management Console. Follow these steps:
- Log in to the AWS Management Console and navigate to the Amazon EKS page.
- Click Add cluster and select Create cluster.
- Enter a cluster name, such as
eks-cluster-test. - Verify the Kubernetes version and leave it at the default setting.
- Ensure that the
eks-cluster-rolecreated earlier is selected in the Cluster service role field. - Click Next to proceed to networking configuration.
- Select the VPC created in Step 2 (e.g.,
eks-worker-node-vpc-stack-VPC). Subnets will be automatically selected. - Select the security group related to the EKS worker node VPC.
- For Cluster endpoint access, choose Public and private, and click Next.
- Leave the default settings unselected for control plane logging and click Next.
- In the Select add-ons page, ensure that the default add-ons (CoreDNS, kube-proxy, and Amazon VPC CNI) are selected, and click Next.
- Keep the default versions for the add-ons and click Next again.
- On the review page, confirm all configurations and click Create.
The EKS cluster will begin provisioning. Once completed, it will be ready for further configuration and Node Group attachment.
To interact with the cluster, configure kubectl:
- Open a terminal and create a kubeconfig file for the newly created EKS cluster.
- Review the default region using the following command to ensure it matches the region where the cluster was created:
aws configure list
- Run the following command to create the kubeconfig file locally:
aws eks update-kubeconfig --name eks-cluster-test
- The kubeconfig file will be located in the
.kube/configfolder. View the context entry for the cluster in this file and confirm that the current context points to the newly created cluster.
Run the following kubectl commands to verify the connection:
- Check nodes in the cluster (output will indicate no resources as nodes aren't yet created):
Output:
kubectl get nodes
No resources found - List namespaces in the cluster:
Output:
kubectl get ns
default kube-node-lease kube-public kube-system - Get cluster information, including the API server endpoint:
kubectl cluster-info
At this point, kubectl is successfully connected to the EKS cluster and is communicating with the API server in the control plane.
Create an IAM role for the worker nodes with necessary policies by following these steps:
- Go to the IAM page in the AWS Management Console.
- Click Roles in the sidebar and select Create Role.
- In the Trusted Entity section, ensure AWS service is selected.
- Under Use Case, select EC2 and click Next.
- In the Add Permissions step, add the following policies:
AmazonEKSWorkerNodePolicyAmazonEC2ContainerRegistryReadOnlyAmazonEKS_CNI_Policy
- Click Next to proceed.
- Enter a name for the role, such as
eks-cluster-node-group-role, and review the selected policies. - Click Create Role. The
eks-cluster-node-group-roleis now ready to be attached to the Node Group.
Node Groups provide the computational power for workloads. Follow these steps to create and attach a Node Group to the EKS cluster:
- Go to the EKS cluster
eks-cluster-testin the AWS Management Console. - Click on Compute and then click Add Node Group.
- Provide a name for the node group, e.g.,
eks-node-group. - Select the IAM role
eks-node-group-rolecreated in Step 5 for the Node IAM role. - Click Next.
- On the Node group compute configuration page:
- Leave the AMI type as the default
Amazon Linux 2. - Set the capacity type to
On-Demand. - Choose the instance type, e.g.,
t3.small. - Leave the disk size as the default
20 GiB.
- Leave the AMI type as the default
- For the Node group scaling configuration, set the desired, minimum, and maximum nodes to
2. - Leave the Node group update configuration at the default value of
1 nodeand click Next. - Review the selected subnets and toggle on Configure remote access to nodes.
- In EC2 Key Pair, select an existing key pair (e.g.,
docker-server) to enable SSH access to the instances. - Under Allow remote access from, select All and click Next.
- Review the configuration and click Create.
- Navigate to the EC2 console to verify that instances are being launched.
- Return to the EKS cluster page to confirm the status of
eks-node-groupas Active. - Open a terminal and run the following command to verify the nodes:
This will display the created nodes.
kubectl get nodes
If additional compute capacity is required later, you can edit the node group scaling configuration from the EKS page. However, to save infrastructure costs, it is recommended to configure a cluster autoscaler, which will be addressed in the next step.
Auto-scaling ensures that the cluster scales up or down based on workloads. Follow these steps:
-
Go to the IAM page in the AWS Management Console.
-
Create a new policy with the following permissions:
{ "Version": "2012-10-17", "Statement": [ { "Action": [ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeLaunchConfigurations", "autoscaling:DescribeTags", "autoscaling:SetDesiredCapacity", "autoscaling:TerminateInstanceInAutoScalingGroup", "ec2:DescribeLaunchTemplateVersions" ], "Resource": "*", "Effect": "Allow" } ] } -
Click Next, specify the policy name as
node-group-autoscale-policy, review the permissions, and click Create policy. -
Attach the policy to the existing Node Group IAM role:
- Go to Roles in IAM and select
eks-node-group-role. - Click Attach policies under Add permissions.
- Select
node-group-autoscale-policyand click Add permissions.
- Go to Roles in IAM and select
-
Deploy the Cluster Autoscaler:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
-
Edit the Cluster Autoscaler deployment to configure it for the EKS cluster:
kubectl edit deployment cluster-autoscaler -n kube-system
- Add the following annotation:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
- In the specs, configure the cluster name as
eks-cluster-testand add these options:- --balance-similar-node-groups - --skip-nodes-with-system-pods=false
- Update the image version to match the Kubernetes version running in the cluster. Refer to the Cluster Autoscaler Tags page for the relevant version.
- Add the following annotation:
-
Save the changes. You should see a message indicating the deployment has been edited:
deployment.apps/cluster-autoscaler edited -
Verify the Autoscaler pod is running:
kubectl get pod -n kube-system
-
Check the pod logs to observe the scaling process:
kubectl logs -f <cluster-autoscaler-pod-name> -n kube-system
-
To test Autoscaler functionality, reduce the desired and minimum number of nodes to
1in the Node Group scaling configuration from the EKS page. Check the logs of the Autoscaler pod for events related to scaling down.
By configuring Autoscaler, you enable the EKS cluster to automatically adjust its compute capacity, optimizing cost and performance.
Deploy a sample NGINX application to test the cluster setup. Steps include:
- Create a configuration file (
nginx-config.yaml) with the following content:apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: LoadBalancer ports: - port: 80 targetPort: 80 selector: app: nginx
- Apply the configuration:
kubectl apply -f nginx-config.yaml
- Verify the pods and service:
kubectl get pods kubectl get svc
- Note the LoadBalancer endpoint in the output of
kubectl get svc. - Open the AWS Management Console and navigate to the EC2 page.
- Under Load Balancers, locate the LoadBalancer created for the NGINX application and verify the DNS endpoint matches the one displayed by
kubectl get svc nginx. - Copy the LoadBalancer URL and paste it into a web browser to access the running NGINX application.
Note: The LoadBalancer is created in the public subnet.
To test autoscaling:
- Increase the number of replicas for the NGINX deployment to 20:
kubectl scale deployment nginx-deployment --replicas=20
- Observe some pods in a pending state while the Cluster Autoscaler scales up the nodes.
- Check the Autoscaler logs to monitor the scale-up process:
kubectl logs -f <cluster-autoscaler-pod-name> -n kube-system
- Verify the increased number of nodes and ensure all pods are in the running state:
kubectl get nodes kubectl get pods