
관리대장) T2 :



7615e61e-682b-4611-a566-562be5649dcb (newvpc_1)

서브넷 생성 규칙: VPC의 CIDR는 10.0.0.0/16이다.
따라서 C클래스를 16씩 증가하며 네트워크를 격리 시켰다.
서브넷내의 넷마스크는 20으로 약 4000개 이상의 ip를 할당받을수 있게 설정되어있다.
Nginx Web Server
DB

FastAPI

66038f94-7222-4a61-bba5-3ba4f6e928c8 (newvpc_1_7615e_sn_8)t2-fastapi-vm
VPC ID 는 7615e61e-682b-4611-a566-562be5649dcb (newvpc_1)
서브넷 이름은 vpc_1_t2_sn_backup2
가용영역은 kr-central-2-b
IP CIDR 블록 10.0.129.240


NGINX

fastapi
인바운드 규칙

아웃바운드 규칙

인바운드 규칙

아웃바운드 규칙

프라이빗 라우팅 테이블 업데이트

BASTION
NGINX
인스턴스 생성



IP 할당 방식에서 서브넷의 C 그룹에 + 1하기 그리고 D에 240
Nginx 인스턴스 퍼블릭 IP 생성 및 연결




NAT GATEWAY 설정
Nat 인스턴스를 통해 nat 게이트웨이 만들기
kakaocloud는 nat 게이트웨이를 만들기 위해 인스턴스를 직접 nat인스턴스로 사용하게 만들어 주어야한다.
우리는 조당 1개의 nginx에 퍼블릭ip가 있기 때문에 nginx를 nat인스턴스로 만들어줄것 이다.
1-7-1. NAT 인스턴스 보안 그룹 설정
인바운드 규칙

아웃바운드 규칙

프라이빗 라우팅 테이블 업데이트

프라이빗 서브넷과 퍼블릭 서브넷을 생성한 후, 라우팅 테이블을 설정
(퍼블릭 서브넷) 라우팅 테이블
인터넷 게이트웨이 ID
(프라이빗 서브넷) 라우팅 테이블

● Nginx 인스턴스로 선택한 이유 : 새로운 인스턴스를 만들수 없었고, 카카오 클라우드 공식문서에 의하면 위 조건에 부합(Nginx 인스턴스)하는 인스턴스가 존재하기 때문.
——————nginx에서——————
*1. 패키지 목록 업데이트
sudo apt-get update -y
인스턴스의 패킷 송신 허용 IP 수정
클라우드 콘솔 설정


위와 동일하게 해주면됨

0.0.0.0/20 여기서 /20이 의미하는것 넷마스크이다.
넷마스크란 네트워크 대역을 논리적으로 분리하여 각자 다른 네트워크 망을 생성해주는것이다.
네트워크 망을 나눔으로써 특정영역은 프라이빗, 특정영역은 퍼블릭으로 설정할수 있다.
넷마스크를 사용하고 이해하는법은 아래와 같다.
/18인 경우 11111111.11111111.11000000.00000000 1이 18개
255 . 255 . 192 . 0 -> 64개씩
/17인 경우 11111111.11111111.10000000.00000000 1이 17개
255 . 255. 128 . 0 -> 128개씩
Nat 게이트웨이를 사용해야 하는 서브넷 고정 ip를 보면 144~192
그렇다면 최소 48블럭이 뚫려있어야 한다 그러면 10.0.128.0/18로 하고 64블럭으로 나눠서 쓰면 되겠네 라고 생각하겠지만 10.0.0.0도 있기 때문에 0~63,64~127,127~191, 192~255 블럭씩 쓸 수 있어 128블럭으로 나눠서 사용해야한다.
10.0.128.0/17로 사용하면 된다.

두개 추가

라우팅 테이블 private에 instance로 0.0.0.0/0 뚫어준다.
후에 잘 됐는지 확인
Private 인스턴스로 들어가
curl -I https://www.google.com
했을때 HTTP/2 200 뜨면 성공
Certification Maneger 등록
1. 프라이빗 키 (Private Key) 생성
openssl genrsa -out private.key 2048

**포맷 확인: 모든 파일은 PEM 형식이어야 합니다.
프라이빗 키 확인
Cat private.key
인증서 본문확인
Cat certificate.crt







t1

퍼블릭 IP연결










T1









10. DNS영역에 로드벨런서 DNS추가



로드벨런싱 설정 완료
**트러블슈팅
증상 : 대상 그룹에서 헬스체크 Unhealthy 상태임
Nginx ssl/tls설정 안함 443의미없음
따라서 Unhealthy 상태
보안그룹 및 Nginx 설정 오류
chmod 400 keypair2.pem
퍼블릭 키 생성
ssh-keygen -y -f keypair2.pem > keypair2.pub
vm 생성 시 위 명령어로 .pub 파일 생성
키 페어 생성 -> 기존 키 업로드 -> 생성된 .pub 파일 업로드
db 테스트 용 ssh 터널
ssh -i keypair2.pem \
-N \
-L 15432(임의 포트 번호):[db엔드포인트 주소]:5432(db포트 번호) \
ubuntu@[퍼블릭 아이피 주소]
위 명령어를 터미널에 입력하면 터널이 열림. 이 상태에서 프로젝트를 실행한다.
터널 사용 시 yaml파일의 datasource url을
jdbc:postgresql://localhost:15432/mydb
로 변경해함.
server {
listen 80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
root /usr/share/nginx/html;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html;
}
# FASTAPI 서버 전달
location /api/ {
proxy_pass http://10.0.145.240:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Chatbot
location /question/ {
proxy_pass http://10.0.145.240:8080/question;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
(Flux<String>)
해결 방법
const response = await chatClient.get(`?question=${encodeURIComponent(input)}`,);
변경 후
const response = await fetch(`http://210.109.82.105/question?question=${inputValue}`);
fastAPI 인스턴스 설정
Python 가상환경 생성 (서버)
sudo apt update
sudo apt install -y python3.12-venv
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
sudo apt update
sudo apt install postgre-client
sudo psql -h az-b.kakao-t2-db-group-po.42272f947b124b5f8f76b5a656d80baf.postgresql.managed-service.kr-central-2.kakaocloud.com -U admin -d postgres
2.vectorDB 익스텐션 설치 및 확인
postgre 접속
psql -d postgres
pgvector vectorDB생성
CREATE EXTENSION vector;
#자바설치명령어
sudo apt install openjdk-21-jre-headless
#자바 설치 확인
java --version
2.Docker 설치
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
GPG 키 추가
curl -fsSL [https://download.docker.com/linux/ubuntu/gpg](https://download.docker.com/linux/ubuntu/gpg) | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Docker 저장소 추가
echo "deb \[arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg\] [https://download.docker.com/linux/ubuntu](https://download.docker.com/linux/ubuntu) $(lsb\_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
#패키지 업뎃
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
#도커설치확인
sudo docker --version
#도커실행확인
sudo systemctl start docker
#도커로그인
sudo docker login
Mysql 인스턴스 설정
bastion에 Mysql-client 설치
sudo apt update
sudo apt install mysql-client
mysql -h az-b.kakao-t2-db-group.42272f947b124b5f8f76b5a656d80baf.mysql.managed-service.kr-central-2.kakaocloud.com -P 3306 -u admin -p
3.2 orders
3.3 products
3.4 users
ssh 접속
ssh -i keypair2.pem ubuntu@[ip주소]
vi ~/.ssh/config
Host nginx-t2
HostName 10.0.129.240
User ubuntu
IdentityFile ~/.ssh/keypair2.pem
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Host fastapi-t2
HostName 10.0.145.240
User ubuntu
IdentityFile ~/.ssh/keypair2.pem
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Host tomcat-t2
HostName 10.0.161.240
User ubuntu
IdentityFile ~/.ssh/keypair2.pem
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
1.Nginx-t2
1.Nginx 서버 접속
ssh -i ~/.ssh/keypair2.pem ubuntu@10.0.129.240
2.Nginx 공식 저장소 등록하여 설치 과정
2-1.
sudo vi /etc/apt/sources.list.d/nginx.list
deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/ubuntu jammy nginx
deb-src [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/ubuntu jammy nginx
컴퓨터의 패키지 매니저(apt)에게 Nginx를 설치할 때 공식 사이트(nginx.org)라는 주소로 가서 찾을 수 있도록 설정 파일 만드는 과정
2-2.
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o/usr/share/keyrings/nginx-archive-keyring.gpg
공식 사이트에서 내려받는 파일이 Nginx에서 검증된 파일이 맞는지 확인하기 위한 디지털 서명을 저장하는 과정
2-3.
sudo apt update
패키지 매니저인 apt 최신 업데이트
2-4.
sudo apt install nginx
패키지 목록에 있는 최신 Nginx를 컴퓨터에 설치
2-5.
nginx -v
Nginx 설치 확인 작업
2.Fast API
1. 키 파일 권한 설정 (로컬 Mac)
/Users/apple/Desktop/react_shoppingmall+springAIchatbot+fastapi/fastapiBack1에있는
fastapiBack1폴더를 bastion 서버(210.109.55.33)를 거쳐서 fastapi서버(10.0.145.240)에 넣어줘야 한다.
로컬 터미널에서 실행
chmod 400 /Users/apple/Desktop/keypair2.pem
ssh -i /Users/apple/Desktop/keypair2.pem ubuntu@210.109.55.33
접속후
로컬 Mac에서 실행
scp -i /Users/apple/Desktop/keypair2.pem \
-r fastapiBack1 \
ubuntu@210.109.55.33:/home/ubuntu/
입력
3. FastAPI VM 접속 테스트 (Bastion → FastAPI)
Bastion 서버 안에서 실행
ssh -i keypair2.pem ubuntu@10.0.145.240
scp -i keypair2.pem \
-r fastapiBack1 \
ubuntu@10.0.145.240:/home/ubuntu/
입력
4. FastAPI 서버 접속 및 프로젝트 확인
ssh -i keypair2.pem ubuntu@10.0.145.240
접속후
ls
fastapiBack1 폴더 있는거 확인.
3. spring
스프링 AI 수동배포
Docker 를 사용하여 배포를 진행한다.
먼저 gradlew 로 스프링 프로젝트를 빌드해야한다.
스프링 프로젝트 빌딩 (경로: 프로젝트 루트 폴더)
#실행 권한을 부여함
chmod +x gradlew
#빌드 실행 명령어
./gradlew build
#테스트를 제외하고 빌드함 (오류 시 이렇게)
./gradlew build -x test
빌드 결과물은
build/libs/
└── your-project-name-0.0.1-SNAPSHOT.jar
경로에 있음
이후 도커 이미지 파일을 제작한다.
Dockerfile (도커 파일 내용) (프로젝트 루트 폴더에서 작성함)
#사용하는 이미지
FROM eclipse-temurin:21-jdk-alpine
#프로젝트가 올라가는 디렉토리
WORKDIR /app
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENV JAVA_TOOL_OPTIONS="-XX:MaxRAMPercentage=75.0 -Duser.timezone=Asia/Seoul"
ENV SPRING_PROFILES_ACTIVE=prod
ENTRYPOINT ["sh", "-c", "java {SPRING_PROFILES_ACTIVE} -jar app.jar"]
ENTRYPOINT ["java", "-jar", "app.jar"]
#포트사용지정(도커내부포트)
EXPOSE 8080
도커파일은 docker 에서 이미지를 생성하기 위한 용도로 작성하는 파일이다.
만들 이미지에 대한 정보를 기술해 둔 템플릿(template) 이라고 보면 된다.
출처: https://toramko.tistory.com/entry/docker-도커파일Dockerfile-의-개념-작성-방법문법-작성-예시 [토람코:티스토리]
도커 명령어 (프로젝트 루트 폴더)
docker login
#Dockerfile을 기반으로 도커 이미지를 빌드하는 명령어
docker build --platform linux/amd64 -f Dockerfile.fast -t [도커허브사용자명]/[프로젝트이름] .
#만들어진 이미지를 도커 허브에 push함
#이 때 프로젝트 이름 뒤에 :3.12 등 숫자를 붙이면 버전에 이미지를 붙인 것이 된다.
#아무것도 붙이지 않으면 자동적으로 latest로 붙여짐
docker push [도커허브사용자명]/[프로젝트이름]
맥os 에서 도커를 빌드할 때 --platform linux/amd64를 옵션으로 넣어주어야한다.
도커 명령어 (서버)
docker login
#깃헙처럼 레포지토리에 push 된것을 pull 하여 서버에 내려받음
sudo docker pull [도커허브사용자명]/[프로젝트이름]
# pull한 도커 이미지들을 확인한다.
sudo docker images
# 환경 변수 선언을 여기에서 할 수 있다.
sudo docker run -d \
--name spring \
-p 8080:8080 \
-e GEMINI_API_KEY=[api key]\
-e GOOGLE_PROJECT_ID=[project id] \
[도커허브사용자명]/[프로젝트이름]:latest
Tomcat
환경 셋팅
sudo apt install openjdk-21-jre-headless