개요
올리브영 온라인 쇼핑몰 public cloud(AWS) 인프라 구축 프로젝트
CloudWave 3기의 1조(5명) 조장을 맡아 올리브영 온라인 쇼핑몰 AWS 인프라 구축 프로젝트를 진행했습니다.(2024.08.08 ~ 2024.08.30) R&R: PM - 아키텍처 설계 및 구축 - Terraform을 이용해 EKS 구축 - Continuous
jsyeo.tistory.com
CloudWave 프로젝트를 진행하며 EKS를 구축한 방법은 다음과 같습니다.
먼저 메인 아키텍처를 설계한 후, 수동으로 VPC와 subnet, nat gateway, cli server를 만들고, sesseion manager를 사용하기 위해 필요한 보안 그룹과 IAM 역할, VPC Endpoint를 생성하여 session manager를 통해 cli server에 접속해 eksctl로 EKS cluster를 생성하는 방식으로 인프라를 구축하였습니다.
그러나 프로젝트 평가 기준 중, 3주간 사용한 비용이 2000$를 넘으면 안된다는 항목이 있었고, 인프라 사용 비용을 줄이기 위해 오전 9시에 인프라를 생성하고, 오후 9시에 생성했던 인프라를 모두 삭제하는 작업을 반복하였습니다.
이러한 반복 작업에 시간을 낭비하고 싶지 않아서 빠르게 Terraform을 작성해 인프라 생성 및 삭제에 활용하였습니다. 이를 통해 프로젝트 중간 발표 이전 약 1주 반의 기간 동안 약 200$만을 사용하며 전체 팀 중 가장 적은 비용을 사용할 수 있었습니다.
이 때, On demand로 요금이 청구되는 서비스나 AWS 글로벌 서비스인 CloudFront나 Route53, ECR, S3 등은 Terraform을 이용해 관리하지 않고 수동으로 구축한 뒤 프로젝트가 끝나고 나서 삭제하였고, 기존에 수동으로 구축했던 VPC와 subnet, nat gateway, cli server 외에도 EKS cluster, Aurora DB, ElastiCache, VPC Endpoint와 필요한 보안 그룹, IAM 역할 등의 AWS 리소스들을 Terraform 코드에 추가하여 VPC와 VPC 내부 리소스 대부분을 Terraform을 이용해 관리할 수 있도록 하였습니다.
EKS 구축 방법
프로젝트에서 인프라 생성을 위해 사용했던 Terraform은 아래 Repository의 eks-managed-node-group 디렉토리 안의 tf 파일들 입니다.
GitHub - JinsuYeo/eks-build: eks-build
eks-build. Contribute to JinsuYeo/eks-build development by creating an account on GitHub.
github.com
1. 우선, 위의 Github Repository를 clone하고, aws cli가 없다면 설치한 뒤 aws configure를 설정합니다.
(참고: eks-managed-node-group, eks-init(eks fargate) 디렉토리의 terraform 파일만 정상적으로 실행됩니다. karpenter는 X)
2. 이후, remote 디렉토리의 s3.tf 파일의 bucket 이름을 원하는 이름으로 수정한 후, terraform apply하여 terraform state file을 저장할 s3 bucket과 state filte의 Lock을 설정하기 위한 DynamoDB를 생성합니다.
(또는 eks-managed-node-group 디렉토리의 backend.tf를 모두 주석처리)
3. eks-managed-node-group 디렉토리 안의 backend.tf 파일의 bucket을 위에서 생성한 bucket 이름으로 수정한 뒤, variable.tf의 설정을 본인의 리전과 profile로 수정합니다.
4. pwd가 eks-managed-node-group인 상태에서 terraform init과 terraform apply 명령을 실행합니다.
(EKS endpoint를 private으로 설정하고 싶다면 eks-al2023.tf 파일의 cluster_endpoint_public_access를 false로 수정)
생성되는 AWS 리소스
- 기본적인 설정이 모두 완료된(IGW, NAT Gateway, VPC Endpoint, Routing Table 등) VPC(10.0.0.0/16)와 Subnet(private 2개, public 2개, infra 2개 - 각각 /20, /24, /24의 서브넷 마스크를 가짐)
- SSM의 Session manager를 이용해 연결 가능한 cli server(private subnet에 생성됨, eksctl과 kubectl이 설치됨)
- 기본적인 설정이 모두 완료된(Node group, IRSA, CNI, alb-controller 등) EKS cluster
+ 만약 클러스터 생성에 실패한다면 cli server에 Session manager을 이용해 연결하여 eksctl을 사용해 생성하는 것이 편리함
Ex) cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: test-cluster
region: ap-northeast-2
vpc:
id: "{vpc-id}"
cidr: "10.0.0.0/16"
subnets:
private:
pri-01:
id: "{subnet-id}"
cidr: "10.0.0.0/20"
pri-02:
id: "{subnet-id}"
cidr: "10.0.16.0/20"
managedNodeGroups:
- name: test-nodegroup
instanceType: t3.medium
desiredCapacity: 2
iam:
withAddonPolicies:
autoScaler: true
externalDNS: true
certManager: true
ebs: true
efs: true
albIngress: true
cloudWatch:
clusterLogging: {}
eksctl create cluster -f cluster.yaml
5. EKS cluster 생성이 모두 완료되었다면, cli server에 Session Manager를 이용해 접속한 뒤 다음 설정을 완료해야 kubectl을 사용 가능해집니다.
(eks public endpoint가 허용된 경우에는 로컬의 터미널에서도 다음 설정을 완료하면 EKS에 kubectl 명령 실행이 가능하며, gossm 사용하면 AWS 웹 콘솔이 아닌 터미널을 이용해 Session Manager 사용 가능합니다.)
5-1. terraform을 띄운 설정과 동일하게 aws configure를 설정합니다.
5-2. aws eks --region {cluster-region} update-kubeconfig --name {cluster-name}
위 명령어를 수행하여 kubeconfig 파일을 cli server에 가져옵니다.
(cat ~/.kube/config을 통해 확인)
+ 추가로, clone한 디렉토리 중, k8s 디렉토리 안의 yaml 파일을 적절히 수정한 뒤
$ kubectl apply -f ./k8s
명령을 수행하여 클러스터에 Ingress, ClusterIP, Deployment, HPA 생성 가능합니다.
(HPA는 아래 추가 기능의 Metric Server 설치해야 실제 CPU나 Memory metric 기반으로 동작할 수 있습니다.)
추가 기능 설치 및 적용
K9s install:
curl -sS https://webinstall.dev/k9s | bash
Metric Server install:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
kiali install:
helm install \
--namespace istio-system \
--set auth.strategy="anonymous" \
--repo https://kiali.org/helm-charts \
kiali-server \
kiali-server
kubectl port-forward svc/kiali 20001:20001 -n istio-system
docker ngrinder install:
docker pull ngrinder/controller
docker run -d -v ~/ngrinder-controller:/opt/ngrinder-controller --name controller -p 80:80 -p 16001:16001 -p 12000-12009:12000-12009 ngrinder/controller
docker pull ngrinder/agent
docker run -d --name agent --link controller:controller ngrinder/agent
Keda install:
# install
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda -n keda --create-namespace
# delete
kubectl delete $(kubectl get scaledobjects.keda.sh,scaledjobs.keda.sh -A \
-o jsonpath='{"-n "}{.items[*].metadata.namespace}{" "}{.items[*].kind}{"/"}{.items[*].metadata.name}{"\n"}')
helm uninstall keda -n keda
Ex)
cat <<EOF> scaledObject.yaml
kind: ScaledObject
metadata:
name: keda-over-provioning
spec:
# min / max count
minReplicaCount: 0
maxReplicaCount: 10
# target
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: overprovision
triggers:
- type: cron
metadata:
timezone: Asia/Seoul
start: 45 * * * *
end: 50 * * * *
desiredReplicas: "5"
kubectl apply -f scaledObject.yaml
helm install:
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
node group autoscailing 정책 변경:
for NODEGROUP in $(aws eks list-nodegroups --cluster-name "${CLUSTER_NAME}" \
--query 'nodegroups' --output text); do aws eks update-nodegroup-config --cluster-name "${CLUSTER_NAME}" \
--nodegroup-name "${NODEGROUP}" --scaling-config "minSize=2,maxSize=4,desiredSize=2"; \
done
argocd:
ArgoCD 설치 및 설정
Terraform 이용한 EKS Cluster 구축CloudWave 프로젝트를 진행하며 EKS를 구축한 방법은 다음과 같습니다. GitHub - JinsuYeo/eks-build: eks-buildeks-build. Contribute to JinsuYeo/eks-build development by creating an account on GitHu
jsyeo.tistory.com
argo rollout:
Argo Rollouts 설치 및 활용
Argo Rollouts이란 Argo rollouts는 blue/green 배포와 canary 배포를 쉽게 구현할 수 있도록 도와주고 roll back을 쉽게 만들어주는, deployment의 확장 버전과 같은 역할을 하는 custom resource입니다. ReplicaSet과 Pod
jsyeo.tistory.com
karpenter:
Karpenter 활용하기
Karpenter란 Karpenter란, 쿠버네티스 클러스터에서 노드를 자동으로 프로비저닝하고 관리하기 위한 오픈 소스 도구입니다. 기존의 Cluster Autoscaler와는 다르게, Karpenter는 보다 유연하고 효율적인 노
jsyeo.tistory.com
회고
처음에는 실제 올리브영이 Fargate를 사용한다는 점과, 어떤 노드 타입을 사용할 지 고민하지 않아도 된다는 점을 고려하여 EKS Fargate를 사용하려 하였으나, Ingress 생성까지는 성공하였지만 ArgoCD 등의 오픈소스 도구들을 사용함에 있어서 추가 설정이 필요한 부분들이 있었고, Fargate 자체에 대한 이해가 부족한 점과 EKS Fargate에 오픈소스를 적용할 때의 트러블 슈팅 정보가 너무 적다는 점 때문에 오픈소스 도구들의 적용에 어려움이 있어 EKS Managed Node Group을 사용하는 것으로 변경하였습니다.
또한 노드의 오토 스케일링에 Karpenter를 사용하였지만, Karpenter를 사용하기로 결정한 것이 Terraform을 통해 안정적으로 동작하는 인프라를 구축하는 데 성공한 이후라는 점과, 따라서 Terraform을 이용해 Karpenter를 생성하기 위해 필요한 학습시간이 불필요하다고 생각한 점으로 인해 Terraform으로 EKS Managed Node Group을 생성한 후, 수동으로 ASG 대신 Karpenter를 사용하도록 변경하는 방법으로 EKS를 구축하였습니다.
이처럼 EKS Fargate나 Karpenter를 Terraform으로 구축하지 못한 점이 아쉽고 기회가 된다면 이 경험을 살려 EKS Fargate로 운영 환경을 구축해보고 싶습니다.
또한 메인 VPC 이외의 VPC에 서버를 생성하고, 해당 서버에서 cron을 이용해 Terraform 코드를 특정 시간에 apply, destroy 하여 시간에 맞춰 인프라를 자동 생성 및 삭제하는 기능을 추가하려 하였지만, 프로젝트 기간 내에 구현하지 못해 아쉽고 기회가 된다면 구상했던 시나리오가 실제로 동작이 가능한 지 테스트해보고 싶습니다.
'DevOps' 카테고리의 다른 글
Argo Rollouts 설치 및 활용 (0) | 2024.09.01 |
---|---|
ArgoCD 설치 및 설정 (1) | 2024.09.01 |
올리브영 온라인 쇼핑몰 public cloud(AWS) 인프라 구축 프로젝트 (3) | 2024.08.31 |
부하 테스트 및 조회 성능 개선(Ehcache, DB index) (0) | 2024.06.11 |
[ Jenkins ] Jenkins를 이용해 빌드/배포 자동화하기 (0) | 2024.02.15 |