들어가며
이번 스터디에서는 Terraform을 통해 AWS EKS를 배포하는 방법에 대해 공부했습니다.
이전 AWES 스터디에서는 EKS에 대해 깊게 학습했지만, Terraform과 각각 스터디를 진행하여 구축하기가 쉽지 않았습니다.
하지만 두 가지 기술 모두 향후 회사에서 유용하게 사용될 기술이라, 스터디를 통해 조금이라도 더 이해해 보고 사용하자는 취지로 집중하여 스터디에 임했습니다.
역시.. 유용한 Best Practice들을 많이 체험할 수 있었습니다.
Amazon EKS Blueprints for Terraform
이 프로젝트는 Terraform으로 구현한 EKS 클러스터 패턴 컬렉션을 통해 개발자들이 빠르게 콘셉트를 이해할 수 있도록 도와 고객이 Amazon EKS를 쉽게 도입할 수 있게 하는 용도입니다.
스터디에서는 EKS Blueprints 프로젝트에서 EKS(컨트롤 플레인)과 Fargate(데이터 플레인) 그리고 Karpenter(오토스케일러)를 통해 AWS환경에서 Terraform을 기반으로 Kubernetes Cluster를 구성하는 방법에 대해 학습했습니다.
레퍼런스를 살펴보면 여러 가지 패턴과 스니펫을 통해 쉽게 클러스터를 개발하도록 예제코드가 제공되고 있습니다. 이 예제들을 통해 콘셉트를 숙지하고 회사 환경에 맞게 적용할 수 있습니다.
하지만 Terraform 모듈을 통해 모듈화 된 코드가 아닌 점과 Local 블록을 통해 싱글 파일로 구축을 하는 점으로 인해 비즈니스 환경에서 사용하는 것은 공식적으로 추천하고 있지 않습니다.
또한 blueprint addon을 통해 EKS addon을 손쉽게 사용할 수 있습니다.
- terraform-aws-eks-blueprint-addon - helm_release서비스 계정(IRSA)에 대한 IAM 역할 외에도 Terraform 리소스를 사용하여 애드온을 프로비저닝 할 수 있는 Terraform 모듈입니다.
- terraform-aws-eks-blueprint-addons - 여러 애드온을 프로비저닝할 수 있는 Terraform 모듈입니다. aws_eks_addon리소스를 사용하는 EKS 애드온과 terraform-aws-eks-blueprint-addon모듈을 사용하는 Helm 차트 기반 애드온 모두입니다.
- terraform-aws-eks-blueprints-teams - Kubernetes 다중 테넌시 리소스와 구성을 생성하는 Terraform 모듈로, 관리자와 애플리케이션 개발자 모두 자신이 책임지는 리소스에만 액세스 할 수 있습니다.
EKS Blueprints for Terraform 코드는 다음과 같이 다운로드할 수 있습니다.
git clone https://github.com/aws-samples/eks-workshop-v2
주의사항
최대한 빠르고 쉽게 패턴을 실행하는 것이 목적이기 때문에, 패턴을 이해하고 직접 구축하는 것이 좋다.
우선 이번 스터디 실습 전에 Fargate와 Karpenter를 간단히 설명하도록 하겠습니다.
Fargate
EKS(컨트롤 플레인) + Fargate(데이터 플레인)의 완전한 서버리스화(=AWS 관리형)
Amazon Fargate는 AWS에서 제공하는 서버리스 컴퓨팅 엔진으로, 컨테이너화된 애플리케이션을 실행할 때 서버나 클러스터를 직접 관리할 필요 없이 사용할 수 있고, 다음과 같은 특징이 있습니다.
- Serverless: 인프라 관리의 부담을 덜어줍니다. 사용자는 클러스터를 프로비저닝하거나 관리할 필요 없이 애플리케이션 실행에만 집중할 수 있습니다.
- 유연성: 각 컨테이너에 필요한 리소스를 개별적으로 설정할 수 있으며, 이를 통해 리소스 사용을 최적화할 수 있습니다.
- 통합: Amazon ECS(Elastic Container Service) 및 Amazon EKS(Elastic Kubernetes Service)와 통합되어 사용됩니다.
- 보안: Fargate는 각 컨테이너가 자체 격리된 환경에서 실행되도록 하여 보안을 강화합니다.
- 자동 확장: 애플리케이션의 요구 사항에 따라 자동으로 확장 및 축소가 가능하여, 사용량에 따라 비용을 절감할 수 있습니다.
Fargate를 사용하면 애플리케이션의 배포, 관리, 확장 등을 더 쉽게 처리할 수 있으며, 서버 관리에 대한 복잡성을 크게 줄일 수 있습니다.
Karpenter
Karpenter는 Kubernetes 클러스터에서 자동으로 스케줄링되는 컨테이너 팟(Pod) 리소스를 관리하기 위한 오픈 소스 프로젝트로써, 대규모 컨테이너 오케스트레이션 시스템으로, 애플리케이션을 여러 컨테이너로 분할하고 이를 클러스터에 배포하고 관리할 수 있도록 도와줍니다.
참고 - 링크
이전 "EKS 워크숍 스터디 - 5주차 Kubernetes Autoscaling 챕터"에서 에서 Karpenter를 이용했던 실습이 있으니, 관심 있으신 분들은 내용을 참고하시면 좋을 것 같습니다.
참고 - 링크
실습 1 - Karpenter on EKS Fargate
사전 준비사항으로는 다음과 같은 툴들이 정상적으로 설치되어 있는지 확인합니다.
awscli(IAM ‘관리자 수전’ 자격증명), terraform, kubectl - Link , helm
aws --version
terraform --version
kubectl version --client=true
helm -h
다음으로 실습을 위한 코드를 다운로드하고 구성을 확인합니다.
git clone https://github.com/aws-ia/terraform-aws-eks-blueprints
cd terraform-aws-eks-blueprints/patterns/karpenter
tree
패턴에 집중하여 작성된 코드들을 확인할 수 있습니다. 또한 스터디장 가시다님의 말씀과 같이 local을 통해 단일 파일에서 환경변수들을 관리합니다. 세부 내용으로는 vpc, fargate, karpenter, eks 등을 설치하는 코드들이 포함되어 있습니다.
우선 사전 준비로 VPC를 생성해 줍니다.
terraform init
terraform apply -target="module.vpc" -auto-approve
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
VPC를 생성하는 코드는 다음과 같습니다.
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
name = local.name
cidr = local.vpc_cidr
azs = local.azs
private_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 4, k)]
public_subnets = [for k, v in local.azs : cidrsubnet(local.vpc_cidr, 8, k + 48)]
enable_nat_gateway = true
single_nat_gateway = true
public_subnet_tags = {
"kubernetes.io/role/elb" = 1
}
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = 1
# Tags subnets for Karpenter auto-discovery
"karpenter.sh/discovery" = local.name
}
tags = local.tags
}
여기서 중요한 점은 private_subnets을 생성할 때 for문을 활용하여 CIDR 구성을 간편화 한 것입니다.
cidersubnet 함수 참고 - 링크
다음으로 나머지 aws, kubernetes, helm, eks, addons를 마저 설치해 줍니다.
여기서는 eks_blueprints_addons 모듈에서 addon들을 손쉽게 만들 수 있도록 템플릿을 만들어놓은 것이 인상 깊었습니다.
karpenter 사용도 boolean으로 쉽게 관리가 됩니다.
배포하고 state list를 살펴보면 eks, vpc, eks.module 등 모듈 별로 설치가 잘 된 것을 확인할 수 있습니다.
terraform apply -auto-approve
terraform state list
echo "data.aws_availability_zones.available" | terraform console
vpc에 커스텀하게 붙여놓은 tag가 붙어있는 모습을 확인할 수 있습니다.
다음으로 로컬에서 eks 클러스터에 접근할 수 있도록 자격증명을 세팅합니다.
이렇게 하면 현재 사용자의 ~/.kube/config에 자격증명 파일이 생성되어 EKS 클러스터에 접속이 가능합니다.
aws eks --region ap-northeast-2 update-kubeconfig --name t101-karpenter
# k8s 노드, 파드 정보 확인
kubectl cluster-info
kubectl get node
kubectl get pod -A
클러스터 정보를 조회하면 다음과 같이 잘 생성된 것을 확인할 수 있습니다.
kubectl get nodes
EKS node viewr를 설치하여 클러스터의 상황을 모니터링해보면 Fargate를 통해 인스턴스가 생성된 것을 확인할 수 있습니다.
eks-node-viewer --resources cpu,memory
kube-ops-view를 통해 각 노드의 Pod 배포상태를 모니터링해 보았습니다.
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
실습 - Karpenter on Amazon EKS Blueprints for Terraform
앞서 프로비저닝 한 인프라에 karpenter를 설치하고, 샘플 Deployment를 배포합니다.
kubectl apply -f karpenter.yaml
kubectl apply -f example.yaml
kubectl scale deployment inflate --replicas=3 && kubectl get pod -w
pod는 배포되었지만, 아무리 기다려도 인스턴스가 생성되지 않습니다.
그래서 Karpenter 컨트롤러 로그를 확인해 보았습니다.
트러블 슈팅
사전에 스폿 인스턴스 생성에 대한 권한이 없을 경우, 다음과 같은 에러가 발생합니다.
AuthFailure.ServiceLinkedRoleCreationNotPermitted: The provided credentials do not have permission to create the service-linked role for EC2 Spot Instances.
검색을 통해 spot 인스턴스 생성권한을 iam의 role로 추가해 줍니다.
aws iam create-service-linked-role --aws-service-name spot.amazonaws.com
https://docs.aws.amazon.com/batch/latest/userguide/spot_fleet_IAM_role.html
https://github.com/eksctl-io/eksctl/issues/6064
사실 검색하고 나니, 스터디 자료 다른 파트 실습에 해당 내용이 있었습니다 : )
생성
이를 해결하고 나니 다음과 같이 잠시 후 스폿인스턴스가 잘 생성되고, 파드가 배치되는 것을 확인할 수 있었습니다.
삭제
# kube-ops-view 삭제
helm uninstall kube-ops-view -n kube-system
# addon & karpenter helm 삭제 : 1분 소요
terraform destroy -target="module.eks_blueprints_addons" -auto-approve
# EKS 삭제 : 8분 소요
terraform destroy -target="module.eks" -auto-approve
# VPC 삭제 : vpc 삭제가 잘 안될 경우 aws 콘솔에서 vpc 수동 삭제 -> vnic 등 남아 있을 경우 해당 vnic 강제 삭제
terraform destroy -auto-approve
# VPC 삭제 확인
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=false' --output yaml
# kubeconfig 삭제
rm -rf ~/.kube/config
파드 삭제 시에는 리소스가 반환되고 파드 삭제결과가 확인됩니다.
조금 더 기다리면 인스턴스도 삭제되는 것을 확인할 수 있습니다.
실습 - EKS Workshop
EKS 실습을 위해 AWS에서 Terraform 코드로 실습환경을 만들어 놓았습니다.
git clone https://github.com/aws-samples/eks-workshop-v2
cd eks-workshop-v2/cluster/terraform
terraform apply -auto-approve
다음으로 EKS 클러스터 접근 권한과 AmazonEKSClusterAdminPolicy를 설정해 줍니다.
(EKS Access Entries 정책이 자동으로 추가되지 않도록 되어있습니다.)
kubectl cluster-info
# EKS 자격증명
## aws eks --region <REGION> update-kubeconfig --name <CLUSTER_NAME> --alias <CLUSTER_NAME>
aws eks --region ap-northeast-2 update-kubeconfig --name eks-workshop
cat ~/.kube/config
# k8s 클러스터 정보 확인
kubectl cluster-info
# 각자 자신의 IAM User 의 access entry 생성
ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
MYIAMUSER=<각자 자신의 IAM User>
MYIAMUSER=admin
echo $ACCOUNT_ID $MYIAMUSER
aws eks create-access-entry --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER}
aws eks list-access-entries --cluster-name eks-workshop
# 각자 자신의 IAM User에 AmazonEKSClusterAdminPolicy 연동
aws eks associate-access-policy --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} \
--policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy --access-scope type=cluster
aws eks list-associated-access-policies --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} | jq
aws eks describe-access-entry --cluster-name eks-workshop --principal-arn arn:aws:iam::${ACCOUNT_ID}:user/${MYIAMUSER} | jq
# (참고) context name 변경
kubectl config rename-context "arn:aws:eks:ap-northeast-2:$(aws sts get-caller-identity --query 'Account' --output text):cluster/eks-workshop" "T101-Lab"
kubectl cluster-info
다음과 같이 정상적으로 클러스터 정보가 나오는 것을 확인할 수 있습니다.
다음으로 kube ops view를 설치하고, cluster의 상황을 모니터링해 봅니다.
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
# 포트 포워딩
kubectl port-forward deployment/kube-ops-view -n kube-system 8080:8080
마치며
이번 시간에는 Terraform을 이용한 AWS EKS 배포 방식에 대해 학습했습니다. 현재 프로젝트에 사용하고 있는 쿠버네티스 클러스터는 3개의 worker node로 정적 구성되어 있습니다. Terraform이 선언형이다 보니 동적으로 설정을 어떻게 하는 것이 좋을지 고민하고 있었는데, 스터디를 통해서 Fargate + Karpenter 조합으로 구성하는 방식을 알게 되어, 빠른 시일 내에 적용해 보아야겠다는 생각이 들었습니다.
또한 EKS workshop을 Terraform을 통해 쉽게 구성을 할 수 있게 되어, 나머지 과정들을 통해 EKS를 좀 더 익숙하게 스터디해 볼 예정입니다. (이번 기회에 하고 싶은데.. 체력이 안 따라주네요.. 피..핑계)
그럼 다음 스터디에서 뵙겠습니다.
감사합니다 :)
'클라우드 컴퓨팅 & NoSQL > [T101] 테라폼 4기 스터디' 카테고리의 다른 글
[8주차 - OpenTofu ] T101 4기 스터디 (24.07.28) (0) | 2024.08.02 |
---|---|
[6주차 - Well-Architected 방식으로 워크로드를 안전하게 마이그레이션 및 현대화하기 Workshop ] T101 4기 스터디 (24.07.14) (0) | 2024.07.17 |
[5주차 - 모듈 & Runner] T101 4기 스터디 (24.07.07) (1) | 2024.07.13 |
[4주차 - Provider & State] T101 4기 스터디 (24.06.30) (0) | 2024.07.04 |
[3주차 - 기본사용#3] T101 4기 스터디 (24.06.23) (0) | 2024.06.29 |