요구사항
서버 상황
- 배포는 “인스턴스 바꾸기”를 통해서 새로운 인스턴스 이름과 ip를 부여받는 방식으로 운영하고 있다.
- 인스턴스 바꾸기를 통해 인스턴스를 삭제하고 교체하면, 인스턴스의 외부 ip도 인스턴스가 교체될 때마다 달라진다.
문제 상황
- NICE API 요청을 위해 ip 주소가 바뀔 때마다 화이트리스트에 등록을 해야함
- VM인스턴스에서 도는 웹사이트는 WebClient를 통해서 NICE 서버와 http 통신을 한다. 이때, VM 인스턴스의 외부 ip가 HTTP 통신 요청 헤더의 host 필드값으로 들어가게 된다. NICE 측에서는 이 요청값을 통해, 화이트리스트에 등록된 IP인지 아닌지 확인을 한다. ➡️ 따라서 IP를 번거롭게 매번 등록해야 한다. 위험성도 높다.
- 인스턴스 바꾸기를 통해 배포가 될 때마다 외부 ip의 값이 변경되는 상황은 단순히 고정 IP로 해결할 수 없다.
해결방안
NAT Gateway 구축
- 개별 VM에 부여된 외부 IP 모두 제거
- NICE 측에서 VM으로 요청 보내는 상황이 없는 경우에만 사용할 것
Cloud NAT
GCP의 Cloud NAT을 통해 Google Cloud의 특정 리소스를 인터넷/다른 VPC 네트워크에 대한 아웃바운드 연결을 만들 수 있다.
Public NAT
외부 IP 주소가 없는 Google Cloud 리소스가 인터넷과 통신할 수 있도록 한다. 따로 프록시 VM을 사용하지 않고, 게이트웨이를 사용하여 인터넷에 대한 아웃바운드 연결을 만드는 각 VM에 외부 IP 주소 및 소스 포트 집합을 할당한다. 이를 통해 개별 VM이 각각 외부 IP 주소를 갖지 않고, 이그레스 방화벽 규칙에 따라 외부 IP 주소가 없는 VM이 인터넷에서 대상에 엑세스 할 수 있다.
Private NAT
Inter-VPC NAT을 사용하여 Network Connectivity Center와 함께 Virtual Private Cloud 네트워크 간 NAT를 수행한다.
ex. VPC 네트워크의 리소스가 다른 법인이 소유한 VPC 네트워크의 리소스와 통신할 때 서브넷 간 트래픽을 겹치지않는 서브넷으로 라우팅할 때 Private NAT 게이트웨이 구축
Cloud NAT은 결국 분산형/관리형 서비스이다. 프록시 VM이나 어플라이언스를 기반으로 하지 않는다.
Google의 Andromeda 소프트웨어 정의 네트워킹으로 구현된다. (Enter the Andromeda zone - Google Cloud Platform’s latest networking stack)
필자는 요구사항 충족을 위해서 같은 VPC 내의 통신을 다루는 private NAT가 아닌 인터넷 통신을 다루는 public NAT을 구축한다.
Cloud NAT 구축
- IAM 권한, gcloud, VPC가 세팅되었다고 가정
1) Cloud NAT에 할당할 고정 외부 IP 주소 만들기
2) Cloud Router 구축
public NAT을 사용하는 인스턴스와 동일한 리전에 Cloud Router를 만든다. 실제 NAT 정보를 VM 인스턴스에 배치하기 위해서 사용된다. 이 구성을 통해서 리전 내 모든 인스턴스가 Public NAT을 사용할 수 있고, 외부 IP 주소가 NAT 게이트웨이에 자동으로 할당된다.
Cloud NAT이 리전에 대한 Gateway이므로, 한 리전에 NAT 구축 & 외부 IP 주소가 없는 인스턴스를 생성하면 자동으로 이 리전의 인스턴스의 외부 IP는 NAT으로 할당된다.
3) Public NAT 구성 만들기
- Public IP 사용을 위해 NAT 유형은 공개로 설정한다.
- 네트워크와 리전을 NAT을 세팅하고 싶은 목록으로 설정하고, Cloud Router를 만들어 준다. GCP의 NAT은 리전을 기준으로 설정된다.
- VM 인스턴스에 대한 NAT 세팅이므로 엔드포인트 유형은 VM 인스턴스로 설정
- 이전에 생성해둔 정적 외부 IP를 수동으로 할당해준다. (static ip가 필요한 거니까..) 고정 IP 할당은 GCP의 VPC 네트워크 > IP 주소에서 가능하며, 필자는 nat-ip-asia-northeast3이라는 이름을 가진 ip를 생성하고, NAT 게이트웨이에 NAT IP 주소를 할당해주었다.
세부사항 설정을 완료하면 GCP Cloud NAT에 만든 Gateway가 생성되어 있음을 확인할 수 있다.
4) 잘 구축되었는지 확인
curl(client url)
curl은 특정 URL로 데이터를 전송하여 서버에 데이터를 보내거나 가져올 때 사용하는 도구다.
- curl 명령어를 사용하기 위해서 이를 설치해주어야 하는데, 어떤 OS냐에 따라 명령어가 달라진다.
- debian 계열 리눅스 : apt-get
- CentOS, Fedora : yum, dnf
curl 명령어로 http://curlmyip.org/ 로 명령을 보낸다.
이 사이트는 나의 ip를 return해주는 사이트로, curl과 함께 사용했을 때 리턴되는 값이 나의 ip다.
이 값을 NAT IP와 비교하여 같음을 확인해보자!
보안을 위해 IP 주소는 가렸지만, 두 개의 값이 같음을 확인하였고 이렇게 되면 NAT 구축이 마무리가 된다.
((추가)) Cloud NAT workflow
1. 외부 IP 주소가 없는 VM은 NAT Gateway를 통해 인터넷과 통신하기 위해 포트 예약 절차를 따른다.
- 예를 들어, 내부 IP 주소 10.240.0.4로 VM에 64개의 소스 포트 예약하고, NAT IP 주소 192.0.2.50은 64개의 예약되지 않은 포트가 있으므로 게이트웨이는 VM에 대해 이 NAT ip 및 소스 포트 튜플집합을 예약한다. ( 192.0.2.50:34000에서 192.0.2.50:34063으로)
포트 예약 절차
1. Cloud NAT가 NAT을 수행해야 하는 VM 내부 IP 주소를 확인한다. (게이트웨이가 제공하도록 구성된 서브넷 IP 주소 범위를 통해 확인한다.)
- 필요한 경우 VM 인스턴스당 최소 포트를 설정한다.
- 정적 포트 할당(VM 당 최소 포트 수를 미리 지정하는 방식)인 경우, Cloud NAT이 VM 당 최소 포트를 두 값의 최대값으로 조정한다. 여기서 두 값은 ① 지정한 VM 인스턴스당 최소 포트 수 ② 숫자 1,024
- 각 VM에 대해 NAT 소스 IP 주소 및 소스 포트 튜플을 예약한다.
- 사용자가 지정한 VM 인스턴스 당 최소 포트 수보다 크거나 같도록 2의 거듭제곱을 사용하여 할당. (안정성)
2. VM이 TCP 프로토콜을 사용하여 포트 80의 업데이트 서버 203.0.113.1에 패킷을 전송하면, NAT Gateway는 이그레스에 소스 네트워크 주소 변환(SNAT)을 수행하여 요청 패킷의 NAT 소스 IP 주소와 소스 포트를 재작성한다. 수정한 패킷은 VPC Next hop이 기본 인터넷 게이트웨이인 203.0.113.1 대상에 대한 경로가 있는 경우 인터넷으로 전송된다.
3. 업데이트 서버가 응답 패킷을 전송하면 패킷은 NAT Gateway에 정보를 가지고 도착한다.
4. NAT Gateway는 응답 패킷에 DNAT을 수행하여 패킷이 VM에 전달되도록 응답 패킷의 대상 주소와 대상 포트를 재작성한다.
정적 포트 할당과 동적 포트 할당
정적 포트 할당은 VM 당 최소 포트 수를 지정하여(Google Cloud에서 기본값 제공) 모든 VM에 동일한 포트 수를 할당하는 방식이다. 모든 VM의 이그레스 사용량이 비슷한 경우에 효율적이며 Public NAT에 기본적으로 사용 설정한다.
동적 포트 할당은 기본적으로 Private NAT에 사용되며, VM 별로 사용하는 포트의 수가 차이가 날 때 사용한다. VM 인스턴스당 최대 포트 수까지 추가 포트를 반복적으로 요청할 수 있다. 만약 포트 사용량이 크게 감소하면 포트가 할당 취소되고 동일한 NAT 게이트웨이를 사용하는 다른 VM에 할당할 수 있는 상태가 됨으로써 유동적으로 포트를 할당할 수 있다.
'DevOps > DevOps' 카테고리의 다른 글
[GCP] Cloud Logging 에러 사항을 메일로 모니터링하기 (0) | 2024.02.14 |
---|---|
[GCP] Google Cloud Load Balancer, GCP 로드밸런서 구축 | Cloud NAT와 로드밸런서 | Cloudflare (0) | 2024.01.29 |
[GCP] Instance Template과 Instance Group을 통한 VM 서버 생성과 블루-그린 배포 (0) | 2024.01.29 |
[GCP] Cloud Build 커밋/푸시없이 트리거 실행하기 (0) | 2024.01.15 |
[Redis] Redis 4편. 운영 방식과 호스팅 (0) | 2024.01.08 |