클라우드 | 가상화/AWS

AWS + kubernetes 3tier 설정

mamdragors 2026. 4. 19. 17:50

 
참고)
https://aakibkhan1.medium.com/project-8-three-tier-application-deployment-on-kubernetes-bf9323de40e0

 

Project 8 → Three tier application deployment on Kubernetes

what do you mean by three tier ?

aakibkhan1.medium.com

 

Overview

3계층(3-Tier)

  • 프레젠테이션 계층 (Frontend): 사용자가 직접 보는 화면 (React 등).
  • 애플리케이션 계층 (Backend): 비즈니스 로직을 처리하는 서버 (Node.js 등).
  • 데이터 계층 (Database): 데이터를 저장하는 공간 (MongoDB).

인프라 구성 (EC2 & IAM)

  • 작업용 EC2 생성: 실습 명령어를 실행할 관리용 EC2 인스턴스를 생성
  • IAM 사용자 설정: AWS CLI 접근을 위해 AdministratorAccess 권한을 가진 IAM 사용자를 생성, Access Key를 발급
  • 필수 도구 설치: EC2 환경에 Docker, AWS CLI, kubectl, eksctl을 설치

도커 이미지 빌드 및 ECR 업로드

  • 이미지 생성: 제공된 GitHub 리포지토리를 클론하여 프론트엔드와 백엔드 각각의 Dockerfile을 빌드합니다.
  • ECR(Amazon Elastic Container Registry) 저장: 빌드한 이미지를 AWS의 컨테이너 저장소(ECR)에 푸시(Push)하여 Kubernetes가 가져갈 수 있게 합니다.

Kubernetes 리소스 배포 (Manifest) 준비된 YAML 파일들을 사용하여 각 계층을 배포

  • Database (MongoDB): 데이터를 보존하기 위해 Persistent Volume(PV)과 PVC를 설정한 후 배포
  • Backend: ECR에 올린 백엔드 이미지를 사용해 배포하고, 내부 통신용 Service 생성
  • Frontend: 프론트엔드 이미지를 배포하고 외부에서 접속할 수 있도록 설정

접근 및 로드밸런싱 Ingress 또는 LoadBalancer: 외부 사용자가 브라우저를 통해 접속할 수 있도록 서비스의 타입을 설정하거나 Ingress 컨트롤러를 구성하여 트래픽을 전달


 
1. Git Repository 생성
2. AWS 에 IAM 사용자 와 인스턴스 생성
    - IAM 사용자 생성 및 권한 설정
    - 인스턴스 생성
3. EC2 인스턴스에 필수 도구 설치
    - SSH Key 등록
    - git 소스 clone
    - AWS CLI 설치, 설정
    - 도커 설치
    - kubectl 설치
    - eksctl 설치
4. Docker 이미지 빌드
    - aws 에 docker 저장소 생성 (frontend, backend 용)
5. 쿠버네티스 설정
    - EKS 클러스터 설정 및 네임스페이스 생성
    - deploy, service 생성 (front, back, db)
    - 애플리케이션 로드 밸런싱 및 인그레스 설정


1. Git Repository 생성

나중에 소스에 변형을 가할 생각이기 때문에 참고 url 의 소스를 내려받아 새로운 레파지토리에서 작업한다.

 
별도의 개발환경 없이 github codespace 를 사용할것이다.
레포지토리 생성화면에서 [create a codespace] 클릭

또는 시작 화면을 지나쳤다면 레포지토리 의 Code 탭에서 코드스페이스를 생성할수도 있다.

 
codespace 화면은 웹에서 실행되는 vscode 라고 생각하면 된다.
터미널에서 아래 명령어 실행

cd ..
git clone --depth 1 https://github.com/Aakibgithuber/Three-tier-Application-Deployment-.git
cd Three-tier-Application-Deployment-/

 

코드 스페이스 말고 다른창에서 생성한 레포지토리에 들어가서 레포지토리 주소를 획득한다.

 
주소를 획득했으면 다시 코드스페이스에서 아래 실행

# .git 폴더를 삭제하여 이전 기록과의 연결을 완전히 끊습니다.
rm -rf .git

# git 초기화
git init
git add .
git commit -m "Initial commit (without history)"

# 생성한  repository 에 연결
git remote add origin [카피한-저장소-URL]

# 브랜치 이름을 main(또는 master)으로 설정 후 푸시
git branch -M main
git push -u origin main --force

 
저장소 페이지를 새로고침 하면 소스가 올라간 것을 확인할 수 있다.

다른곳에서 clone 가능하도록 git token 생성

 


2. AWS 에 IAM 사용자 와 인스턴스 생성

 
사용자 권한
 
AdministratorAccess
AWSLoadBalancerControllerIAMPolicy

 
- VPC 생성 : 3T-TEST-VPC
CIDR : 10.10.0.0/16
- Subnet 생성 : 3T-TEST-SUBNET-2A
resion : ap-northeast-2a
CIDR : 10.10.10.0/24
- Routing 테이블 생성 : 3T-TEST-RT
- Internet Gateway 생성 : 3T-TEST-IGW
- Routing 테이블 편집, 연결
- 보안 그룹 만들기 : 3T-TEST-SG-2A
인바운드 규칙 : SSH, HTTP, HTTPS, ICMP
아웃바운드 규칙 : HTTPS, SSH
- 인스턴스 생성 : 3T-TEST-INSTANCE
ubuntu22.04, 8g
기본 ip : 10.10.10.250

 
인스턴스 생성 참고
https://mamdragors.tistory.com/25

 

AWS - 2. VPC생성하여 쉘접속

아래 작업을 진행할 것이다. 1. 도메인생성 (가비아)2. 도메인 등록 (AWS Route 53)3. 도메인과 연결할 인증서 생성 (AWS Certificate Manager)4. VPC 생성 - VPC 생성 - Subnet 생성 - Routing 테이블 생성 - Internet Gatew

mamdragors.tistory.com


3. EC2 인스턴스에 필수 도구 설치

만들어진 인스턴스의 public ip 로 ssh접속.
putty 를 사용할 경우 pem 파일을 사용할 수 없기 때문에
컨테이너 생성시 설정한 키파일의 pem 파일을
puttyGen 으로 ppk 파일로 변경하어 접속한다.

접속 성공

 
 
접속은 AWS 클라우드 쉘에서 진행해도 된다
aws 웹페이지의 좌측 하단 [CloudShell]  > [작업] > 파일업로드

3tier-user 의 pem 파일 업로드

chmod 400 3tier.pem
ssh -i 3tier.pem ubuntu@[퍼블릭ip]

접속 성공

 
 
터미널에서 아래 명령어 실행

sudo su
apt update
mkdir 3-tier
cd 3-tier

 

SSH Key 등록

# SSH 키 생성 (로컬 터미널) . 
ssh-keygen -t ed25519 -C "내이메일@example.com"

# 공개키 복사:
cat ~/.ssh/id_ed25519.pub
# 출력된 ssh-ed25519 ... 로 시작하는 긴 문자열을 복사

 
 
복사한 문자열 GitHub에 등록

 
github 는 22 포트를 허용하지 않기 때문에 SSH 포트를 443으로 우회 설정 해야 한다.

vi ~/.ssh/config

# 아래내용 저장
Host github.com
    Hostname ssh.github.com
    Port 443
    User git


# 접속 테스트
ssh -T git@github.com
# Hi [사용자명] ... 출력되면 성공

git 레포지토리에서 ssh 주소 획득

SSH 주소로 Clone

cd 3-tier
git clone [ssh 주소]

내려받은 소스 확인

 
 

AWS CLI 설치

snap install aws-cli --classic

 

AWS CLI 설정

aws configure
[3tier-user 의 엑세스키]
[3tier-user 의 비밀엑세스키]

 

도커 설치

# universe 리포지토리 활성화
add-apt-repository universe
# 패키지 리스트 갱신
apt update

# 필수 도구 설치
apt install ca-certificates curl gnupg -y

# Docker GPG 키 등록
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg --yes
chmod a+r /etc/apt/keyrings/docker.gpg

# 리포지토리 설정 (22.04 jammy 전용)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu jammy stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

# 최종 설치
apt update
apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

#상태 확인
systemctl status docker

# 현재 접속중인 사용자 docker 그룹에 추가. root 로 진행하고 있기 때문에 root 사용자가 추가됨
# 다른 사용자로 진행하려면 $USER 대신 사용자 이름을 입력한다.
usermod -aG docker $USER # Replace with your username e.g ‘ubuntu’

#그룹 변경사항 즉시 적용
newgrp docker

# Docker의 핵심 통신 통로인 '소켓 파일'의 권한 변경 
sudo chmod 660 /var/run/docker.sock

# 명령어 확인
which docker
docker ps

 

kubectl 설치

snap install kubectl --classic

 

eksctl 설치

curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp

sudo mv /tmp/eksctl /usr/local/bin
eksctl version

4. Docker 이미지 빌드

Elastic Container Registry(ECR) 설정

AWS 콘솔에 접속하여 ECR을 검색

 
프런트엔드용 저장소 생성 

백엔드용 저장소 생성

frontend 레포지토리 이름을 클릭하고 들어가서 [푸시 명령보기] 에서 나오는 명령어 복사하여 실행

복사한 명령어 인스턴스에 접속한 쉘에서 실행
!! frontend 폴더에서 실행한다.

 
올라간 이미지 확인

 
이미지를 실행해 본다
 

docker run -d -p 3000:3000 3tier-test/frontend:latest

 
인바운드 규칙에서 3000 포트가 허용되어 있는지 확인

웹 브라우저에서 접속 테스트  -> http://[퍼블릭ip]:3000 

 
 
backend 레포지토리 이름을 클릭하고 들어가서 [푸시 명령보기] 에서 나오는 명령어 복사하여 실행

 
!! backend 폴더에서 실행한다

 


5. 쿠버네티스 설정

1. 배포란 무엇인가:

  • 공장을 상상해 보세요 : 배포를 소프트웨어 애플리케이션의 복사본을 생산하고 관리하는 공장으로 생각해 보십시오.
  • 다중 복제본 : 공장에서 여러 개의 동일한 제품을 생산할 수 있는 것처럼, Kubernetes 배포 환경에서도 애플리케이션의 여러 복사본(복제본)을 생성하고 관리할 수 있습니다.
  • 간편한 업데이트 : 애플리케이션을 변경하거나 업데이트하려는 경우, 배포 시스템이 마치 공장에서 생산을 중단하지 않고 부품을 교체하는 것처럼 원활하게 처리할 수 있습니다.

2. 서비스란 무엇인가:

  • 리셉션 데스크를 상상해 보세요: 쿠버네티스의 서비스를 건물의 리셉션 데스크에 비유해 보세요.
  • 중앙 접점: 이 서비스는 애플리케이션을 위한 중앙 접점을 제공합니다. 시스템의 다른 부분들이 각 애플리케이션을 직접 찾는 대신, 이 서비스와 통신하여 필요한 애플리케이션을 찾을 수 있습니다.
  • 안정적인 주소: 마치 안내 데스크에 일관된 주소가 있는 것처럼, 서비스도 시스템의 다른 부분이 애플리케이션과 통신하는 데 사용할 수 있는 안정적인 주소를 가지고 있습니다.

3. 네임스페이스란 무엇인가요?

  1. 네임스페이스는 쿠버네티스 내에서 애플리케이션을 구성하고 실행할 수 있는 레이블이 지정된 영역과 같습니다. 각 네임스페이스는 애플리케이션이 서로 간섭하지 않고 각자의 작업을 수행할 수 있는 울타리로 둘러싸인 공간입니다.
  2. 간단히 말해, 쿠버네티스에서 네임스페이스는 여러 프로젝트나 애플리케이션을 분리하고 체계적으로 관리하는 방법으로, 복잡한 쿠버네티스 클러스터 환경에서 이러한 프로젝트와 애플리케이션을 더 쉽게 관리할 수 있도록 해줍니다

 
 

5-1. EKS 클러스터 설정 및 네임스페이스 생성

EKS(Elastic Kubernetes Service)는 "AWS가 대신 관리해 주는 쿠버네티스(Kubernetes) 서비스"

# 1. 클러스터 생성 (서울 리전, t3.small , 워커노드 최소2개, 최대2개). 15~20분 소요
eksctl create cluster --name 3tier-cluster --region ap-northeast-2 --node-type t3.small --nodes-min 2 --nodes-max 2

클러스터 생성 명령어 실행하고 CloudFormation 화면에 들어가면 진행 상황을 볼수 있다.

 
스택 세부정보에서 이벤트도 확인 가능

 

nodegroup 과 cluster 가  CREATE_COMPLETE 되면 다음 진행

더보기

각 스택의 의미

 

1. 첫 번째 스택: 컨트롤 플레인 (Control Plane)

  • 이름 형식: eksctl-3tier-cluster-cluster
  • 역할: EKS 클러스터의 핵심인 두뇌(Control Plane) 역할을 하는 인프라를 생성합니다.
  • 포함 리소스: VPC, 서브넷(Public/Private), 인터넷 게이트웨이, 라우팅 테이블, IAM 역할, 보안 그룹 등 네트워크 전반의 기초 공사가 이 단계에서 이루어집니다.

2. 두 번째 스택: 노드 그룹 (Node Group)

  • 이름 형식: eksctl-3tier-cluster-nodegroup-[이름]
  • 역할: 실제로 애플리케이션이 돌아갈 몸통(Worker Nodes) 인프라를 생성합니다.
  • 포함 리소스: EC2 인스턴스(t3.small 2대), 오토스케일링 그룹(ASG), 노드 전용 IAM 역할 및 보안 그룹 등이 포함됩니다.
# 2. 접속 설정(kubeconfig) 업데이트
# 클러스터가 만들어진 후, 내 컴퓨터(또는 현재 서버)에서 kubectl 명령어로 클러스터를 조종할 수 있게 **인증 정보(kubeconfig)**를 가져오는 명령. 
# 이 명령을 실행하면 ~/.ssh/config와 유사하게 ~/.kube/config 파일에 해당 클러스터의 접속 정보가 등록됨
aws eks update-kubeconfig --region ap-northeast-2 --name 3tier-cluster

# 3. 노드 상태 확인
kubectl get nodes

# 4. 네임스페이스 생성 및 변경 ( 3tier-test )
kubectl create namespace 3tier-test
kubectl config set-context --current --namespace 3tier-test

 
k8s_manifests/frontend-deployment.yaml 파일의 이미지 경로와 namespace 수정
k8s_manifests/frontend-service.yaml 파일의 namespace 수정

변경 후 apply 명령 실행

kubectl apply -f frontend-deployment.yaml
kubectl apply -f frontend-service.yaml

 
backend-deployment.yaml, backend-service.yaml 파일의 이미지 경로와 workspace 수정

 
백엔드도 apply

kubectl apply -f backend-deployment.yaml
kubectl apply -f backend-service.yaml
kubectl get pods -n 3tier-test

 
DB apply 후 전체 확인
!! 실행 전 mongo 폴더의 모든 yaml 파일의 워크스페이스 수정

cd mongo

# 실행 전 mongo 폴더의 모든 yaml 파일의 워크스페이스 수정
kubectl apply -f .

kubectl get all

 
pod 3개 생성 확인 ( frontend, backend, db )

 
 

5-2. 애플리케이션 로드 밸런싱 및 인그레스 설정

외부 트래픽을 클러스터로 라우팅하기 위한 애플리케이션 로드 밸런서와 3개 계층 간의 내부 라우팅을 위한 인그레스를 생성.
 
ALB의 IAM 정책 가져오기

curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.7.2/docs/install/iam_policy.json

 
 iam_policy.json 파일을 기반으로 AWS 계정에 IAM 정책을 생성

aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://iam_policy.json

 
OIDC 제공업체 연결

eksctl utils associate-iam-oidc-provider --region=ap-northeast-2 --cluster=3tier-cluster --approve
더보기

AWS Load Balancer Controller는 클러스터 외부의 **AWS 리소스(ALB/NLB)**를 직접 생성하고 수정해야 합니다.

  1. 쿠버네티스 안의 **서비스 계정(Service Account)**이
  2. IAM Role을 사용할 수 있게 권한을 부여받아야 하는데,
  3. 이 두 세계(K8s와 AWS IAM)를 이어주는 인증 표준이 바로 OIDC입니다.

 
로드 밸런서 정책을 EKS 클러스터에 적용하여 EKS 클러스터가 해당 정책에 따라 로드 밸런서와 연동되도록 설정

eksctl create iamserviceaccount --cluster=3tier-cluster --namespace=kube-system --name=aws-load-balancer-controller --role-name AmazonEKSLoadBalancerControllerRole --attach-policy-arn=[위명령어실행시 출력된Arn] --approve --region=ap-northeast-2

 
로드 밸런서 배포를 위한 HELM 설정

# Helm을 설치 (Kebernetes 배포관리도구)
sudo snap install helm --classic

# AWS(Amazon Web Services)에서 공식적으로 운영하는 GitHub 기반의 Helm 차트 저장소에서 
# 로드 밸런싱용 특정 매니페스트를 Helm을 사용하여 추가
helm repo add eks https://aws.github.io/eks-charts

# Helm을 사용하여 eks 저장소를 업데이트
helm repo update eks

# EKS 클러스터에 로드 밸런싱 컨트롤러를 설치
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=3tier-cluster --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller 
kubectl get deployment -n kube-system aws-load-balancer-controller

 
내부 라우팅을 위한 인그레스 설정

# full_stack_lb.yaml namespace 수정
vi full_stack_lb.yaml

kubectl apply -f full_stack_lb.yaml 
kubectl get ing -n 3tier-test

 
ADDRESS  주소가 나오지 않는다면 권한을 확인해 본다

# AWSLoadBalancerControllerIAMPolicy 에 항목 추가
"elasticloadbalancing:DescribeListenerAttributes"

 
권한 추가 후 서비스 재시작

kubectl rollout restart deployment aws-load-balancer-controller -n kube-system

 
5분정도 기다렸다가 상태확인

kubectl describe ingress mainlb

# 아래 내용이 출력되면 성공
#   Normal   SuccessfullyReconciled  2m55s                  ingress  Successfully reconciled

# get 으로 주소가 들어왔는지 확인
kubectl get ing

 
주소가 나오면 해당 주소로 웹브라우저에서 접속 확인

 


확인이 끝났으면 전부 제거한다.

# /home/ubuntu/3-tier/3tier-test/k8s_manifests/ 경로에서 진행
kubectl delete -f .

# /home/ubuntu/3-tier/3tier-test/k8s_manifests/mongo 경로에서 진행
kubectl delete -f .

# 네임스페이스의 모든 리소스 삭제
kubectl delete all --all -n 3tier-test

# 클러스터를 삭제하기 전에 반드시 아래 명령어를 먼저 실행
kubectl delete svc --all -n 3tier-test
kubectl delete ingress --all -n 3tier-test

# 클라우드포메이션의 클러스터와 스택을 삭제(15분 정도 소요)
eksctl delete cluster --name 3tier-cluster --region ap-northeast-2

aws cloudformation delete-stack --stack-name eksctl-3tier-cluster-cluster --region ap-northeast-2

 
 
AWS 클라우드포메이션 콘솔에서 모든 변경 사항을 확인

 
DataZone 같은게 남아있다면 삭제한다. 날짜를보니 다른작업 하면서 만들어진듯

# 첫 번째 스택 삭제
aws cloudformation delete-stack --stack-name [첫번째-전체-스택이름] --region ap-northeast-2

# 두 번째 스택 삭제
aws cloudformation delete-stack --stack-name [두번째-전체-스택이름] --region ap-northeast-2

 

전부 삭제되었으면 인스턴스를 중지한다.