eksctl을 활용한 테스트용 eks를 구축
비용 효율적인 스팟인스턴스를 사용한 EKS를 구축해봄으로써 테스트 환경의 비용절감과 Unmanaged nodegroup을 사용해
스팟 인스턴스의 단점인 불안정성을 보완하는 환경을 구축해보는 테스트를 진행했다.
EKS Spot Instance
- 목적 : 테스트나 개발 단계에서 EKS를 활용할 때 Spot Instance를 사용해 비용 절감
- 상황 : Spot Instance는 저렴한 가격으로 이용할 수 있지만 Instance가 가격 변동이 생기면 자동으로 Terminate 됨
- 목표 : Spot Instance를 사용해 비용을 절감하면서 기존 단점인 안정성을 확보할 수 있는 방안
Spot Instance는 On-Demand Instance 보다 40~80% 정도 저렴합니다.
Instance Type, Availability Zones에 따라 다름
Spot Instance는 가격이 실시간으로 변동된다. → 가격 변동, Zone에 가용 용량이 부족한 경우 2분 내에 회수 됨
Spot Instance 가격은 AWS Console → EC2 → SpotRequest → Pricing history에서 확인 할 수 있습니다.
AWS Console에서는 Type과 하나의 Instance만 선택 할 수 있기 때문에 가격변동에 취약해 지게 됩니다.
그래서 eksctl을 활용해서 Eks 클러스터와 노드 그룹을 구성하게 되었습니다.
Spot NodeGroup 구성
- 목표 : eksctl을 활용한 Cluster, NodeGroup 구성
- 사전 준비 :
- aws cli, eksctl 설치된 환경
- AWS AccessKey, IAM Role : ssm(System Manager), Cloud Formation 권한 등 필요
eksctl을 사용하면 다양한 옵션을 포함한 Nodegroup을 생성할 수 있습니다.
하지만 명령어 보단 수정과 관리가 편한 Config 파일로 진행하였습니다.
명령어 사용 예시
eksctl create nodegroup \
--cluster=eksworkshop-eksctl --region=${AWS_REGION} \
--managed --spot --name=ng-spot \
--instance-types=m5.large,m4.large,m5d.large,m5a.large,m5ad.large,m5n.large,m5dn.large
Config 파일 예시
다양한 파라미터가 있지만 제가 사용한 예시입니다.
다른 파라미터는https://eksctl.io/usage/schema/#nodeGroups-instancesDistribution 참고해 주세요
Cluster와 NodeGroup을 한번에 생성
eksctl에는 NodeGroup과 ManagedNodeGroup 두가지 방법으로 클러스터에 노드를 배포 할 수 있는데,
제가 테스트 해보았을 때는 ManagedNodeGroup은 기존 웹 콘솔 만큼만 설정이 가능한 것 같았습니다.
eksctl create cluster -f config.yaml
# 노드그룹만 배포를 하는 경우
eksctl create nodegroup -f config.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: ${Cluster_Name}
region: ${AWS_REGION}
version: ${Kubernetes_Version}
# 클러스터 설정
vpc:
id: "${VPC_ID}"
autoAllocateIPv6: false
clusterEndpoints:
privateAccess: true
publicAccess: true
#sharedNodeSecurityGroup: "${SG_ID}"
subnets:
public:
ap-northeast-2a:
id: "PUBILC_SUBNET_ID"
ap-northeast-2b:
id: "PUBILC_SUBNET_ID"
ap-northeast-2c:
id: "PUBILC_SUBNET_ID"
private:
ap-northeast-2a:
id: "PRIVEATE_SUBNET_ID"
ap-northeast-2b:
id: "PRIVEATE_SUBNET_ID"
ap-northeast-2c:
id: "PRIVEATE_SUBNET_ID"
nodeGroups: # 노드 그룹 생성
- name: ${NG_NAME}
iam: # iam 옵션을 지정해주지 않으면 노드에 아무 권한이 없음
withAddonPolicies:
imageBuilder: true
autoScaler: true
externalDNS: true
certManager: true
appMesh: true
appMeshPreview: true
ebs: true
awsLoadBalancerController: true
xRay: true
cloudWatch: true
amiFamily: AmazonLinux2
availabilityZones: [ # 가용가능한 Zone 설정 Cluster의 AZ와 같게 설정
"ap-northeast-2a",
"ap-northeast-2b",
"ap-northeast-2c"
]
privateNetworking: false
minSize: 3
maxSize: 5
desiredCapacity: 3
volumeSize: 30
volumeType: gp2
instancesDistribution:
maxPrice: 0.10
instanceTypes:
- c5.xlarge
- m6g.xlarge
- m6gd.xlarge
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 20 # all the instances will be Spot Instances = 0
spotAllocationStrategy: capacity-optimized
조금 자세하게 다룰 부분은 아래 부분이라고 생각합니다.
instancesDistribution:
maxPrice: 0.10
instanceTypes:
- c5.xlarge
- m6g.xlarge
- m6gd.xlarge
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 20 # all the instances will be Spot Instances = 0
spotAllocationStrategy: capacity-optimized
maxPrice : 인스턴스의 최대 가격
옵션을 사용해서 스팟 인스턴스 타입의 최근 3개월 가격(0.64~0.7) 보다 높은가격으로 설정해서
가격변동으로 종료될 변수를 줄였습니다. → 안정성 확보
instanceTypes : 인스턴스 타입 설정
기존 웹 콘솔에서와는 동일한 스펙의 여러 인스턴스를 리스트로 선언해서 가용가능한 인스턴스가 부족할 경우
2순위, 3순위 인스턴스를 찾게 됩니다.
onDemandBaseCapacity : 온디멘드 인스턴스의 갯수
onDemandPercentageAboveBaseCapacity : 온디멘드 인스턴스 비율
옵션으로 on-demand 인스턴스를 섞어서 사용할 수도 있습니다. * (전부 Spot으로 사용할 시 둘다 0으로 설정)
spotAllocationStrategy : Spot 정책
클러스터에서 Spot 중단 수를 줄이기 위해 가장 많은 가용 용량으로 Spot Instance Pool에서 Instance를 시작하는 spotAllocationStrategy로 capacity-optimized를 지정했습니다. → 가장 안정성 높은 정책
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-fleet-allocation-strategy.html
IaC 활용법
추가적으로 Spot Blueprints라는 기능을 활용해 Cloud Formation이나 Terraform 코드로 템플릿을 쉽게 생성 할 수 있습니다. (추후 테스트 예정)
IAM Role이나 VPC 등을 설정 할 수 있고 템플릿 받은 후에 추가적인 수정을 하면 좀더 손쉽게 IaC를 이용한
Spot Instance 활용 가능할 것 같습니다.
addons 설정
eksctl을 좀더 테라폼 처럼 활용해보고 싶어 addon을 추가해보았습니다.
결과부터 말씀드리면 생각보다 엄청 단순하게 생성할 수 있었다.
eksctl을 사용해서 만들면 iam, policy 등을 생성할 필요가 없고 얘네가 자동으로 생성하고 attach도 시켜줘서 간편합니다.
( 노드그룹에 권한이 있어서 인지? )
iam:
withOIDC: true
addons:
- name: vpc-cni
# all below properties are optional
version: v1.15.1-eksbuild.1
- name: coredns
version: v1.10.1-eksbuild.4
- name: kube-proxy
version: v1.28.2-eksbuild.2
- name: aws-ebs-csi-driver
version: v1.26.1-eksbuild.1
위의 코드만 추가해주어도 addon이 생성되면서 aws-ebs-csi-driver 같은 경우에는 Role도 자동으로 생성해주고 addon에
attach도 자동으로 해줘서 간편합니다.
기타 유의사항
추가적으로 테스트 과정에서 생겼던 몇가지 이슈에 대해 말씀드리겠습니다.
- 스팟 인스턴스를 처음에 검색할 당시 사용 가능 리전에 대한 정보만으로 인스턴스 리스트를 작성했는데 AZ 별로 구분 됨
- Cluster가 설정된 AZ에 가용 인스턴스가 없으면 노드그룹 생성 안됨
# 가용 가능 AZ 확인 방법
❯ aws ec2 describe-instance-type-offerings --location-type availability-zone \
--filters Name=instance-type,Values=c5.xlarge --region ap-northeast-2 --output table
------------------------------------------------------------
| DescribeInstanceTypeOfferings |
+----------------------------------------------------------+
|| InstanceTypeOfferings ||
|+--------------+-------------------+---------------------+|
|| InstanceType | Location | LocationType ||
|+--------------+-------------------+---------------------+|
|| c5.xlarge | ap-northeast-2a | availability-zone ||
|| c5.xlarge | ap-northeast-2c | availability-zone ||
|| c5.xlarge | ap-northeast-2b | availability-zone ||
|| c5.xlarge | ap-northeast-2d | availability-zone ||
|+--------------+-------------------+---------------------+|
(END)
❯ aws ec2 describe-instance-type-offerings --location-type availability-zone \
--filters Name=instance-type,Values=c4.8xlarge --region ap-northeast-2 --output table
------------------------------------------------------------
| DescribeInstanceTypeOfferings |
+----------------------------------------------------------+
|| InstanceTypeOfferings ||
|+--------------+-------------------+---------------------+|
|| InstanceType | Location | LocationType ||
|+--------------+-------------------+---------------------+|
|| c4.8xlarge | ap-northeast-2a | availability-zone || # a,c 만 가능
|| c4.8xlarge | ap-northeast-2c | availability-zone ||
|+--------------+-------------------+---------------------+|
(END)
- eksctl로 클러스터를 생성할 때 생성 실패시 stack이 남아서 같은 이름으로 생성 불가
- 버그로 판명됐는데 아직 고쳐지지 않았다고 합니다.
- 그나마 대처 가능한 방법으로 스택 삭제하는 코드입니다.
- aws --region ap-northeast-2 cloudformation delete-stack --stack-name eksctl-${CLUSTER_NAME}-cluster
- 추가로 스택에 의한 문제는 콘솔에서 스택을 삭제하거나 실행 시작했던 eks의 cluster name을 delete해주면 스택이 삭제되며 정상작동됩니다.
- 생성 시 eksctl create cluster --dry-run 명령어로 확인해보는 것을 권장.
요약
- Eks를 사용할 때 1/3 가격정도로 테스트 가능
- eksctl nodegroup을 활용해서 웹 콘솔보다 조금 안정적으로 Spot 인스턴스를 활용 가능합니다.
- 인스턴스 가격과 리스트를 넓게 조정해서 안정성을 확보.
- 하지만 AZ에 인스턴스가 부족하면 인스턴스가 변경되는 경우가 있기 때문에 테스트나 개발 환경으로만 사용하는 것이 바람직해 보입니다.
'Engineering' 카테고리의 다른 글
AWS External ALB, Internal ALB, EKS Targetgroupbinding 구성 (0) | 2024.03.08 |
---|---|
AWS EKS ALB 하나로 여러 Ingress 구성 ( Ingress Group, TargetGroupBinding) (0) | 2024.02.06 |
OpenTelemetry Beginner & Kubernetes (1) | 2024.01.24 |
OpenTelemetry Beginner & Kubernetes (0) | 2024.01.16 |
Helm Chart 인덱스 파일과 패키지 생성 및 GitHub 페이지로 호스팅하기 (1) | 2023.12.08 |