A few month back I stumbled across the Weave.works command-line tool eksctl.io to create and manage AWS EKS clusters. Amazon recently announced eksctl.io is the official command-line tool for managing AWS EKS clusters. It follows a similar approach what we have seen with the new openshift-installer to create an OpenShift 4 cluster or with the Google Cloud Shell to create a GKE cluster with a single command and I really like the simplicity of these tools.
Before we start creating a EKS cluster, see below the IAM user policy to set the required permissions for eksctl.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:CreateInstanceProfile",
"iam:DeleteInstanceProfile",
"iam:GetRole",
"iam:GetInstanceProfile",
"iam:RemoveRoleFromInstanceProfile",
"iam:CreateRole",
"iam:DeleteRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:ListInstanceProfiles",
"iam:AddRoleToInstanceProfile",
"iam:ListInstanceProfilesForRole",
"iam:PassRole",
"iam:CreateServiceLinkedRole",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteServiceLinkedRole",
"ec2:DeleteInternetGateway",
"iam:GetOpenIDConnectProvider",
"iam:GetRolePolicy"
],
"Resource": [
"arn:aws:iam::552276840222:instance-profile/eksctl-*",
"arn:aws:iam::552276840222:oidc-provider/oidc.eks*",
"arn:aws:iam::552276840222:role/eksctl-*",
"arn:aws:ec2:*:*:internet-gateway/*"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:DeleteSubnet",
"ec2:AttachInternetGateway",
"ec2:DeleteRouteTable",
"ec2:AssociateRouteTable",
"ec2:DescribeInternetGateways",
"autoscaling:DescribeAutoScalingGroups",
"ec2:CreateRoute",
"ec2:CreateInternetGateway",
"ec2:RevokeSecurityGroupEgress",
"autoscaling:UpdateAutoScalingGroup",
"ec2:DeleteInternetGateway",
"ec2:DescribeKeyPairs",
"ec2:DescribeRouteTables",
"ec2:ImportKeyPair",
"ec2:DescribeLaunchTemplates",
"ec2:CreateTags",
"ec2:CreateRouteTable",
"ec2:RunInstances",
"cloudformation:*",
"ec2:DetachInternetGateway",
"ec2:DisassociateRouteTable",
"ec2:RevokeSecurityGroupIngress",
"ec2:DescribeImageAttribute",
"ec2:DeleteNatGateway",
"autoscaling:DeleteAutoScalingGroup",
"ec2:DeleteVpc",
"ec2:CreateSubnet",
"ec2:DescribeSubnets",
"eks:*",
"autoscaling:CreateAutoScalingGroup",
"ec2:DescribeAddresses",
"ec2:DeleteTags",
"ec2:CreateNatGateway",
"autoscaling:DescribeLaunchConfigurations",
"ec2:CreateVpc",
"ec2:DescribeVpcAttribute",
"autoscaling:DescribeScalingActivities",
"ec2:DescribeAvailabilityZones",
"ec2:CreateSecurityGroup",
"ec2:ModifyVpcAttribute",
"ec2:ReleaseAddress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:DeleteLaunchTemplate",
"ec2:DescribeTags",
"ec2:DeleteRoute",
"ec2:DescribeLaunchTemplateVersions",
"elasticloadbalancing:*",
"ec2:DescribeNatGateways",
"ec2:AllocateAddress",
"ec2:DescribeSecurityGroups",
"autoscaling:CreateLaunchConfiguration",
"ec2:DescribeImages",
"ec2:CreateLaunchTemplate",
"autoscaling:DeleteLaunchConfiguration",
"iam:ListOpenIDConnectProviders",
"ec2:DescribeVpcs",
"ec2:DeleteSecurityGroup"
],
"Resource": "*"
}
]
}
Now let’s create the EKS cluster with the following command:
$ eksctl create cluster --name=cluster-1 --region=eu-west-1 --nodes=3 --auto-kubeconfig
[ℹ] eksctl version 0.10.2
[ℹ] using region eu-west-1
[ℹ] setting availability zones to [eu-west-1a eu-west-1c eu-west-1b]
[ℹ] subnets for eu-west-1a - public:192.168.0.0/19 private:192.168.96.0/19
[ℹ] subnets for eu-west-1c - public:192.168.32.0/19 private:192.168.128.0/19
[ℹ] subnets for eu-west-1b - public:192.168.64.0/19 private:192.168.160.0/19
[ℹ] nodegroup "ng-b17ac84f" will use "ami-059c6874350e63ca9" [AmazonLinux2/1.14]
[ℹ] using Kubernetes version 1.14
[ℹ] creating EKS cluster "cluster-1" in "eu-west-1" region
[ℹ] will create 2 separate CloudFormation stacks for cluster itself and the initial nodegroup
[ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=eu-west-1 --cluster=cluster-1'
[ℹ] CloudWatch logging will not be enabled for cluster "cluster-1" in "eu-west-1"
[ℹ] you can enable it with 'eksctl utils update-cluster-logging --region=eu-west-1 --cluster=cluster-1'
[ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "cluster-1" in "eu-west-1"
[ℹ] 2 sequential tasks: { create cluster control plane "cluster-1", create nodegroup "ng-b17ac84f" }
[ℹ] building cluster stack "eksctl-cluster-1-cluster"
[ℹ] deploying stack "eksctl-cluster-1-cluster"
[ℹ] building nodegroup stack "eksctl-cluster-1-nodegroup-ng-b17ac84f"
[ℹ] --nodes-min=3 was set automatically for nodegroup ng-b17ac84f
[ℹ] --nodes-max=3 was set automatically for nodegroup ng-b17ac84f
[ℹ] deploying stack "eksctl-cluster-1-nodegroup-ng-b17ac84f"
[✔] all EKS cluster resources for "cluster-1" have been created
[✔] saved kubeconfig as "/home/ubuntu/.kube/eksctl/clusters/cluster-1"
[ℹ] adding identity "arn:aws:iam::xxxxxxxxxx:role/eksctl-cluster-1-nodegroup-ng-b17-NodeInstanceRole-1DK2K493T8OM7" to auth ConfigMap
[ℹ] nodegroup "ng-b17ac84f" has 0 node(s)
[ℹ] waiting for at least 3 node(s) to become ready in "ng-b17ac84f"
[ℹ] nodegroup "ng-b17ac84f" has 3 node(s)
[ℹ] node "ip-192-168-5-192.eu-west-1.compute.internal" is ready
[ℹ] node "ip-192-168-62-86.eu-west-1.compute.internal" is ready
[ℹ] node "ip-192-168-64-47.eu-west-1.compute.internal" is ready
[ℹ] kubectl command should work with "/home/ubuntu/.kube/eksctl/clusters/cluster-1", try 'kubectl --kubeconfig=/home/ubuntu/.kube/eksctl/clusters/cluster-1 get nodes'
[✔] EKS cluster "cluster-1" in "eu-west-1" region is ready
Alternatively there is the option to create the EKS cluster in an existing VPC without eksctl creating the full-stack, you are required to specify the subnet IDs for private and public subnets:
eksctl create cluster --name=cluster-1 --region=eu-west-1 --nodes=3 \
--vpc-private-subnets=subnet-0ff156e0c4a6d300c,subnet-0426fb4a607393184,subnet-0426fb4a604827314 \
--vpc-public-subnets=subnet-0153e560b3129a696,subnet-009fa0199ec203c37,subnet-0426fb4a412393184
The option –auto-kubeconfig stores the kubeconfig under the users home directory in ~/.kube/eksctl/clusters/<-cluster-name-> or you can obtain cluster credentials at any point in time with the following command:
$ eksctl utils write-kubeconfig --cluster=cluster-1
[ℹ] eksctl version 0.10.2
[ℹ] using region eu-west-1
[✔] saved kubeconfig as "/home/ubuntu/.kube/config"
Using kubectl to connect and manage the EKS cluster:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-5-192.eu-west-1.compute.internal Ready <none> 3m42s v1.14.7-eks-1861c5
ip-192-168-62-86.eu-west-1.compute.internal Ready <none> 3m43s v1.14.7-eks-1861c5
ip-192-168-64-47.eu-west-1.compute.internal Ready <none> 3m41s v1.14.7-eks-1861c5
You are able to view the created EKS clusters:
$ eksctl get clusters
NAME REGION
cluster-1 eu-west-1
As easy it is to create an EKS cluster you can also delete the cluster with a single command:
$ eksctl delete cluster --name=cluster-1 --region=eu-west-1
[ℹ] eksctl version 0.10.2
[ℹ] using region eu-west-1
[ℹ] deleting EKS cluster "cluster-1"
[✔] kubeconfig has been updated
[ℹ] cleaning up LoadBalancer services
[ℹ] 2 sequential tasks: { delete nodegroup "ng-b17ac84f", delete cluster control plane "cluster-1" [async] }
[ℹ] will delete stack "eksctl-cluster-1-nodegroup-ng-b17ac84f"
[ℹ] waiting for stack "eksctl-cluster-1-nodegroup-ng-b17ac84f" to get deleted
[ℹ] will delete stack "eksctl-cluster-1-cluster"
[✔] all cluster resources were deleted
I can only recommend checking out eksctl.io because it has lot of potentials and the move towards an GitOps model to manage EKS clusters in a declarative way using a cluster manifests or hopefully in the future an eksctld operator to do the job. RedHat is working on a similar tool for OpenShift 4 called OpenShift Hive which I will write about very soon.