실습용 환경 설정
오늘은 3-tier(front,back,db) app을 클라우드에 배포하는 것이 목표이다. 오늘의 실습을 위해 강사님께서 카카오클라우드 클러스터를 만들어주셨다. 하나의 클러스터 안에서 리소스가 논리적으로 격리된 공간을 네임스페이스라고 부른다. 나는 그 클러스터 안에 나의 네임스페이스를 만들고 작업할 필요가 있다.
💡 쉽게 비유하면?
| 개념 | 비유 |
| 클러스터 | 아파트 단지 전체 |
| 네임스페이스 | 각 동(건물) |
| Pod/Service 등 | 각 세대의 집들 |
카카오클라우드에 만들어진 클러스터에 접속하고, 나만의 작업공간인 네임스페이스를 만들어보자.
1. kubeconfig-sfacspace.yaml 파일 바탕화면에 배치
# kubeconfig-sfacspace.yaml
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM2akNDQWRLZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJMU1EUXdPVEV4TVRneE5Gb1hEVE0xTURRd056RXhNak14TkZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBS0VPCjZ1RmdULzU2VU1YSlR1cGsrcDNYL1A5ZHNjQjExTm4zdkd5b28xTmRuSXZHNkxtVzJGRWFIZi9BYk5Ya1FzcWkKbHorM2xWQnhDMHRjczVVc0xERXRhMEw5SzFRTzFqQ3VlZEJIS1lkVGFiWmkyMzlVRGNBZVNkazlsUGsvcm5CMQpIZjhqYUV6UEFlSEFuVkZHeXZETFM5RlgvcGJBK1I2ajhma0N2aWNJdHZUV3ppajY1VDVtK0FEWi91RWlyWi9SCkQ1emY2QWF6SXR6dGYxcHVVOHJVeFVPMmo5U2ZFekxrY2NmMW1GQ3I4M1dveGFpTEkzaFFRYXlzY2JKL3paemIKRkhGd1F5UFNwY0YyeW1DVExMd1J1cUZtdi8vSXNWT2RBZ2VnT1VMeTg0VHlqakk0bnIvMkFmOHdORlE5U0RiYQpma2RFNlg4d1lLMXltb1RPOVg4Q0F3RUFBYU5GTUVNd0RnWURWUjBQQVFIL0JBUURBZ0trTUJJR0ExVWRFd0VCCi93UUlNQVlCQWY4Q0FRQXdIUVlEVlIwT0JCWUVGQlpvM2ZVMGtEQlYyYm9lTWw1WmpEdUs4RC9rTUEwR0NTcUcKU0liM0RRRUJDd1VBQTRJQkFRQnlZZHZiKzZHeTU2aDdXQ2ZWVEN2bXJsdTNiUCtSbU1NbXdESFc3anNVSCtHSgppSWJHeGVSZGdZOHVseHB4UU0rWlY4aW15cnhrMUN4UUJaVG83MlF1K3dGZWZPaU9meVBNN0IvU1k4SytqWmlRClJYYW9uVXAxZS95RkFXbDVqYi91WFBwejV2YTBLOWFVMVJ2RUdKa3Y3WlBSUWtudG1xL0ZSTUNxWU5kK0lEYjQKeDBzMWtqTU8wZWJnQWM3enF2czJFZmZUa2FQcnVoaUpSbm0rN3hPV2dUaDNNNjhQOWxsTG5UVGVCRTRhUnJ3dwpEczNUT3RUVFRQdVF2R0IrQlRSY0ZMNG11NkJ2cStDL0oxM1IyMW9URG84endzb3J0L0M4UlY0T1ZHdmpWcjF5CmptZTdlQ0g3MVpRV2xtL2dFbDVFTG0zbU05WkY3MTh1cXJMVXF1c3IKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
server: https://58d6c44b-be0b-4635-9e76-700a077a5f06-public.ke.kr-central-2.kakaocloud.com
name: sfacspace
contexts:
- context:
cluster: sfacspace
user: sfacspace-admin
name: sfacspace-admin@sfacspace
current-context: sfacspace-admin@sfacspace
kind: Config
preferences: {}
users:
- name: sfacspace-admin
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args: null
command: kic-iam-auth
env:
- name: "OS_AUTH_URL"
value: "https://iam.kakaocloud.com/identity/v3"
- name: "OS_AUTH_TYPE"
value: "v3applicationcredential"
- name: "OS_APPLICATION_CREDENTIAL_ID"
value: "fd9f2ff1df4c449a99797dc7e873f770"
- name: "OS_APPLICATION_CREDENTIAL_SECRET"
value: "955cb9b203f07a03b28612b1e823349328ed8fdb8bcc4dcc22a16376d239c4da43aabf"
- name: "OS_REGION_NAME"
value: "kr-central-2"
2. 본인 환경에 맞는 카카오클라우드 인증 클라이언트(kic-iam-auth)를 다운로드 (가이드라인 URL 참조)
가이드라인: https://docs.kakaocloud.com/service/container-pack/k8se/how-to-guides/k8se-kubectl
kubectl 제어 설정 | 카카오클라우드
Kubernetes 커맨드 라인 도구인 kubectl의 설치 및 제어 방법을 설명합니다.
docs.kakaocloud.com
3. 다음 커맨드를 입력하여 kubectl 연결 및 네임스페이스 만들기
# 1. 명령 프롬프트(cmd)를 관리자 권한으로 실행합니다.
# 2. 바탕화면으로 이동합니다:
cd %USERPROFILE%\Desktop
# 3. 현재 경로 확인:
echo %CD%
# 4. 경로에 kic-iam-auth 추가:
set PATH=%PATH%;%CD%
# 5. kubeconfig 파일 경로 설정:
set KUBECONFIG=%CD%\kubeconfig-sfacspace.yaml
# 6. 설정이 제대로 적용되었는지 확인:
echo %PATH%
echo %KUBECONFIG%
# 7. kubectl 명령 테스트:
kubectl --kubeconfig=%KUBECONFIG% get nodes
# 8. alias로 저장해두기 (Windows PowerShell은 doskey 이용)
doskey k=kubectl --kubeconfig=%KUBECONFIG% get nodes
# alias로 kubectl 혹은 k로 간단하게 지정해서 `kubectl --kubeconfig=%KUBE_CONFIG`가 불러와지도록!
# 10. 본인의 작업 네임스페이스 만들기
kubectl create namespace ${본인 이니셜}
# ex) kubectl create namespace kdj
# 참고) namespace 목록 출력하는 법
# kubectl --kubeconfig=%KUBECONFIG% get namespaces
# 참고) 현재 컨텍스트 확인하는 법 (minikube인가 kakao cloud인가)
# kubectl config current-context

실습 1: 3-Tier 아키텍처 애플리케이션 실습 가이드
0. 샘플 3-Tier 애플리케이션 구조
이 샘플 애플리케이션은 다음 세 가지 계층으로 구성됩니다:
- 프론트엔드 (React) - 사용자 인터페이스 제공
- 백엔드 (Express.js) - 비즈니스 로직 및 API 제공
- 데이터베이스 (MySQL) - 데이터 저장
1. 기본 파일 작성 및 로컬에서 구동 테스트
1-1. Docker Compose 실행
docker-compose up -d
1-2. 로그 확인
각 컨테이너의 로그를 확인하여 서비스가 제대로 시작되었는지 확인
# 모든 로그 확인
docker-compose logs -f
# 특정 서비스 로그 확인
docker-compose logs -f db
docker-compose logs -f backend
docker-compose logs -f frontend
1-3. 애플리케이션 접속
브라우저에서 다음 URL로 접속:
- 프론트엔드: http://localhost
- 백엔드 API: http://localhost:3000/api/users
- 백엔드 상태 확인: http://localhost:3000/health



1-4. 데이터베이스 확인
MySQL 클라이언트를 사용하여 데이터베이스에 접속하고 초기 데이터가 제대로 생성되었는지 확인
docker exec -it 3tier-db mysql -u appuser -papppassword myapp -e "SELECT * FROM users;"

1-5. API 테스트(필요시)
로컬 웹에서 프론트를 통해 데이터베이스가 보이고 기능 이 작동하면 제대로 동작하는것임!
curl 또는 Postman을 사용하여 백엔드 API를 테스트합니다:
# 모든 사용자 조회
curl http://localhost:3000/api/users
# 새 사용자 추가 Windows
Set-Content -Encoding ascii body.json '{"username":"testuser","email":"test@example.com"}'
curl.exe -X POST http://localhost:3000/api/users -H "Content-Type: application/json" --data "@body.json"
# 새 사용자 추가 Mac
# curl -X POST http://localhost:3000/api/users \
# -H "Content-Type: application/json" \
# -d '{"username":"testuser","email":"test@example.com"}'
# 특정 사용자 조회
curl http://localhost:3000/api/users/1
# 사용자 삭제 Windows
curl.exe -X DELETE http://localhost:3000/api/users/1
# 사용자 삭제 Mac
# curl -X DELETE http://localhost:3000/api/users/1

1-6. 변경 사항 테스트
ex) 프론트엔드 코드를 수정한 경우 다시 빌드하는 방법
docker-compose up -d --build frontend
1-7. 정리
테스트가 완료되면 컨테이너를 중지하고 삭제
# 컨테이너 중지 (데이터 유지)
# docker-compose up -d 하면 추가했던 유저가 남아있음
docker-compose down
# 컨테이너 중지 및 볼륨 삭제 (모든 데이터 삭제)
# docker-compose up -d 하면 추가했던 유저가 남아있지 않음
docker-compose down -v
2. Docker 이미지 빌드 및 Docker Hub에 푸시
애플리케이션의 각 계층(frontend, backend, database)을 컨테이너화하고 Docker Hub에 Push
- your-dockerhub-username : 자신의 Docker Hub 사용자명
# Docker Hub 로그인
docker login
# 프론트엔드 이미지 빌드 및 푸시
cd frontend
docker build -t ${your-dockerhub-username}/3tier-frontend:latest .
docker push ${your-dockerhub-username}/3tier-frontend:latest
# 백엔드 이미지 빌드 및 푸시
cd ../backend
docker build -t ${your-dockerhub-username}/3tier-backend:latest .
docker push ${your-dockerhub-username}/3tier-backend:latest
# 데이터베이스 이미지 빌드 및 푸시 (선택 사항)
cd ../database
docker build -t ${your-dockerhub-username}/3tier-database:latest .
docker push ${your-dockerhub-username}/3tier-database:latest

3. 쿠버네티스 배포
3-1. 메니페스트 파일 작성
쿠버네티스 클러스터에 배포할 리소스들(Pod, Service, HPA 등)의 설정 파일(YAML)들을 작성하자.
이미지 이름(tierr/3tier-backend etc.) 등은 자신의 환경에 맞게 알아서 바꿔야 한다.
- backend.yaml
# 5. 백엔드용 ConfigMap, Secret
---
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-config
data:
NODE_ENV: "production"
PORT: "3000"
DB_HOST: "mysql"
DB_PORT: "3306"
DB_NAME: "myapp"
DB_USER: "appuser"
LOG_LEVEL: "info"
---
apiVersion: v1
kind: Secret
metadata:
name: backend-secret
type: Opaque
stringData:
DB_PASSWORD: "apppassword"
# 6. 백엔드용 Deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: tierr/3tier-backend:latest
ports:
- containerPort: 3000
envFrom:
- configMapRef:
name: backend-config
- secretRef:
name: backend-secret
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 15
periodSeconds: 20
# 7. 백엔드용 Service
---
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
selector:
app: backend
ports:
- port: 3000
targetPort: 3000
type: ClusterIP
# 8. 백엔드용 HPA
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: backend-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: backend
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- database.yaml
# DB 배포 (StatefulSet)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: mysql
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: tierr/3tier-database:latest
ports:
- containerPort: 3306
name: mysql
envFrom:
- secretRef:
name: mysql-secret
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
readinessProbe:
exec:
command: ["mysqladmin", "ping", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 5
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "csi-cinder-sc-delete" # Explicitly specify the storage class
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
stringData:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: myapp
MYSQL_USER: appuser
MYSQL_PASSWORD: apppassword
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
selector:
app: mysql
ports:
- port: 3306
targetPort: 3306
clusterIP: None # Headless Service
- frontend.yaml
# 9.프론트엔드용 Deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: tierr/3tier-frontend:latest
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 300m
memory: 256Mi
readinessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 20
# 10. 프론트엔드용 Service
---
apiVersion: v1
kind: Service
metadata:
name: frontend
annotations:
service.beta.kubernetes.io/openstack-internal-load-balancer: 'true'
loadbalancer.ke.kakaocloud.com/load-balancer-type: 'ALB'
spec:
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 80
type: LoadBalancer
---
# 11. 프론트엔드용 HPA
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: frontend-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: frontend
minReplicas: 2
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
3-2. 쿠버네티스에 배포
쿠버네티스에 배포하고 카카오클라우드 콘솔에서 퍼블릭 IP를 할당한 뒤, 접속해서 테스트해보기
- your-namespace : 클러스터에 생성한 자신의 네임스페이스
# 데이터베이스 배포
kubectl apply -f k8s-manifests/database.yaml -n ${your-namespace}
# 데이터베이스가 준비되었는지 체크
kubectl get pods -n ${your-namespace} -l app=mysql -w
# 백엔드 배포
kubectl apply -f k8s-manifests/backend.yaml -n ${your-namespace}
# 프론트엔드 배포
kubectl apply -f k8s-manifests/frontend.yaml -n ${your-namespace}

3-3. 데이터베이스 연결 테스트
# Mac
# kubectl run mysql-client --rm -it --image=mysql:8.0 --restart=Never -n your-namespace -- \
# mysql -h mysql -u appuser -papppassword -e "SELECT * FROM myapp.users;"
# Windows
# 데이터베이스 확인을 위해 1회성 MySQL 클라이언트 Pod 생성
kubectl run mysql-client --rm -it --image=mysql:8.0 --restart=Never -n ${your-namespace} -- mysql -h mysql -u appuser -papppassword -e "SELECT * FROM myapp.users;"
3-4. 포트 포워딩을 통한 로컬 접속
브라우저에서 http://localhost:8080으로 접속합니다.
- your-namespace : 클러스터에 생성한 자신의 네임스페이스
kubectl port-forward svc/frontend 8080:80 -n ${your-namespace}
# 예제
kubectl port-forward svc/backend 3000:3000 &
kubectl port-forward svc/frontend 8080:80 &
kubectl port-forward svc/mysql 3306:3306 &


실습2: Kakao Cloud Container Registry의 이미지 저장소(Repository) 이용하기
1. Repository에 이미지 저장하기
우측 메뉴에서 [Container Pack > Container Registry] 탭에서 '리포지토리 생성' 버튼을 눌러서 리포지토리를 생성 가능하다.

외부에서 레포지토리에 접속하려면 IAM 액세스 키가 필요하다.
[우측 상단 프로필 클릭 > 자격 증명] 을 누르면 계정 설정 페이지로 올 수 있다. 여기서 IAM 액세스 키를 생성할 수 있다.

[IAM 액세스 키 생성] 버튼을 눌러서 키를 생성할 수 있다.
단, 만들고 나면 IAM 액세스 키 Id와 Password를 알려주는데, 어디다 기록해두고 잘 보관해야 하므로 주의해야 한다.

■ 이미지 build & tag
docker build -t ${image-name}:${tag} .
docker tag ${image-name}:${tag} ${project-name}.kr-central-2.kcr.dev/${repository-name}/${image-name}:${tag}
■ 로그인 (Windos CMD)
docker login ${project-name}.kr-central-2.kcr.dev ^
--username ${IAM-Access-Key-ID} ^
--password ${IAM-Access-Key-PW}
■ 이미지 push
docker push ${project-name}.kr-central-2.kcr.dev/${repository-name}/${image-name}:${tag}
Container Registry 에서 테스트용으로 만든 리포지토리(tutorial-yji)에 들어가보면, 내가 push한 이미지들을 확인할 수 있다.

2. Repository에 저장된 이미지 사용하기
로컬 환경에서 테스트할때는 실제 코드 파일을 빌드해서 실행시켰다.하지만 이번에는 레포지터리에 있는 이미지를 pull 받아서 실행시킬 것이기 때문에 docker-compose.yml 파일을 이미지를 이용하게끔 수정해야 한다.

이제는 이미지를 이용하기 때문에 새로운 폴더에 docker-compose.yml 파일만 있어도 컨테이너를 실행할 수 있다.
# 테스트를 위해 기존 이미지 삭제 (Docker Desktop 에서 직접 삭제해도 된다)
docker rmi 이미지이름:태그
# KC Repository로부터 이미지 Pull
docker pull ${project-name}.kr-central-2.kcr.dev/${repository-name}/{image-name}:${tag}
# docker compose 실행
docker-compose up -d
본 후기는 [카카오엔터프라이즈x스나이퍼팩토리] 카카오클라우드로 배우는 AIaaS 마스터 클래스 (B-log) 리뷰로 작성 되었습니다.
'학습일지 > K-Digital Traing' 카테고리의 다른 글
| [KDT] AIaaS 마스터클래스 4주차 - Database와 ERD 작성 과제 (0) | 2025.04.17 |
|---|---|
| [KDT] AIaaS 마스터클래스 3주차 - Prometheus & Grafana 모니터링 실습 (0) | 2025.04.11 |
| [KDT] AIaaS 마스터클래스 3주차 - 쿠버네티스 실습 (0) | 2025.04.09 |
| [KDT] AIaaS 마스터클래스 2주차 - 3 Tier Application 배포 실습 (0) | 2025.04.04 |
| [KDT] AIaaS 마스터클래스 2주차 - VM 배포 실습 (0) | 2025.04.03 |