다중 가용 영역에서 NAT 인스턴스를 이용한 네트워크 구축
본 문서는 다중 가용 영역(Multi Availability Zone)의 각 가용 영역에 카카오클라우드 VM의 NAT(Network Address Translation) 인스턴스를 구축하는 방법을 소개합니다.
- 예상 소요 시간: 40분
- 권장 운영 체제: MacOS, Ubuntu
- Region: kr-central-2
시작하기 전에
카카오클라우드 VPC 환경에서 가용 영역(Availability Zone) 마다 NAT 인스턴스를 배치할 수 있습니다. 이러한 구성을 통해 어느 한 가용 영역에서 장애가 발생하더라도 다른 가용 영역의 워크로드는 해당 영역의 NAT 인스턴스를 통해 중단 없이 외부와 통신할 수 있습니다. 이는 전체 클라우드 시스템의 원활한 운영을 보장하며, 잠재적인 서비스 중단을 예방할 수 있습니다.
시나리오 소개
이 문서에서는 카카오클라우드 VPC 환경에서 NAT 인스턴스를 통해 프라이빗 서브넷의 인스턴스들이 안전하게 외부와 통신할 수 있도록 구성하는 방법을 단계별로 설명합니다. 이 시나리오의 주요 내용은 다음과 같습니다.
- NAT 인스턴스 생성 및 설정: 외부 통신을 지원하는 NAT 인스턴스를 생성하고 설정합니다.
- Route Table 구성: 프라이빗 서브넷에 대한 라우트 테이블을 생성하고 외부 인터넷을 향하는 요청을 해당 가용 영역의 NAT 인스턴스로 라우트하도록 구성합니다.
- Security Group 및 인바운드 정책 설정: 보안을 위해 NAT 인스턴스를 통하는 요청의 포트를 80(HTTP)과 443(HTTPS) 포트로 제한합니다.
시나리오 아키텍처
작업 순서
카카오클라우드 VPC의 Private 서브넷에서 인터넷에 접속하기 위해 NAT 통신을 지원하는 NAT 인스턴스를 구성해 보겠습니다.
Step 1. VPC 및 서브넷 생성
VPC 및 서브넷을 생성합니다.
-
카카오클라우드 콘솔 > Beyond Networking Service > VPC 메뉴로 이동합니다.
-
VPC 탭에서 [VPC 생성] 버튼을 클릭한 후, 다음과 같이 VPC 및 Subnet을 생성합니다.
구분 항목 설정/입력값 VPC 정보 VPC 이름 tutorial VPC IP CIDR 블록 10.0.0.0/16 Availability Zone AZ 개수 2 첫 번째 AZ kr-central-2-a 두 번째 AZ kr-central-2-b Subnet 설정 AZ당 Public Subnet 개수 1 AZ당 Private Subnet 개수 4 kr-central-2-a - Public Subnet IPv4 CIDR 블록: 10.0.0.0/20
- Private Subnet IPv4 CIDR 블록: 10.0.16.0/20, 10.0.32.0/20, 10.0.48.0/20, 10.0.64.0/20
kr-central-2-b - Public Subnet IPv4 CIDR 블록: 10.0.80.0/20
- Private Subnet IPv4 CIDR 블록: 10.0.96.0/20, 10.0.112.0/20, 10.0.128.0/20, 10.0.144.0/20
- Public Subnet IPv4 CIDR 블록: 10.0.0.0/20
-
하단에 생성되는 다이어그램을 확인 후, [만들기] 버튼을 클릭합니다.
- Subnet의 상태는
Pending Create
>Pending Update
>Active
순서로로 변경됩니다.Active
상태가 되어야 다음 단계를 진행할 수 있습니다. - 생성하는데 5 ~ 10분 정도의 소요 시간이 있을 수 있습니다.
- Subnet의 상태는
Step 2. Security Group 생성
VPC에서 VM을 실행 시 해당 VM에 대한 보안을 강화하기 위해, 다음과 같이 Security Group을 생성하고 인바운드 및 아웃바운드 정책을 추가합니다.
-
카카오클라우드 콘솔 > Beyond Networking Service > VPC 메뉴로 이동합니다.
-
Security Group 탭에서 [+ Security Group 만들기] 버튼을 클릭합니다.
-
Security Group 이름에
tutorial-nat-sg
를 입력합니다. -
하단의 [+ 추가하기] 버튼을 클릭 후, 인바운드 조건을 아래와 같이 설정합니다.
나의 Public IP 확인하기다음 버튼을 클릭하면 현재 사용 중인 나의 Public IP를 확인할 수 있습니다.
정책 설명 프로토콜 패킷 출발지 포트 번호 inbound http policy TCP 10.0.0.0/16 80 inbound https policy TCP 10.0.0.0/16 443 ssh policy TCP {사용자의 Public IP}/32
22 -
아웃바운드 조건을 아래와 같이 설정합니다.
정책 설명 프로토콜 패킷 목적지 포트 번호 outbound http policy TCP 0.0.0.0/0 80 outbound https policy TCP 0.0.0.0/0 443 outbound DNS policy UDP 169.254.169.253/32 53 outbound DNS policy 2 UDP 10.0.0.2/32 53 -
하단의 [만들기] 버튼을 클릭하여 Security Group을 생성합니다.
Step 3. NAT 인스턴스 생성
NAT 인스턴스를 생성하면 Private 서브넷 내의 인스턴스가 인터넷과 안전하게 통신할 수 있습니다. NAT 인스턴스는 Private 서브넷의 인스턴스가 인터넷으로 트래픽을 보내는 것을 허용지 만, 인터넷으로부터의 직접적인 접근은 차단합니다. 이로써 보안을 강화하고 Private 서브넷 내의 인스턴스들이 필요한 업데이트와 패치를 받을 수 있도록 합니다.
-
카카오클라우드 콘솔 > Beyond Compute Service > Virtual Machine 메뉴로 이동합니다.
-
Instance 탭에서 [Instance 만들기] 버튼을 클릭한 후, 다음과 같이 두 개의 가용 영역에 VM 인스턴스를 생성합니다.
가용 영역별 입력값 kr-central-2-a kr-central-2-b 기본 정보 - 이름: tutorial-nat-instance-a
- 개수:1
- 이름: tutorial-nat-instance-b
- 개수:1
Image Ubuntu 20.04 - 5.4.0-164
⚠️ NVIDIA 유형이 아닌 일반 이미지 선택 이미지Ubuntu 20.04 - 5.4.0-164
⚠️ NVIDIA 유형이 아닌 일반 이미지 선택 이미지Instance 타입 t1i.nano
t1i.nano
Volume Root Volume: 30
Root Volume: 30
Key Pair 키 페어 선택 키 페어 선택 Network - VPC: tutorial
- Subnet:main
ㄴ 가용 영역 kr-central-2-a의 Public 서브넷
- Security Group:tutorial-nat-sg
- VPC: tutorial
- Subnet:tutorial_{VPC_CODE}_sn_1
형식 선택 (10.0.80.0/20)
ㄴ 가용 영역 kr-central-2-b의 Public 서브넷이며,sn_1
으로 끝나는 서브넷 선택
- Security Group:tutorial-nat-sg
-
입력 값을 모두 확인하고 콘솔 하단의 [만들기] 버튼을 클릭하여 VM을 생성합니다.
Step 4. NAT 인스턴스 설정
가용 영역에 생성한 두 개의 NAT 인스턴스(tutorial-nat-instance-a와 tutorial-nat-instance-b)에 인터넷과의 통신을 위한 Public IP를 부여하고 NAT 설정을 진행합니다.
① tutorial-nat-instance-a
-
VM > Instance 탭에서 위에서 생성했던
tutorial-nat-instance-a
인스턴스를 선택 후, 우측의 [Public IP 연결] 버튼을 클릭합니다. -
Public IP 연결 설정 팝업창이 뜨면, Public IP 할당에서 새로운 Public IP를 생성하고 자동으로 할당을 선택하고 [확인] 버튼을 클릭합니다. 연결된 Public IP는 Network 탭에서 확인할 수 있습니다.
-
로컬 환경에서 터미널 실행 후,
cd
명령어를 사용하여 Key Pair 파일을 다운로드받은 폴더로 이동합니다.- 프라이빗 키 파일을 최초 생성해서 사용했다면, 기본적으로 다운로드 폴더에 저장됩니다. (
cd ~/Downloads
)
- 프라이빗 키 파일을 최초 생성해서 사용했다면, 기본적으로 다운로드 폴더에 저장됩니다. (
-
Key Pair 파일을 다운로드받은 폴더로 이동하여, SSH 접근을 합니다.
SSH 접근chmod 400 {PRIVATE_KEY}.pem # 읽기 권한 부여
ssh -i {PRIVATE_KEY}.pem ubuntu@{NAT_INSTANCE_PUBLIC_IP}항목 설명 {PRIVATE_KEY}
프라이빗 키 파일 이름 {NAT_INSTANCE_PUBLIC_IP}
VM > Instance 탭에서 생성한 tutorial-nat-instance-a
인스턴스 클릭 후, Network 탭에서 확인 가능 -
다음 명령어를 통해 NAT 인스턴스 설정을 수행합니다. 중간에 동의가 필요하면
Yes
를 입력 또는 엔터키를 누릅니다.- 이 명령어는 NAT 인스턴스 설정을 자동으로 수행합니다. 구체적으로, 사용 가능한 네트워크 인터페이스를 자동으로 식별하여 선택하고, IP 포워딩을 활성화하며, 선택된 인터페이스에 대한 네트워크 트래픽 마스커레이딩을 자동 구성합니다.
NAT 인스턴스 설정sudo apt-get update -y
LINE=$(grep 'net.ipv4.ip_forward=' /etc/sysctl.conf)
sudo sed -i "s/${LINE}/net.ipv4.ip_forward=1/" /etc/sysctl.conf
sudo sysctl -p
INTERFACE=$(ip link | awk -F: '$0 !~ "lo|vir|wl|^[^0-9]"{print $2;getline}')
sudo /sbin/iptables -t nat -A POSTROUTING -o ${INTERFACE} -j MASQUERADE
sudo apt-get install -y iptables-persistent -
아래 창이 팝업하면, Yes가 선택되어있는 상태에서 엔터키를 누릅니다.
-
결과 화면은 다음과 같습니다.
② tutorial-nat-instance-b
tutorial-nat-instance-a를 참고하여, tutorial-nat-instance-b에 대해서도 동일하게 위의 작업을 반복합니다.
Step 5. 출발지/목적지 확인 변경 설정
인스턴스는 기본적으로 출발지/목적지를 확인하며 본인을 목적지로 하는 트래픽만을 수신합니다. 그러나 NAT Instance는 트래픽의 출발지와 목적지가 자신이 아니어도 트래픽을 보내고 받을 수 있어야 합니다. 이 경우, 인스턴스의 출발지/목적지 확인 변경 기능을 통해 생성한 인스턴스를 NAT 인스턴스 용도로 설정할 수 있습니다.
-
카카오클라우드 콘솔 > Beyond Compute Service > Virtual Machine 메뉴로 이동합니다.
-
Instance 탭에서 인스턴스
tutorial-nat-instance-a
의 [더 보기] 아이콘 > 출발지/목적지 확인 변경을 선택합니다. -
출발지/목적지 확인 변경 팝업창에서
출발지/목적지 확인 중지
를 선택 후 [완료] 버튼을 클릭합니다. -
tutorial-nat-instance-b
에 대해서도 위의 1번 ~ 3번 과정을 동일하게 수행하고,출발지/목적지 확인 중지
를 선택 후 [완료] 버튼을 클릭합니다.
Step 6. Route Table 생성 및 설정
Route Table을 통해 서브넷 내부에서 특정 목적지를 향하는 요청에 대해 라우트 규칙을 설정할 수 있습니다. 이를 통해 Private 서브넷에서 외부로 나가는 요청은 해당 서브넷이 속한 가용 영역의 NAT 인스턴스를 통해 NAT 통신하도록 설정합니다.
-
카카오클라우드 콘솔 > Beyond Networking Service > VPC 메뉴로 이동합니다.
-
Route Table 탭에서 [Route Table 만들기] 버튼을 클릭한 후, 다음과 같이 두 개의 가용 영역에 Route Table를 생성합니다.
가용 영역별 설정값 kr-central-2-a kr-central-2-b Route Table 이름 tutorial-priv-a-rt
tutorial-priv-b-rt
VPC tutorial
tutorial
-
생성한 Route Table의 이름을 클릭하여 Route Table의 상세페이지에 접속합니다.
-
Route 탭에서 [+ Route 추가] 버튼을 클릭합니다.
-
가용 영역마다 0.0.0.0/0을 목적지로 하는 요청을 가용 영역 내의 NAT 인스턴스로 라우팅하도록 설정합니다. 인스턴스의 ID는 VM > Instance 탭에서 확인할 수 있습니다.
라우트 테이블별 설정값 tutorial-priv-a-rt tutorial-priv-b-rt Target 타입 Instance
Instance
Target 인스턴스 {tutorial-nat-instance-a-id}
{tutorial-nat-instance-b-id}
목적지 0.0.0.0/0 0.0.0.0/0 -
각 라우트 테이블의 Association 탭에서 [+ Association 설정] 버튼을 클릭하고, 각 가용 영역에 해당하는 Private 서브넷이 적용되도록 [연결] 버튼을 클릭합니다.
라우트 테이블: tutorial-priv-a-rt
다음 정보를 확인하여 Association을 설정합니다.
Subnet IP CIDR 블록 Route Table tutorial_ {VPC_ID}
_sn_510.0.64.0/20
tutorial_ {VPC_ID}
_private_rttutorial_ {VPC_ID}
_sn_410.0.48.0/20
tutorial_ {VPC_ID}
_private_rttutorial_ {VPC_ID}
_sn_310.0.32.0/20
tutorial_ {VPC_ID}
_private_rttutorial_ {VPC_ID}
_sn_210.0.16.0/20
tutorial_ {VPC_ID}
_private_rt라우트 테이블: tutorial-priv-b-rt
다음 정보를 확인하여 Association을 설정합니다.
Subnet IP CIDR 블록 Route Table tutorial_ {VPC_ID}
_sn_910.0.144.0/20
tutorial_ {VPC_ID}
_private_rttutorial_ {VPC_ID}
_sn_810.0.128.0/20
tutorial_ {VPC_ID}
_private_rttutorial_ {VPC_ID}
_sn_710.0.112.0/20
tutorial_ {VPC_ID}
_private_rttutorial_ {VPC_ID}
_sn_610.0.96.0/20
tutorial_ {VPC_ID}
_private_rt
Step 7. VPC Topology 확인
VPC의 Topology 탭에서 VPC가 적절히 구성되었는지 확인합니다.
VPC Topology 확인
결과 확인하기
결과를 확인하기 위해 카카오클라우드 VM에서 Bastion 호스트를 포함한 3개의 VM 인스턴스를 생성합니다. 그 후, Private 서브넷에서 생성한 VM의 Public IP와 NAT 인스턴스의 Public IP가 서로 일치하는지 확인하여 결과를 확인합니다.
- Bastion 호스트는 외부에서 내부 리소스에 안전하게 접근을 도와주는 게이트웨이 역할을 합니다.
Step 1. Bastion 인스턴스를 위한 Security Group 생성
다음과 같이 Bastion 인스턴스에 보안 그룹을 생성하고, 인바운드 정책을 설정합니다.
-
VPC 메뉴에서 Security Group 탭을 선택합니다.
-
[Security Group 만들기] 버튼을 클릭합니다.
-
Security Group 만들기 팝업창에서, Security Group 이름에
sg-bastion
을 입력합니다. -
인바운드 정책 탭에 다음의 정책을 모두 추가 후 [만들기] 버튼을 클릭합니다.
나의 Public IP 확인하기다음 버튼을 클릭하면 현재 사용 중인 나의 Public IP를 확인할 수 있습니다.
인바운드 정책 프로토콜 패킷 출발지 포트 번호 bastion inbound policy 1 TCP {사용자의 Public IP}/32
10000-10010 bastion inbound policy 2 TCP {사용자의 Public IP}/32
81 bastion ssh policy TCP {사용자의 Public IP}/32
22 -
아웃바운드 정책 탭에 다음의 정책을 추가 후 [만들기] 버튼을 클릭합니다.
아웃바운드 정책 프로토콜 패킷 목적지 포트 번호 bastion outbound policy ALL 0.0.0.0/0 ALL
Step 2. Bastion 인스턴스 생성 및 Security Group 설정
-
Beyond Compute Service > Virtual Machine > Instance 탭에서 [Instance 만들기] 버튼을 클릭한 후, 아래 목록의 필요한 Bastion 인스턴스를 생성합니다.
항목 설명 기본 정보 - 이름: tutorial-bastion
- 개수:1
Image Ubuntu 20.04 - 5.4.0-164
⚠️ NVIDIA 이미지가 아닌 일반 이미지 선택Instance 타입 t1i.nano
Volume Root Volume: 30
Key Pair 상기 작업에서 사용했던 기존 키 페어 사용 Network - VPC: tutorial
- Subnet:main
- Security Group:sg-bastion
(현재 설정 그대로 사용) -
VPC 메뉴에서 Security Group 탭을 선택합니다.
-
[Security Group 만들기] 버튼을 클릭합니다.
-
Security Group 만들기 팝업창에서, Security Group 이름에
private-vm-sg
을 입력합니다. -
인바운드 정책 탭에 다음의 정책을 모두 추가 후 [만들기] 버튼을 클릭합니다.
- 내부 호스트로 들어오는 트래픽은 Bastion을 통해 전달됩니다.
az-a-vm
,az-b-vm
호스트가 Bastion에서 보낸 트래픽을 받을 수 있는지 카카오클라우드 콘솔 내 Security Group을 확인해야 합니다. 인바운드 정책에 아래의 내용이 포함되어 있는지 확인하고 추가합니다.
인바운드 정책 프로토콜 패킷 출발지(Source) 포트 번호 private-vm inbound policy TCP {BASTION_PRIVATE_IP}/32
-tutorial-bastion
의 Private IP로, VM > Instance 탭에서 확인22 - 내부 호스트로 들어오는 트래픽은 Bastion을 통해 전달됩니다.
-
아웃바운드 정책 탭에 다음의 정책을 추가 후 [만들기] 버 튼을 클릭합니다.
아웃바운드 정책 프로토콜 패킷 목적지 포트 번호 private-vm outbound policy ALL 0.0.0.0/0 ALL
Step 3. 가용 영역별 인스턴스 생성
Beyond Compute Service > Virtual Machine > Instance 탭에서 [Instance 만들기] 버튼을 클릭한 후, 다음과 같이 두 개의 가용 영역에 배치할 VM 인스턴스를 생성합니다.
가용 영역별 설정값 | kr-central-2-a | kr-central-2-b |
---|---|---|
기본 정보 | - 이름: az-a-vm - 개수: 1 | - 이름: az-b-vm - 개수: 1 |
Image | Ubuntu 20.04 - 5.4.0-164 ⚠️ NVIDIA 이미지가 아닌 일반 이미지 선택 | Ubuntu 20.04 - 5.4.0-164 ⚠️ NVIDIA 이미지가 아닌 일반 이미지 선택 |
Instance 타입 | t1i.nano | t1i.nano |
Volume | Root Volume: 30 | Root Volume: 30 |
Key Pair | 상기 작업에서 사용했던 기존 키 페어 사용 | 상기 작업에서 사용했던 기존 키 페어 사용 |
Network | - VPC: tutorial - Subnet: tutorial_{VPC_ID}_sn_2 (10.0.16.0/20) - Security Group: private-vm-sg | - VPC: tutorial - Subnet: tutorial_{VPC_ID}_sn_6 (10.0.96.0/20)- Security Group: private-vm-sg |
Step 4. Bastion 인스턴스에 Public IP 연결
Bastion 호스트는 외부에서 접근할 수 있어야 하므로, 다음과 같이 Public IP를 설정합니다.
- VM > Instance 탭에서 위에서 생성했던
tutorial-bastion
인스턴스를 선택 후, 우측의 [Public IP 연결] 버튼을 클릭합니다. - Public IP 연결 설정 팝업창이 뜨면, Public IP 할당에서 새로운 Public IP를 생성하고 자동으로 할당을 선택하고 [확인] 버튼을 클릭합니다.
- 연결된 Public IP는 Network 탭에서 확인할 수 있습니다.
Step 5. Bastion 호스트 설정
-
로컬 환경에서 터미널 실행 후,
cd
명령어를 사용하여 Key Pair 파일을 다운로드받은 폴더로 이동합니다. -
다음 명령어를 실행하여 SSH에 접근합니다.
SSH 접근chmod 400 ${PRIVATE_KEY}.pem # 읽기 권한 부여
ssh -i ${PRIVATE_KEY}.pem ubuntu@${BASTION_PUBLIC_IP}항목 설명 ${PRIVATE_KEY}
키 파일 이름 ${BASTION_PUBLIC_IP}
VM > Instance 탭에서 생성한 tutorial-bastion
인스턴 스 클릭 후, Network 탭에서 확인 가능안내키 페어 파일 권한 문제로
bad permissions
오류가 발생할 경우,sudo
명령어를 추가하여 문제를 해결할 수 있습니다. -
nginx-proxy-manager를 사용하여 Bastion 호스트를 구성하기 위해, SSH로 Bastion 호스트에 접속하고 아래 명령어를 실행하여 프로비저닝 합니다.
Bastion 호스트 구성sudo curl -o /tmp/init-bastion.sh https://raw.githubusercontent.com/kakaoenterprise/kc-handson-config/vm-3tier/init-bastion.sh
bash /tmp/init-bastion.sh -
위 작업이 완료되면 nginx-proxy-manager이 실행됩니다. 사용자 로컬 환경에서 브라우저를 열고, 아래 주소를 입력하여 관리 페이지에 접속합니다.
-
http://
${BASTION_PUBLIC_IP}
:81/login
- 아이디 :
admin@example.com
- 비밀번호 :
changeme
-
-
Dashboard > Streams에서 가용 영역별(
az-a-vm
,az-b-vm
) 호스트의 스트림을 각각 등록합니다. 각 가용 영역별 인스턴스의 Private IP는 VM > Instacne 탭에서 해당 인스턴스를 클릭 후, Network 탭에서 확인할 수 있습니다.가용 영역별 설정값 az-a-vm az-b-vm Incoming Port 10000
10001
Forward Host az-a-vm의 Private IP
az-b-vm의 Private IP
Forward Port 22
22
Forwarding Protocol TCP
TCP
-
Key Pair 파일을 다운로드받은 폴더로 이동 후, 사용자 로컬 환경에서 각 호스트로 접근이 가능한지 확인합니다. 앞에서 진행한 포워딩 정보를 바탕으로 포트에 맞게 매핑해준 내부 호스트로 연결을 진행합니다.
호스트별 접근 확인* vm-a
ssh -i ${PRIVATE_KEY}.pem ubuntu@${BASTION_PUBLIC_IP} -p 10000
* vm-b
ssh -i ${PRIVATE_KEY}.pem ubuntu@${BASTION_PUBLIC_IP} -p 10001
Step 6. IP 일치 여부 확인
아래 명령어를 실행하면, 외부 통신에서 사용 중인 Public IP를 확인할 수 있습니다. 해당 IP가 NAT 인스턴스의 Public IP와 일치한다면, 위 작업이 성공적으로 수행된 것입니다. NAT 인스턴스의 Public IP는 VM > Instace 탭에서 tutorial-nat-instance-a
/ tutorial-nat-instance-b
를 클릭 후, Network탭에서 확인할 수 있습니다.
curl https://ifconfig.me/ip
# 결과 예제: ***.***.***.***