Deploy Amazon EKS and NodeGroups using CloudFormation

이민석's avatar
Mar 03, 2024
Deploy Amazon EKS and NodeGroups using CloudFormation

Introduction

Thank you for clicking through to my arcticle. I've been a DevOps engineer for 2 years in dev-team of 7 engineers.

My name is MINSEOK, LEE, but I use Unchaptered as an alias on the interenet. So, you can call me anythings "MINSEOK, LEE" or "Unchaptered" to ask something.

This article is based on learning content of 1 week, AEWS 2.

Topic

In this article, I'll cover the followings:

  1. Deploy EKS Control Plane

  2. Deploy EKS Data Plane, Managed Node Groups using kubectl.

This main codes is written in unchaptered/iac-storage.
You can easily deploy Amazon EKS using the cli by following this article.
I've prepared dual scripts for CMD (Windows 11) and Shell (Linux+)."

It also walks you through how to use Private ECR.

Warning / Warning / Warning
If you end the practice, be sure to go through "11. Delete All Resources"

Keywords

  • LocalHostMachine
    Your pc, laptob command input box.

  • EC2, ClientHost
    On instances after step 1, in the command input box.

0. Get Ip Address

curl -s ipinfo.io/ip

1. Deploy K8S Control Plain (Local LocalHostMachine)


# Win, Cmd
for /f %i in ('curl -s ipinfo.io/ip') do aws cloudformation deploy  ^
    --template-file ./myeks-1week.yaml                              ^
    --stack-name myeks                                              ^
    --parameter-overrides KeyName=myeks-pem SgIngressSshCidr=%i/32  ^
    --region ap-northeast-2                                         ^
    --profile eksprac

# Ubuntu, Shell
aws cloudformation deploy                        \
    --template-file         ./myeks-1week.yaml   \
    --stack-name            myeks                \
    --parameter-overrides   KeyName=myeks-pem SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32   \
    --region                ap-northeast-2       \
    --profile               eksprac

2. Access K8S Control Plain (Local LocalHostMachine)

  • CMD, Windows

    for /f %i in ('aws ec2 describe-instances --filters "Name=tag:Name,Values=myeks-host" ^
                                --query "Reservations[0].Instances[0].PublicIpAddress"    ^
                                --profile eksprac') do ssh root@%i

  • ShellScript, Linux

    
    ssh root@$(aws ec2 describe-instances --filters "Name=tag:Name,Values=myeks-host"  \
                                --query "Reservations[0].Instances[0].PublicIpAddress" \
                                --profile eksprac)

3. Configure IAM Credentials (EC2, ClientHost)

aws configure

4. Set up environment (EC2, ClientHost)


# 4.1. Set env value (Key:VPCID)
export VPCID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=$CLUSTER_NAME-VPC" | jq -r .Vpcs[].VpcId)
echo "export VPCID=$VPCID" >> /etc/profile
echo $VPCID

# 4.2. Check VPC Subnet
aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPCID" --output yaml | yh

export PubSubnet1=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet1" --query "Subnets[0].[SubnetId]" --output text)
export PubSubnet2=$(aws ec2 describe-subnets --filters Name=tag:Name,Values="$CLUSTER_NAME-PublicSubnet2" --query "Subnets[0].[SubnetId]" --output text)

echo "export PubSubnet1=$PubSubnet1" >> /etc/profile
echo "export PubSubnet2=$PubSubnet2" >> /etc/profile

echo $PubSubnet1
echo $PubSubnet2

5. Install HELM (EC2, ClientHost) (Skipped, Already Installed)

In step 1, cloudformation install helm already.
But if you wanna manually install helm, follow it.

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

6. Create EKS Cluster and NodeGroup (EC2, ClientHost)

You can check cluster template with --dry-run options.

# 6.1. Check Cluster Files with dry run
eksctl create cluster                               \
    --name $CLUSTER_NAME                            \
    --region=$AWS_DEFAULT_REGION                    \
    --nodegroup-name=$CLUSTER_NAME-nodegroup        \
    --node-type=t3.medium                           \
    --node-volume-size=32                           \
    --node-ami-family Ubuntu2004                    \
    --vpc-public-subnets "$PubSubnet1,$PubSubnet2"  \
    --version 1.28                                  \
    --ssh-access                                    \
    --external-dns-access                           \
    --verbose 4                                     \
    --dry-run | yh

# 6.2. Deploy
eksctl create cluster                               \
    --name $CLUSTER_NAME                            \
    --region=$AWS_DEFAULT_REGION                    \
    --nodegroup-name=$CLUSTER_NAME-nodegroup        \
    --node-type=t3.medium                           \
    --node-volume-size=32                           \
    --node-ami-family Ubuntu2004                    \
    --vpc-public-subnets "$PubSubnet1,$PubSubnet2"  \
    --version 1.28                                  \
    --ssh-access                                    \
    --external-dns-access                           \
    --verbose 4

7. Download and Install Nginx-Ingreee-Controller (EC2, ClientHost)

# 7.1. Add nginx-stable using helm
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update

# 7.2. Install nginx-ingress using helm
helm install nginx-ingress nginx-stable/nginx-ingress --set rbac.create=true

helm install nginx-ingress-controller nginx-ingress/nginx-ingress-controller -f helm.nginx.ingress.controller.yml

kubectl get services nginx-ingress-controller

8. Watch logs of Nginx-Ingress-Controller (EC2, ClientHost)

kubectl logs -f $(kubectl get pods -l app.kubernetes.io/instance=nginx-ingress -o custom-columns=:metadata.name)

9. Uplaod Server Application into ECR (EC2, LocalHostMachine)

# 9.1. Create ECR Repository
aws ecr create-repository               ^
    --repository-name myeks_app_ecr     ^
    --tags Key=Name,Value=myeks_app_ecr ^
    --profile eksprac
    
# 9.2. Describe ECR Repository
aws ecr describe-repositories                                   ^
    --query "repositories[?repositoryName=='myeks_app_ecr']"    ^
    --query "repositories[0].repositoryUri"                     ^
    --profile eksprac

# 9.3. Get ECR Password
aws ecr get-login-password  ^
    --region ap-northeast-2 ^
    --profile eksprac

# 9.4. Docker Login
docker login --username AWS --password <PASSWORD> <ECR_URI>

# 9.5. Cd codes
cd ./app

docker build -t myeks_app_ecr .

docker tag myeks_app_ecr <ECR_URI>
docker push <ECR_URI>

docker tag myeks_app_ecr <ACCOUNT_ID>.dkr.ecr.ap-northeast-2.amazonaws.com/myeks_app_ecr:latest
docker push <ACCOUNT_ID>.dkr.ecr.ap-northeast-2.amazonaws.com/myeks_app_ecr:latest

10. Create K8S Deployment (EC2, ClientHost)


kubectl apply -f k8s.server.yml

kubectl expose deployment d-myeks-app-ecr --name svc-myeks-app-ecr --port=80 --target-port=80 --type=LoadBalancer

kubectl apply -f k8s.nginx.ingress.controller.yml

11. Delete all resources (EC2, ClientHost -> LocalHostMachine)

eksctl delete cluster --name $CLUSTER_NAME

aws cloudformation delete-stack --stack-name myeks


 

Share article

Unchaptered