Day52

https://velog.io/@dos123789/DAY52

1. 배운 내용

이번 실습을 통해 클라우드 인프라 → 네트워크 → 서버 접근 → 애플리케이션 배포까지의 전체 흐름을 실제로 경험했다.

가장 큰 수확은 “FastAPI 서버가 실제로 외부 요청을 받아 응답하기까지 필요한 모든 단계”를 손으로 직접 연결해봤다는 점이다.

VPC · 서브넷 · 보안그룹 이해

VPC 안에서 서브넷이 가용 영역 단위로 분리된다는 점을 명확히 이해했다.

서브넷 CIDR 범위와 보안그룹 인바운드 규칙이 실제 통신 가능 여부를 결정한다는 것을 실습으로 체감했다.

FastAPI(8000), SSH(22), Vite(5173)를 왜 각각 열어야 하는지 목적이 분명해졌다.

Bastion Host의 역할

Bastion 서버는 외부 → 내부 프라이빗 서버로 들어가기 위한 관문이라는 개념을 이론이 아니라 실전으로 이해했다.

로컬 → Bastion → FastAPI VM으로 이어지는 2-hop SSH 구조를 직접 구성해봄으로써,

프라이빗 IP 서버는 외부에서 바로 접근할 수 없다는 점

보안적으로 Bastion이 왜 필요한지
를 확실히 알게 됐다.

SSH · SCP 명령어 숙련

chmod 400의 의미(개인 키 보호)를 이해했다.

ssh -i key.pem user@ip / scp -i key.pem -r 흐름을 반복하면서 서버 작업의 기본 루틴이 몸에 익었다.

특히 Bastion을 경유한 파일 복사 과정에서
“어디서 실행하는 명령인지”가 얼마나 중요한지 깨달았다.

FastAPI 서버 환경 구성

서버에서 Python 가상환경을 직접 구성하며,

로컬 개발 환경과 서버 실행 환경이 분리되어야 하는 이유를 이해했다.

uvicorn --host 0.0.0.0 옵션의 의미를 정확히 알게 됐다.

curl로 외부 요청을 보내 실제 응답이 돌아오는 것을 확인하면서
“배포 성공”의 기준이 무엇인지 명확해졌다.

2. 부족한 점 및 보완할 점

실습을 성공적으로 마쳤지만, 몇 가지 한계와 개선 포인트도 분명히 느꼈다.

네트워크 설계 이해의 깊이 부족

CIDR 범위(10.0.112.0/20, 10.0.129.240)를 암기 수준으로 사용했다.

향후에는

해당 IP 대역이 실제로 몇 개의 IP를 포함하는지

왜 이 범위를 선택했는지
를 계산 기반으로 설명할 수 있도록 보완이 필요하다.

서버 운영 관점 부족

현재는 uvicorn을 직접 실행하는 수준이라,

서버 재부팅 시 자동 실행되지 않음

프로세스 관리가 불안정함

다음 단계로는

systemd 서비스 등록

또는 gunicorn + uvicorn workers

Nginx 리버스 프록시
까지 연결해 운영 환경 수준으로 끌어올릴 필요가 있다.

보안 설정에 대한 인식 부족

보안그룹을 “열어야 하니까 연다”는 관점에서 설정했다.

이후에는

8000 포트 외부 노출 최소화

Bastion IP만 SSH 허용

API 서버는 내부 통신 전용으로 구성
같은 보안 기준 중심 사고를 강화해야겠다.

자동화 미흡

모든 과정이 수동 명령 위주라 재현성이 떨어진다.

추후 보완 목표:

서버 초기 세팅 스크립트화

requirements.txt + 실행 명령 정형화

CI/CD 또는 GitHub Actions 연계

Day53

https://velog.io/@dos123789/Day53

1. 배운 내용

이번 실습을 통해 단일 서버 배포가 아닌, 실제 서비스 수준의 인프라 구성과 배포 흐름을 처음부터 끝까지 경험했다.
특히 “왜 이렇게 구성해야 하는가”에 대한 이해가 이전보다 훨씬 명확해졌다.

1) VPC · 서브넷 · CIDR 설계 이해

VPC를 10.0.0.0/16으로 설정한 뒤, 서브넷을 /20 단위로 분리해 역할별 네트워크를 구성했다.

단순히 IP를 나눈 것이 아니라:

Web(Nginx)

WAS(FastAPI, Spring/Tomcat)

DB(MySQL, PostgreSQL Vector DB)
를 네트워크 레벨에서 격리했다는 점이 핵심이다.

/20, /17, /18 넷마스크를 실제 이진수로 계산해보며
“얼마만큼의 IP 블록을 확보하는지”를 논리적으로 판단하는 경험을 했다.

2) 퍼블릭 / 프라이빗 서브넷과 NAT 구조

퍼블릭 서브넷에는 Nginx + Bastion만 두고,

FastAPI, Spring, DB 인스턴스는 모두 프라이빗 서브넷에 배치했다.

KakaoCloud 특성상 NAT Gateway를 별도 서비스로 생성하지 않고
Nginx 인스턴스를 NAT 인스턴스로 활용해야 했는데,

IP Forwarding

iptables MASQUERADE

패킷 송신 허용 IP 설정
까지 직접 설정하며 NAT의 내부 동작 원리를 이해할 수 있었다.

프라이빗 인스턴스에서 curl google.com 테스트로
아웃바운드 통신 성공 여부를 검증한 과정이 인상 깊었다.

3) Bastion Host 기반 접근 구조

외부 → Bastion → 내부 인스턴스로 이어지는 2-Hop SSH 구조를 직접 구성했다.

~/.ssh/config를 활용해

nginx-t2

fastapi-t2

tomcat-t2
별칭 접속 환경을 만든 경험은 이후 서버 관리 효율을 크게 높여줄 것이라 느꼈다.

“프라이빗 서버는 절대 외부에서 직접 접근하지 않는다”는 원칙이 명확해졌다.

4) 로드밸런서 + 인증서 구성

ALB 생성 → 리스너(80/443) → 인증서 등록 → 대상 그룹 연결
전체 흐름을 처음부터 끝까지 구성했다.

SSL 인증서 생성 과정(OpenSSL → CSR → CRT)을 직접 수행하며
인증서의 구성 요소와 PEM 포맷의 의미를 이해했다.

헬스체크 Unhealthy 이슈를 통해
SSL 설정이 없는 Nginx에서 443 헬스체크가 실패하는 이유를 명확히 알게 되었다.

5) 서비스별 배포 전략 차이 이해

Frontend (React)

build → dist 생성 → Nginx 정적 파일 배포

try_files 설정으로 SPA 라우팅 처리

FastAPI

Bastion 경유 파일 전송

Python venv 구성

uvicorn 직접 실행

Spring (AI 서버)

Gradle 빌드 → Docker 이미지 생성

Docker Hub push → 서버 pull → 컨테이너 실행

서비스 특성에 따라 배포 방식이 달라져야 한다는 점을 실전에서 체감했다.

6) 프론트엔드 ↔ 백엔드 통신 트러블슈팅

Spring AI 서버가 FluxString 스트림 응답을 반환하면서
프론트엔드에서 JSON 파싱 에러가 발생한 문제를 경험했다.

axios 대신 fetch API를 사용해 스트림 응답을 처리하며,
응답 타입과 클라이언트 처리 방식의 중요성을 이해했다.

2. 부족한 점 및 보완할 점

실습을 성공적으로 마쳤지만, 운영 관점에서는 여전히 보완할 점이 많다고 느꼈다.

1) 자동화 부족

인프라 생성, 서버 세팅, 배포 과정 대부분이 수동이다.

향후에는:

인프라: Terraform 또는 IaC 도입

서버 초기화: Shell Script 정리

배포: CI/CD 파이프라인 구성
으로 재현성과 안정성을 높이고 싶다.

2) 서버 운영 안정성

FastAPI는 uvicorn을 직접 실행 중이라

서버 재부팅 시 자동 실행 불가

장애 발생 시 복구 어려움

systemd 등록 또는 Docker 기반 실행으로 전환이 필요하다.

3) 보안 설정에 대한 체계 부족

보안 그룹과 포트 설정은 “필요해서 열었다” 수준에 머물렀다.

이후에는:

내부 통신 포트 최소화

관리용 SSH IP 제한

서비스별 보안 그룹 분리
같은 보안 기준 중심 설계를 더 강화해야겠다.

4) 아키텍처 문서화 미흡

구성은 복잡하지만, 이를 한눈에 볼 수 있는

네트워크 다이어그램

서비스 흐름도
가 부족하다.

다음 단계에서는 설계 문서 + 아키텍처 그림을 반드시 함께 남길 계획이다.

Day54

https://velog.io/@dos123789/Day54

1. 배운 내용

이번 정리를 통해 Spring Boot 애플리케이션을 ‘수동 배포’에서 ‘자동 배포’로 전환하는 전체 흐름을 명확히 이해하게 되었다.
단순히 빌드 명령을 자동화하는 수준이 아니라, CI/CD의 역할 분리와 운영 관점의 배포 구조를 학습한 것이 가장 큰 수확이다.

1) 자동 배포의 목적과 필요성

코드 수정 → 빌드 → 서버 업로드 → 재시작을 매번 수동으로 하는 방식은

실수 가능성이 높고

배포 시간이 길며

장애 발생 시 롤백이 어렵다.

GitHub Actions를 이용한 자동 배포는

배포 과정을 표준화하고

사람 개입을 최소화하며

동일한 절차를 반복 가능하게 만든다.

2) CI/CD 전체 흐름 이해

로컬에서 코드 작성 후 git push

GitHub Actions 트리거 발생

Gradle 기반 Spring Boot 프로젝트 빌드

빌드 산출물(Jar) 생성

EC2 서버로 파일 전송

서버에서 애플리케이션 재시작

이 흐름을 통해
CI는 “빌드의 신뢰성 확보”,
CD는 “서버 반영 자동화”
라는 역할 분리가 명확해졌다.

3) GitHub Actions 기본 구조 이해

deploy.yml 파일 하나로

트리거 조건

실행 환경

빌드 단계

배포 단계
를 모두 정의할 수 있다는 점이 인상적이었다.

checkout, setup-java, gradlew build 단계가
실제 서버 없이도 빌드 환경을 재현해준다는 점에서
빌드 환경 독립성의 중요성을 느꼈다.

4) Secrets 기반 보안 설정

EC2 접속 정보와 Private Key를 코드에 직접 넣지 않고
GitHub Secrets로 관리함으로써

레포지토리 보안

키 노출 방지
를 동시에 만족시킬 수 있었다.

자동 배포 환경에서도 보안은 항상 분리 관리되어야 한다는 원칙을 체감했다.

5) scp + ssh 방식 배포 이해

scp를 통해 빌드 결과물을 서버로 전송하고

ssh를 통해 원격에서 실행 스크립트를 호출하는 구조는
자동 배포의 가장 단순하지만 직관적인 형태였다.

이 방식을 통해

서버 내부 구조

실행 파일 위치

재시작 방식
을 명확히 인지하게 되었다.

6) systemd 기반 운영의 중요성

단순 nohup java -jar 방식은

서버 재부팅 시 자동 실행되지 않고

프로세스 관리가 어렵다.

systemd를 사용하면

서비스 자동 시작

비정상 종료 시 자동 재시작

운영 명령어 표준화
가 가능해져 운영 안정성이 크게 향상됨을 이해했다.

2. 부족한 점 및 보완할 점

자동 배포의 기본 흐름은 구축했지만, 실서비스 관점에서는 여전히 개선할 부분이 많다.

1) 무중단 배포 구조 미흡

현재 구조는 배포 시 기존 프로세스를 종료하고 새로 실행하는 방식이다.

요청이 많은 환경에서는 짧은 다운타임이 발생할 수 있다.

향후에는

Blue-Green 배포

로드밸런서 기반 무중단 배포

Docker + 컨테이너 교체 방식
으로 확장할 필요가 있다.

2) 롤백 전략 부족

배포 실패 시 이전 버전으로 되돌리는 명확한 전략이 없다.

버전별 Jar 관리 또는

Docker 이미지 태그 관리

이전 버전 자동 복구 스크립트
를 도입해야 한다.

3) 로그 관리 미흡

현재는 단일 로그 파일로 출력되고 있다.

장기 운영을 고려하면

로그 로테이션

로그 분리 (access / error)

중앙 로그 수집
이 필요하다.

4) 환경 분리 부족

현재 구조는 단일 환경(main 브랜치 기준) 중심이다.

추후에는

dev / prod 환경 분리

브랜치별 배포 전략

환경 변수 세분화
를 통해 실제 운영 환경에 가깝게 개선해야겠다.

Day55

https://velog.io/@dos123789/Day55

1. 배운 내용

이번 정리를 통해 Linux 서버를 다룰 때 필요한 가장 기본적이면서도 필수적인 명령어 흐름을 체계적으로 이해하게 되었다.
단순 명령어 암기가 아니라, 서버에서 실수하지 않기 위한 작업 습관을 익힌 것이 가장 큰 수확이다.

1) 디렉터리 이동 시 기본 루틴 정립

서버에 접속하면 항상

pwd로 현재 위치 확인

ls로 디렉터리 구조 확인
하는 습관의 중요성을 체감했다.

이 기본 루틴만 지켜도

잘못된 경로에서 파일 삭제

엉뚱한 위치에 파일 생성
같은 사고를 크게 줄일 수 있다는 점을 알게 되었다.

2) ls 옵션을 통한 파일 정보 해석

ls -l 출력 결과를 통해

파일 권한

소유자

그룹

파일 크기와 수정 시간
을 읽을 수 있게 되었다.

/, @, 실행 파일 표시 등을 통해
파일의 성격을 한눈에 파악하는 감각을 익혔다.

3) 절대경로 vs 상대경로 개념 명확화

서버 작업에서는 상대경로보다
절대경로를 기준으로 명령어를 작성하는 것이 안전하다는 점을 이해했다.

/etc/nginx/nginx.conf처럼
시스템 설정 파일은 항상 절대경로 기준으로 접근해야 한다는 인식이 생겼다.

4) Linux 디렉터리 구조 감각 습득

모든 디렉터리를 외울 필요는 없지만,

/etc는 설정

/var는 로그

/home은 사용자 영역
이라는 역할 중심 이해가 중요하다는 것을 배웠다.

로그가 /var/log 아래에 모이는 이유를
실습과 함께 자연스럽게 연결할 수 있었다.

5) man 페이지 활용 습관

옵션이 기억나지 않을 때 검색보다
man 명령어를 먼저 확인하는 습관이 중요하다는 점을 인식했다.

이는 서버 환경처럼 인터넷 접근이 제한된 상황에서도
스스로 문제를 해결할 수 있는 기본 역량이 된다.

6) 파일 권한과 보안 인식

drwxr-xr-x 형태의 권한 표기를 통해

소유자 / 그룹 / 기타 사용자 권한 구분

읽기, 쓰기, 실행 권한의 의미
를 명확히 이해했다.

특히 서버 환경에서는
권한 설정이 곧 보안 설정이라는 점을 체감했다.

7) 로그 확인 능력의 중요성

tail -f를 통한 실시간 로그 확인은
백엔드·서버 개발에서 가장 중요한 디버깅 도구임을 알게 되었다.

애플리케이션 장애 발생 시
“코드보다 로그를 먼저 본다”는 말의 의미를 이해했다.

2. 부족한 점 및 보완할 점

기본 명령어는 익혔지만, 실무 수준으로 사용하기 위해서는 추가 보완이 필요하다.

1) 명령어 조합 활용 부족

현재는 단일 명령어 위주로 사용하고 있다.

이후에는

grep, awk, pipe(|)

find와 xargs
같은 명령어 조합을 통해
대량 로그 처리와 자동화 작업까지 확장할 필요가 있다.

2) 권한 변경 실습 부족

chmod, chown에 대한 개념은 이해했지만
실제 상황에서 많이 다뤄보지는 못했다.

실습을 통해

서비스 실행 권한 문제

배포 시 권한 에러
를 직접 해결해보는 경험이 필요하다.

3) 위험 명령어에 대한 체감 부족

rm -rf의 위험성은 이론적으로 알고 있지만
실제 서버 사고 사례를 통해 더 경각심을 가질 필요가 있다.

이후에는

삭제 전 ls로 재확인

-i 옵션 적극 활용
같은 안전 습관을 철저히 유지해야겠다.

4) 서버 자동화와의 연결 부족

현재는 수동 명령어 위주 학습이다.

이 명령어들을

배포 스크립트

서버 초기화 스크립트

CI/CD 자동화
에 어떻게 녹일 수 있는지까지 연결해서 학습할 필요가 있다.

Day56 휴무

개인사정으로 인한 휴무로 참석하지못함.

본 후기는 카카오엔터프라이즈x스나이퍼팩토리 카카오클라우드로 배우는 AIaaS 마스터 클래스 3기(B-log) 리뷰로 작성 되었습니다.

profile
Change Up

0개의 댓글