INFRA BASICS
VPC·배스천·NAT부터 SSH·pem·jar 배포까지. 인프라를 처음 보는 사람이 남에게 설명할 수 있을 만큼만 담았어요.
1부
클라우드에 서버를 두면 그 서버는 어떤 땅, 어떤 구역에 놓이고, 사람과 데이터는 어느 문으로 드나드는지.
Virtual Private Cloud
VPC는 클라우드 안에 울타리를 친 우리 전용 땅이에요.
클라우드는 아마존 같은 회사가 지은 거대한 건물을 여러 회사가 나눠 쓰는 곳이에요. 그냥 두면 내 서버와 옆 회사 서버가 같은 복도에 놓이죠. 그래서 울타리를 쳐요. 그 울타리 안이 VPC예요.
10.0.0.0/16 (우리 땅 안에서만 쓰는 주소 범위를 적는 방식)문 — 드나들려면 반드시 거치는 곳 인터넷과 통하는 구역 보호 구역
서브넷은 울타리 안을 나눈 구역이에요. 길가 구역(퍼블릭)과 안쪽 구역(프라이빗), 이 둘만 기억하면 돼요.
| 구분 | 퍼블릭 서브넷 | 프라이빗 서브넷 |
|---|---|---|
| 비유 | 길가 쪽 마당 | 안쪽 주방·창고 |
| 인터넷 | 직접 오갈 수 있음 | 밖에서 들어올 길이 없음 |
| 뭘 두나 | 문 역할 하는 것들 — 배스천, NAT, 로드밸런서(손님을 여러 서버에 나눠 주는 안내원) | 앱 서버, DB |
규칙은 하나예요. 중요한 건 전부 안쪽(프라이빗)에 둔다. 앱 서버도, DB도요. 그러면 바로 문제 두 개가 생겨요.
문제 ① 안쪽 서버에 개발자가 들어갈 길이 없다
배스천은 사람이 안쪽 서버로 들어가는 유일한 문이에요. 길가 구역에 세운 작은 경비실.
로그를 보거나 설정을 고치려면 서버에 직접 들어가야 해요. 그런데 안쪽 서버는 인터넷에서 들어갈 길이 없죠. 그래서 길가 구역에 작은 서버를 한 대 둬요. 그게 배스천(bastion, 요새)이에요.
두 번 거치는 이유는 하나예요. 밖에 열린 문이 딱 하나가 되니까요. 문이 스무 개면 못 지키지만 하나면 지킬 수 있어요.
문제 ② 안쪽 서버도 밖에 나갈 일이 있다
NAT 게이트웨이는 안쪽 서버 대신 밖에 나갔다 오는 심부름꾼이에요.
안쪽 서버도 프로그램을 설치하고, 보안 패치를 받고, 다른 회사 서비스를 호출해요. 그런데 공인 IP(바깥 세상에서 쓰는 주소)가 없어서 직접은 못 나가요.
그래서 심부름꾼을 둬요. 안쪽 서버가 "이거 받아 와" 하면 NAT 게이트웨이가 자기 공인 IP로 바꿔서 대신 요청하고, 답이 오면 원래 서버에 돌려줘요.
제일 중요한 특징은 한 방향이라는 것. 안에서 먼저 시켜야만 움직여요. 밖에서 NAT한테 "나 들여보내 줘"라고 두드리는 건 안 돼요.
| 구분 | 배스천 서버 | NAT 게이트웨이 |
|---|---|---|
| 방향 | 밖 → 안 (들어옴) | 안 → 밖 (나감) |
| 누가 쓰나 | 사람 (개발자, 운영자) | 서버 (프로그램) |
| 목적 | 관리 접속 (SSH) | 패치, 외부 서비스 호출 |
| 위치 | 퍼블릭 서브넷 | 퍼블릭 서브넷 |
| 없으면 | 서버 관리 불가 | 프로그램 설치·외부 연동 불가 |
AWS Session Manager를 쓰면 배스천 없이, 22번 포트도 안 열고 안쪽 서버에 들어갈 수 있어요. AWS 권한(IAM)으로 통제하고 접속 기록도 자동으로 남아요. 새로 지으면 이쪽을 먼저 검토하세요. 그래도 배스천 개념은 알아둬야 해요. 기존 시스템엔 거의 다 남아 있거든요.
시간당 요금에 더해 지나가는 데이터 GB당 요금이 붙어요. 가용영역(AZ)마다 하나씩 두면 그만큼 곱해지고요. 인프라 비용표 위쪽에 NAT Gateway가 있으면 이 항목을 먼저 보세요.
S3나 DynamoDB(AWS 데이터베이스)로 가는 트래픽이 많다면 VPC Endpoint를 달아 NAT를 안 거치게 해요. AWS 안 길로 가니까 싸고 빨라요. S3·DynamoDB용 Endpoint는 무료예요.
2부
내 컴퓨터에서 고친 코드가 어떻게 자동으로 서버에 올라가 실행되는지. 자바 서버를 AWS EC2에 올리는 경우로 봐요.
CI/CD가 하는 일
코드를 push하면 자동으로 굽고(빌드), 서버에 갖다 놓고 켜요(배포). 이게 CI/CD예요.
요리로 비유하면 이래요.
| 등장인물 | 비유 | 하는 일 |
|---|---|---|
| GitHub 저장소 | 레시피 보관함 | 코드를 보관해요. |
| GitHub Actions 러너 | 임시 주방 | 코드가 바뀌면 jar를 굽고 사라져요. Jenkins는 이 주방을 직접 차린 버전이에요. |
| EC2 | 24시간 여는 식당 | VPC 안에 항상 켜져 있는 리눅스 컴퓨터예요. |
| app.jar | 완성된 요리 | 실행 가능한 프로그램 파일이에요. |
빌드 쪽 — 일회용 서버 쪽 — 항상 켜짐
포인트 세 개.
./gradlew build 같은 명령으로 app.jar를 만들어요.가장 기본적인 건네주기 방법이 SSH예요. 택배 기사가 열쇠로 식당 뒷문을 열고, 음식을 놓고, 스위치를 켜는 것과 같아요.
준비물은 세 개예요.
scp와 ssh 명령 적기Secure Shell
SSH는 멀리 있는 컴퓨터를 내 앞에 있는 것처럼 조종하는, 암호로 잠근 무전기예요.
지구 반대편 컴퓨터에 명령을 치고 파일을 보낼 수 있어요. 그 내용은 아무도 엿듣지 못하게 암호로 잠겨요.
핵심은 하나. 열쇠와 자물쇠는 한 쌍이에요.
~/.ssh/authorized_keys에 달려요.SSH로 하는 일은 두 가지예요.
# EC2에 들어가서 명령 치기 (여기서 java -jar 실행)
ssh -i key.pem ec2-user@1.2.3.4
# 같은 터널로 파일 복사 (scp = SSH 위에서 파일 복사)
scp -i key.pem app.jar ec2-user@1.2.3.4:/home/ec2-user/
22번 포트는 이 무전기의 주파수 번호예요. 보안 그룹에서 22번을 열어야 두드릴 수 있고, 아무 IP에나 열면 위험하니 보통 정해진 IP만 허용해요.
java -jar를 직접 치지 말고 리눅스 systemd에 서비스로 등록해 두세요. sudo systemctl restart myapp으로 재시작하고, 서버가 재부팅돼도 알아서 다시 떠요.
질문: pem 파일은 EC2마다 하나씩인가요? 아니면 한 EC2에 여러 개?
둘 다 아니에요. pem은 EC2가 아니라 AWS 계정에 있는 열쇠 쌍이에요. EC2를 만들 때 "이 열쇠 쓸게요" 하고 고르는 것뿐이에요.
아파트 마스터키 하나로 여러 집을 여는 것과 같아요.
| 경우 | 되나요 | 어떻게 |
|---|---|---|
| 열쇠 쌍 1개 → EC2 여러 대 | 돼요. 흔해요. | 만들 때 같은 열쇠 쌍을 고르면 끝. |
| EC2 1대 → 열쇠 여러 개 | 돼요. | 서버 안 authorized_keys 파일에 다른 사람 공개키를 한 줄 더 붙여요. AWS 콘솔이 아니라 리눅스 파일을 직접 고치는 거예요. |
| 잃어버린 개인키 다시 받기 | 안 돼요. | AWS는 개인키를 보관하지 않아요. 만들 때 딱 한 번 다운로드. |
그래서 개인키가 새면 그 열쇠로 만든 EC2 전부가 위험해요. 실무에서는 환경별·팀별로 열쇠 쌍을 나누되, EC2마다 만들진 않아요. 개발/운영 서버 열쇠를 분리하고, 배포용(GitHub Actions) 열쇠를 따로 두는 식이에요.
Session Manager는 22번 포트를 아예 안 열고 AWS 권한(IAM)만으로 터미널에 들어가요. EC2 Instance Connect는 60초짜리 1회용 열쇠를 발급해요. 열쇠 파일을 여러 사람이 돌려 쓰는 문제가 사라져요.
질문: EC2에서 도는 WAS가 jar 파일들인 거죠?
절반만 맞아요. 두 가지 형태가 있고, 요즘은 첫 번째가 대세예요.
WAS는 자바 프로그램을 돌려 주는 서버 소프트웨어예요. Tomcat이 대표예요.
| 구분 | 내장 WAS (Spring Boot) | 외장 WAS (전통) |
|---|---|---|
| 비유 | 도시락. 밥·반찬 다 들어 있음 | 식당 건물 + 요리사 |
| 파일 | app.jar 하나. Tomcat 포함 | Tomcat 설치 + .war 파일 |
| 실행 | java -jar app.jar | war를 webapps/에 넣고 Tomcat 재시작 |
| 배포 | jar만 옮기면 끝 | war 옮기고 Tomcat 재시작 (또는 자동 배포) |
| 요즘 | 대세 | 옛 시스템에 남아 있음 |
어느 쪽인지는 서버에서 한 줄이면 알아요.
ps -ef | grep java
# java -jar xxx.jar 가 보이면 → 내장
# org.apache.catalina.startup.Bootstrap 이 보이면 → 외장
내장형이라도 EC2 한 대에 jar가 여러 개 돌 수 있어요. 주문 서비스 8080, 재고 서비스 8081처럼 포트를 나눠요. "WAS가 돌고 있다"는 말이 실제로는 "jar 프로세스가 N개 떠 있다"인 경우가 많아요.
질문: Tomcat 설정을 바꾸려면 재빌드·재배포해야 한다면, 내장형인 거죠?
네, 내장형이라는 강한 신호예요. 설정이 jar 안에 같이 구워져 있거든요.
| 구분 | 내장 WAS | 외장 WAS |
|---|---|---|
| 설정이 있는 곳 | jar 안 application.yml | 서버의 Tomcat conf/server.xml |
| 바꾸는 법 | jar 안 yml만 바꾸면 재빌드. 바깥으로 빼면 빌드 없음 | SSH로 파일 고치고 Tomcat만 재시작. 빌드 없음 |
빌드 없이 바꾸는 방법이 있어요. Spring Boot는 바깥에 있는 설정을 먼저 봐요.
# 실행 인자
java -jar app.jar --server.port=9090
# 환경 변수
SERVER_TOMCAT_THREADS_MAX=400 java -jar app.jar
# jar 옆에 application.yml 을 두면 jar 안의 것보다 먼저 적용
설정이 jar 안에만 있고 바깥 설정 경로를 안 쓰는 거예요. 잘못은 아니지만, 자주 바뀌는 값은 환경변수나 외부 yml로 빼두면 운영 부담이 줄어요.
처음엔 SSH로 직접, 커지면 S3 경유 → CodeDeploy → Docker 순으로 넘어가요.
| 방식 | 어떻게 | 언제 쓰나 |
|---|---|---|
| SSH 직접 | 러너가 scp로 놓고 ssh로 켜요. | 서버 한두 대, 처음 시작할 때 |
| S3 경유 | 러너가 jar를 S3에 올리고, EC2가 스스로 내려받아요. | 22번 포트를 닫고 싶을 때 |
| CodeDeploy | 러너가 배포를 걸면 EC2 안의 에이전트(작은 배포 도우미)가 S3에서 받아 설치하고 재시작해요. | 서버가 여러 대일 때 |
| Docker + ECR | 컨테이너 이미지를 ECR(이미지 창고)에 올리고 EC2가 docker pull로 받아요. | 요즘 가장 흔해요. 새로 시작하면 이쪽 |
1부와 연결하면, SSH 직접 방식은 EC2에 22번 포트를 여는 거라 "문은 하나만" 원칙과 부딪혀요. S3 경유, CodeDeploy, Session Manager는 그 문을 안 열어도 되는 방법이에요.
3부
구조도나 대화에서 튀어나올 때 찾아보세요
| 용어 | 한 줄 설명 | 비유 |
|---|---|---|
| VPCVirtual Private Cloud | 클라우드 안에 만든 내 전용 네트워크 | 울타리 친 땅 |
| 서브넷 | VPC 안을 나눈 구역 | 길가 구역 / 안쪽 구역 |
| 퍼블릭 서브넷 | 인터넷과 직접 통하는 구역 | 길가 |
| 프라이빗 서브넷 | 인터넷에서 못 들어오는 구역 | 안쪽 주방·창고 |
| 공인 IPPublic IP · Internet Protocol | 인터넷 전체에서 통하는 주소 | 도로명 주소 |
| 사설 IPPrivate IP | 울타리 안에서만 통하는 주소 | 집 안 방 번호 |
| 배스천 서버Bastion Host · bastion = 요새 | 안쪽 서버로 들어가기 위해 거치는 서버 | 경비실 있는 유일한 문 |
| NAT 게이트웨이Network Address Translation | 안쪽 서버 대신 밖에 나가는 장치 | 심부름꾼 |
| 로드밸런서 | 들어오는 요청을 여러 서버에 나눠 주는 장치 | 손님을 창구로 나눠 주는 안내원 |
| 보안 그룹 | 서버별 방화벽. 어느 포트를 누구에게 열지 | 문 앞 출입 명단 |
| 포트 | 한 컴퓨터 안의 창구 번호. 22=SSH, 80/443=웹 | 무전기 주파수 |
| Session ManagerAWS Systems Manager Session Manager | 22번 포트 없이 AWS 권한으로 서버에 접속 | 열쇠 대신 출입증 |
| VPC EndpointVirtual Private Cloud Endpoint | NAT 없이 AWS 서비스로 가는 전용 길 | 건물 안 지름길 |
| 가용영역 (AZ)Availability Zone | 한 지역 안의 독립된 데이터센터 | 같은 도시의 다른 건물 |
| IAMIdentity and Access Management | AWS 권한 관리 | 출입증 발급소 |
| EC2Elastic Compute Cloud | AWS에서 빌린 가상 컴퓨터(서버) | 24시간 식당 |
| 러너 | CI가 빌드할 때 잠깐 쓰는 일회용 컴퓨터 | 임시 주방 |
| GitHub Actions / Jenkins | 코드가 바뀌면 자동으로 빌드·배포하는 도구 | 주방 자동화 |
| CI / CDContinuous Integration / Continuous Delivery | 자동 빌드 / 자동 배포 | 굽기 / 배달 |
| SSHSecure Shell | 원격 컴퓨터를 안전하게 조종하는 방법 | 암호 무전기 |
| scpSecure Copy | SSH로 파일 복사 | 무전기로 택배 보내기 |
| 공개키 / 개인키 | 서버에 다는 자물쇠 / 내가 가진 열쇠 | 자물쇠 / 열쇠 |
| pemPrivacy-Enhanced Mail (파일 형식 이름) | 개인키를 담은 파일 | 열쇠 파일 |
| ymlYAML · YAML Ain't Markup Language | 설정이나 자동화 순서를 적는 텍스트 파일 형식 | 설정 메모지 |
| GitHub Secrets | 저장소에 숨겨 두는 비밀값 | 금고 |
| jarJava Archive | 자바 프로그램을 하나로 묶은 파일 | 도시락 |
| warWeb Application Archive | 외장 WAS에 넣는 자바 웹앱 파일 | 식당에 들어가는 요리사 |
| WASWeb Application Server | 자바 웹 프로그램을 실행해 주는 서버 소프트웨어 | 식당 건물 |
| Tomcat | 가장 흔한 WAS | 식당 건물 브랜드 |
| Spring Boot | Tomcat을 내장한 자바 프레임워크 | 도시락 만드는 법 |
| systemd | 리눅스에서 프로그램을 서비스로 등록해 자동 실행 | 자동 스위치 |
| S3Simple Storage Service | AWS 파일 창고 | 큰 창고 |
| CodeDeploy | S3의 새 버전을 서버에 자동 설치 | 배달 로봇 |
| Docker / ECRECR · Elastic Container Registry | 프로그램과 실행 환경을 통째로 담은 상자 / 그 상자 창고 | 밀키트 / 밀키트 창고 |