본문으로 건너뛰기

다중 가용 영역에서 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 및 서브넷을 생성합니다.

  1. 카카오클라우드 콘솔 > Beyond Networking Service > VPC 메뉴로 이동합니다.

  2. VPC 탭에서 [VPC 만들기] 버튼을 클릭한 후, 다음과 같이 VPC 및 Subnet을 생성합니다.

    구분항목설정/입력값
    VPC 정보VPC 이름tutorial
    VPC IP CIDR 블록10.0.0.0/16
    Availability ZoneAZ 개수2
    첫 번째 AZkr-central-2-a
    두 번째 AZkr-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
  3. 하단에 생성되는 다이어그램을 확인 후, [만들기] 버튼을 클릭합니다.

    • Subnet의 상태는 Pending Create > Pending Update > Active 순서로로 변경됩니다. Active 상태가 되어야 다음 단계를 진행할 수 있습니다.
    • 생성하는데 5 ~ 10분 정도의 소요 시간이 있을 수 있습니다.

Step 2. Security Group 생성

VPC에서 VM을 실행 시 해당 VM에 대한 보안을 강화하기 위해, 다음과 같이 Security Group을 생성하고 인바운드 및 아웃바운드 정책을 추가합니다.

  1. 카카오클라우드 콘솔 > Beyond Networking Service > VPC 메뉴로 이동합니다.

  2. Security Group 탭에서 [+ Security Group 만들기] 버튼을 클릭합니다.

  3. Security Group 이름tutorial-nat-sg를 입력합니다.

  4. 하단의 [+ 추가하기] 버튼을 클릭 후, 인바운드 조건을 아래와 같이 설정합니다.

    나의 Public IP 확인하기

    다음 버튼을 클릭하면 현재 사용 중인 나의 Public IP를 확인할 수 있습니다.

    정책 설명프로토콜패킷 출발지포트 번호
    inbound http policyTCP   10.0.0.0/1680
    inbound https policyTCP10.0.0.0/16443
    ssh policyTCP{사용자의 Public IP}/3222
  5. 아웃바운드 조건을 아래와 같이 설정합니다.

    정책 설명프로토콜패킷 목적지포트 번호
    outbound http policyTCP   0.0.0.0/0  80
    outbound https policyTCP0.0.0.0/0443
    outbound DNS policyUDP169.254.169.253/3253
    outbound DNS policy 2UDP10.0.0.2/3253
  6. 하단의 [만들기] 버튼을 클릭하여 Security Group을 생성합니다.

Step 3. NAT 인스턴스 생성

NAT 인스턴스를 생성하면 Private 서브넷 내의 인스턴스가 인터넷과 안전하게 통신할 수 있습니다. NAT 인스턴스는 Private 서브넷의 인스턴스가 인터넷으로 트래픽을 보내는 것을 허용지만, 인터넷으로부터의 직접적인 접근은 차단합니다. 이로써 보안을 강화하고 Private 서브넷 내의 인스턴스들이 필요한 업데이트와 패치를 받을 수 있도록 합니다.

  1. 카카오클라우드 콘솔 > Beyond Compute Service > Virtual Machine 메뉴로 이동합니다.

  2. Instance 탭에서 [Instance 만들기] 버튼을 클릭한 후, 다음과 같이 두 개의 가용 영역에 VM 인스턴스를 생성합니다.

    가용 영역별 입력값kr-central-2-akr-central-2-b
    기본 정보- 이름: tutorial-nat-instance-a
    - 개수: 1
    - 이름: tutorial-nat-instance-b
    - 개수: 1
    ImageUbuntu 20.04 - 5.4.0-164
    ⚠️ NVIDIA 유형이 아닌 일반 이미지 선택 이미지
    Ubuntu 20.04 - 5.4.0-164
    ⚠️ NVIDIA 유형이 아닌 일반 이미지 선택 이미지
    Instance 타입       t1i.nanot1i.nano
    VolumeRoot Volume: 30Root 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
  3. 입력 값을 모두 확인하고 콘솔 하단의 [만들기] 버튼을 클릭하여 VM을 생성합니다.

Step 4. NAT 인스턴스 설정

가용 영역에 생성한 두 개의 NAT 인스턴스(tutorial-nat-instance-atutorial-nat-instance-b)에 인터넷과의 통신을 위한 Public IP를 부여하고 NAT 설정을 진행합니다.

① tutorial-nat-instance-a
  1. VM > Instance 탭에서 위에서 생성했던 tutorial-nat-instance-a 인스턴스를 선택 후, 우측의 [Public IP 연결] 버튼을 클릭합니다.

  2. Public IP 연결 설정 팝업창이 뜨면, Public IP 할당에서 새로운 Public IP를 생성하고 자동으로 할당을 선택하고 [확인] 버튼을 클릭합니다. 연결된 Public IP는 Network 탭에서 확인할 수 있습니다.

  3. 로컬 환경에서 터미널 실행 후, cd 명령어를 사용하여 Key Pair 파일을 다운로드받은 폴더로 이동합니다.

    • 프라이빗 키 파일을 최초 생성해서 사용했다면, 기본적으로 다운로드 폴더에 저장됩니다. (cd ~/Downloads)
  4. 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 탭에서 확인 가능
  5. 다음 명령어를 통해 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
  6. 아래 창이 팝업하면, Yes가 선택되어있는 상태에서 엔터키를 누릅니다. 이미지

  7. 결과 화면은 다음과 같습니다.
    이미지

② tutorial-nat-instance-b

tutorial-nat-instance-a를 참고하여, tutorial-nat-instance-b에 대해서도 동일하게 위의 작업을 반복합니다.



Step 5. 출발지/목적지 확인 변경 설정

인스턴스는 기본적으로 출발지/목적지를 확인하며 본인을 목적지로 하는 트래픽만을 수신합니다. 그러나 NAT Instance는 트래픽의 출발지와 목적지가 자신이 아니어도 트래픽을 보내고 받을 수 있어야 합니다. 이 경우, 인스턴스의 출발지/목적지 확인 변경 기능을 통해 생성한 인스턴스를 NAT 인스턴스 용도로 설정할 수 있습니다.

  1. 카카오클라우드 콘솔 > Beyond Compute Service > Virtual Machine 메뉴로 이동합니다.

  2. Instance 탭에서 인스턴스 tutorial-nat-instance-a의 [더 보기] 아이콘 > 출발지/목적지 확인 변경을 선택합니다.

  3. 출발지/목적지 확인 변경 팝업창에서 출발지/목적지 확인 중지를 선택 후 [완료] 버튼을 클릭합니다.

  4. tutorial-nat-instance-b에 대해서도 위의 1번 ~ 3번 과정을 동일하게 수행하고, 출발지/목적지 확인 중지를 선택 후 [완료] 버튼을 클릭합니다.

Step 6. Route Table 생성 및 설정

Route Table을 통해 서브넷 내부에서 특정 목적지를 향하는 요청에 대해 라우트 규칙을 설정할 수 있습니다. 이를 통해 Private 서브넷에서 외부로 나가는 요청은 해당 서브넷이 속한 가용 영역의 NAT 인스턴스를 통해 NAT 통신하도록 설정합니다.

  1. 카카오클라우드 콘솔 > Beyond Networking Service > VPC 메뉴로 이동합니다.

  2. Route Table 탭에서 [Route Table 만들기] 버튼을 클릭한 후, 다음과 같이 두 개의 가용 영역에 Route Table를 생성합니다.

    가용 영역별 설정값kr-central-2-akr-central-2-b
    Route Table 이름  tutorial-priv-a-rttutorial-priv-b-rt
    VPCtutorialtutorial
  3. 생성한 Route Table의 이름을 클릭하여 Route Table의 상세페이지에 접속합니다.

  4. Route 탭에서 [+ Route 추가] 버튼을 클릭합니다.

  5. 가용 영역마다 0.0.0.0/0을 목적지로 하는 요청을 가용 영역 내의 NAT 인스턴스로 라우팅하도록 설정합니다. 인스턴스의 ID는 VM > Instance 탭에서 확인할 수 있습니다.

    라우트 테이블별 설정값tutorial-priv-a-rttutorial-priv-b-rt
    Target 타입InstanceInstance
    Target 인스턴스    {tutorial-nat-instance-a-id}{tutorial-nat-instance-b-id}
    목적지0.0.0.0/00.0.0.0/0
  6. 각 라우트 테이블의 Association 탭에서 [+ Association 설정] 버튼을 클릭하고, 각 가용 영역에 해당하는 Private 서브넷이 적용되도록 [연결] 버튼을 클릭합니다.

    라우트 테이블: tutorial-priv-a-rt

    다음 정보를 확인하여 Association을 설정합니다.

    SubnetIP CIDR 블록Route Table
    tutorial_{VPC_ID}_sn_510.0.64.0/20tutorial_{VPC_ID}_private_rt
    tutorial_{VPC_ID}_sn_410.0.48.0/20tutorial_{VPC_ID}_private_rt
    tutorial_{VPC_ID}_sn_310.0.32.0/20tutorial_{VPC_ID}_private_rt
    tutorial_{VPC_ID}_sn_210.0.16.0/20tutorial_{VPC_ID}_private_rt
    라우트 테이블: tutorial-priv-b-rt

    다음 정보를 확인하여 Association을 설정합니다.

    SubnetIP CIDR 블록Route Table
    tutorial_{VPC_ID}_sn_910.0.144.0/20tutorial_{VPC_ID}_private_rt
    tutorial_{VPC_ID}_sn_810.0.128.0/20tutorial_{VPC_ID}_private_rt
    tutorial_{VPC_ID}_sn_710.0.112.0/20tutorial_{VPC_ID}_private_rt
    tutorial_{VPC_ID}_sn_610.0.96.0/20tutorial_{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 인스턴스에 Security Group을 생성하고, 인바운드 정책을 설정합니다.

  1. VPC 메뉴에서 Security Group 탭을 선택합니다.

  2. [Security Group 만들기] 버튼을 클릭합니다.

  3. Security Group 만들기 팝업창에서, Security Group 이름에 sg-bastion을 입력합니다.

  4. 인바운드 정책 탭에 다음의 정책을 모두 추가 후 [만들기] 버튼을 클릭합니다.

    나의 Public IP 확인하기

    다음 버튼을 클릭하면 현재 사용 중인 나의 Public IP를 확인할 수 있습니다.

    인바운드 정책프로토콜패킷 출발지포트 번호
    bastion inbound policy 1TCP   {사용자의 Public IP}/3210000-10010
    bastion inbound policy 2TCP{사용자의 Public IP}/3281
    bastion ssh policyTCP{사용자의 Public IP}/3222
  5. 아웃바운드 정책 탭에 다음의 정책을 추가 후 [만들기] 버튼을 클릭합니다.

    아웃바운드 정책프로토콜패킷 목적지포트 번호
    bastion outbound policyALL   0.0.0.0/0  ALL

Step 2. Bastion 인스턴스 생성 및 Security Group 설정

  1. Beyond Compute Service > Virtual Machine > Instance 탭에서 [Instance 만들기] 버튼을 클릭한 후, 아래 목록의 필요한 Bastion 인스턴스를 생성합니다.

    항목설명
    기본 정보- 이름: tutorial-bastion
    - 개수: 1
    ImageUbuntu 20.04 - 5.4.0-164
    ⚠️ NVIDIA 이미지가 아닌 일반 이미지 선택
    Instance 타입t1i.nano
    VolumeRoot Volume: 30
    Key Pair상기 작업에서 사용했던 기존 키 페어 사용
    Network- VPC: tutorial
    - Subnet: main
    - Security Group: sg-bastion (현재 설정 그대로 사용)
  2. VPC 메뉴에서 Security Group 탭을 선택합니다.

  3. [Security Group 만들기] 버튼을 클릭합니다.

  4. Security Group 만들기 팝업창에서, Security Group 이름에 private-vm-sg을 입력합니다.

  5. 인바운드 정책 탭에 다음의 정책을 모두 추가 후 [만들기] 버튼을 클릭합니다.

    • 내부 호스트로 들어오는 트래픽은 Bastion을 통해 전달됩니다. az-a-vm, az-b-vm 호스트가 Bastion에서 보낸 트래픽을 받을 수 있는지 카카오클라우드 콘솔 내 Security Group을 확인해야 합니다. 인바운드 정책에 아래의 내용이 포함되어 있는지 확인하고 추가합니다.
    인바운드 정책프로토콜패킷 출발지(Source)포트 번호
    private-vm inbound policyTCP   {BASTION_PRIVATE_IP}/32
    - tutorial-bastion의 Private IP로, VM > Instance 탭에서 확인
    22
  6. 아웃바운드 정책 탭에 다음의 정책을 추가 후 [만들기] 버튼을 클릭합니다.

    아웃바운드 정책프로토콜패킷 목적지포트 번호
    private-vm outbound policyALL   0.0.0.0/0   ALL

Step 3. 가용 영역별 인스턴스 생성

Beyond Compute Service > Virtual Machine > Instance 탭에서 [Instance 만들기] 버튼을 클릭한 후, 다음과 같이 두 개의 가용 영역에 배치할 VM 인스턴스를 생성합니다.

가용 영역별 설정값kr-central-2-akr-central-2-b
기본 정보- 이름: az-a-vm
- 개수: 1
- 이름: az-b-vm
- 개수: 1
ImageUbuntu 20.04 - 5.4.0-164
⚠️ NVIDIA 이미지가 아닌 일반 이미지 선택
Ubuntu 20.04 - 5.4.0-164
⚠️ NVIDIA 이미지가 아닌 일반 이미지 선택
Instance 타입       t1i.nanot1i.nano
VolumeRoot Volume: 30Root 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를 설정합니다.

  1. VM > Instance 탭에서 위에서 생성했던 tutorial-bastion 인스턴스를 선택 후, 우측의 [Public IP 연결] 버튼을 클릭합니다.
  2. Public IP 연결 설정 팝업창이 뜨면, Public IP 할당에서 새로운 Public IP를 생성하고 자동으로 할당을 선택하고 [확인] 버튼을 클릭합니다.
    • 연결된 Public IP는 Network 탭에서 확인할 수 있습니다.

Step 5. Bastion 호스트 설정

  1. 로컬 환경에서 터미널 실행 후, cd 명령어를 사용하여 Key Pair 파일을 다운로드받은 폴더로 이동합니다.

  2. 다음 명령어를 실행하여 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 명령어를 추가하여 문제를 해결할 수 있습니다.

  3. 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
  4. 위 작업이 완료되면 nginx-proxy-manager이 실행됩니다. 사용자 로컬 환경에서 브라우저를 열고, 아래 주소를 입력하여 관리 페이지에 접속합니다.

    • http://${BASTION_PUBLIC_IP}:81/login

    • 아이디 : admin@example.com
    • 비밀번호 : changeme
  5. Dashboard > Streams에서 가용 영역별(az-a-vm, az-b-vm) 호스트의 스트림을 각각 등록합니다. 각 가용 영역별 인스턴스의 Private IP는 VM > Instacne 탭에서 해당 인스턴스를 클릭 후, Network 탭에서 확인할 수 있습니다.

    가용 영역별 설정값az-a-vmaz-b-vm
    Incoming Port1000010001
    Forward Hostaz-a-vm의 Private IPaz-b-vm의 Private IP
    Forward Port2222
    Forwarding ProtocolTCPTCP
  6. 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탭에서 확인할 수 있습니다.

IP 일치 여부 확인
curl https://ifconfig.me/ip
# 결과 예제: ***.***.***.***