1.2.2.2.6.2 OCI Network Load Balancer 기반 NGINX Ingress Controller에서 클라이언트 IP 얻기
Nginx Ingress Controller를 사용할 때, Pod에 있는 애플리케이션에서 모니터링 등을 위해 실 Client IP를 확인 할 필요가 있습니다. 하지만, 클라이언트의 요청은 Nginx Ingress Controller가 사용하는 OCI Network Load Balancer를 거쳐 오는 경우에도 실제 Client IP를 얻기 위한 방법을 알아봅니다.
-
참고 문서
기본 설치 상태에서 확인하기
기본 설치 상태에서 애플리케이션 로그 확인하기
-
인그레스 주소를 확인하고, 접속합니다.
$ kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-path-basic nginx * 10.0.20.182,152.xx.xxx.xxx 80 10h
-
웹브라우저에서 관련 사이트를 통해, 자신의 Public IP를 확인합니다.
-
테스트 앱을 브라우저로 접속합니다.
-
애플리케이션 로그를 확인합니다.
예시에서는 클라이언트 주소(X-Forwarded-For)가 14.45.121.214로 앞서 확인한 나의 작업 PC의 Public IP가 나오는 것을 확인할 수 있습니다.
$ kubectl logs -lapp=nginx-blue -f 10.244.1.5 - - [02/Jul/2023:01:54:07 +0000] "GET /blue HTTP/1.1" 200 7270 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" "14.45.121.214"
관린설정 확인
-
Client IP를 보존하기 위해 다음 설정이 필요합니다..
-
Load Balancer 타입을 Network Load Balancer로 설정
oci.oraclecloud.com/load-balancer-type: "nlb"
-
Network Load Balancer의 Client IP 보존 설정
oci-network-load-balancer.oraclecloud.com/is-preserve-source: "true"
-
spec.externalTrafficPolicy을 Local로 지정
externalTrafficPolicy: Local
-
NGINX Ingress Controller 설치시 다운받은 deploy.yaml 파일을 아래와 같이 변경하여 배포하면됩니다.
... --- apiVersion: v1 kind: Service metadata: ... name: ingress-nginx-controller namespace: ingress-nginx annotations: oci.oraclecloud.com/load-balancer-type: "nlb" oci-network-load-balancer.oraclecloud.com/is-preserve-source: "true" spec: externalTrafficPolicy: Local ...
-
-
Nginx Ingress Controller v1.8.0 버전로 2023년 6월 기준 OKE에 설치시에는 위 설정이 기본 적용되어 있습니다.
# 설정하지 않더라도 nlb를 사용하는 경우 디폴트가 true임 oci-network-load-balancer.oraclecloud.com/is-preserve-source: "true" # Nginx Ingress Controller v1.8.0 설치시 다운받은 deploy.yaml에 기본값이 Local임 spec: externalTrafficPolicy: Local
클라이언트 IP가 확인되지 않는 경우
기본 설치 상태에서 애플리케이션 로그 확인하기
-
인그레스 주소를 확인하고, 접속합니다.
$ kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-path-basic <none> * 146.56.xxx.xxx 80 21m
-
테스트 앱을 브라우저로 접속합니다.
-
애플리케이션 로그를 확인합니다.
예시에서는 클라이언트 주소가 10.0.20.21로 나옵니다.
- 10.0.20.x는 Quick Create 모드로 OKE 클러스터를 만든 경우 oke-svclbsubnet의 대역으로, Nginx Ingress Controller와 연동된 Load Balancer의 Private IP입니다.
$ kubectl logs -lapp=nginx-blue -f 10.244.1.3 - - [02/Sep/2022:12:35:39 +0000] "GET /blue HTTP/1.1" 200 7272 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "10.0.20.21"
-
테스트에서 보듯이, 기본 Nginx Ingress Controller 설치상태에서는 애플리케이션 Pod에서 찍히는 Client IP는 실제 클라이언트의 IP가 아님을 알 수 있습니다.
클라이언트 IP를 얻기 위해 관련 설정하기
-
NGINX Ingress Controller 설치 파일을 다운로드 합니다.
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml
-
Client IP를 보존하기 위해 다음 설정을 합니다.
-
Load Balancer 타입을 Network Load Balancer로 설정합니다.
oci.oraclecloud.com/load-balancer-type: "nlb"
-
Network Load Balancer의 Client IP 보존 설정을 합니다.
oci-network-load-balancer.oraclecloud.com/is-preserve-source: "true"
-
spec.externalTrafficPolicy을 Local로 지정합니다.
externalTrafficPolicy: Local
-
다운받은 NGINX Ingress Controller 설치 파일 변경 예시
... --- apiVersion: v1 kind: Service metadata: ... name: ingress-nginx-controller namespace: ingress-nginx annotations: oci.oraclecloud.com/load-balancer-type: "nlb" oci-network-load-balancer.oraclecloud.com/is-preserve-source: "true" spec: externalTrafficPolicy: Local ...
-
-
변경한 설정파일로 NGINX Ingress Controller을 배포합니다.
kubectl apply -f deploy.yaml
-
기존 NGINX Ingress Controller가 있는 경우 삭제 후 재배포합니다. 또한 기존 Nginx Ingress Controller의 Public IP를 그대로 사용하려는 경우 다음을 참조하여 loadBalancerIP 값을 설정합니다.
-
Specifying Reserved Public IP Addresses
apiVersion: v1 kind: Service metadata: ... annotations: oci.oraclecloud.com/load-balancer-type: "nlb" spec: loadBalancerIP: 146.56.xx.xxx type: LoadBalancer ...
-
-
-
Security Rule을 설정합니다.
-
Load Balancer에서 Worker Node(10.0.10.0/24)으로 접근할 수 있도록 Service Subnet의 Security List에 다음 규칙을 추가합니다.
-
Security List 이름: 예) oke-svclbseclist-quick-~~~~
-
추가할 Egress Rule
Stateless Destination IP Protocol Source Port Range Destination Port Range Type and Code Allows Description No 10.0.10.0/24 TCP All 30000-32767 TCP traffic for ports: 30000-32767
-
-
Worker Node(10.0.10.0/24)에서 Load Balancer를 통해 들어오는 요청을, 클라이언트 IP로 접근할 수 있도록 Worker Node Subnet의 Security List에 다음 규칙을 추가합니다.
-
Security List 이름: 예) oke-nodeseclist-quick-~~~~
-
추가할 Ingress Rule
Stateless Source IP Protocol Source Port Range Destination Port Range Type and Code Allows Description No 0.0.0.0/0 TCP All 30000-32767 TCP traffic for ports: 30000-32767
-
-
-
웹브라우저에서 관련 사이트를 통해, 자신의 Public IP를 확인합니다.
-
테스트 앱을 브라우저로 접속합니다.
-
애플리케이션 로그를 확인합니다.
예시에서는 클라이언트 주소(X-Forwarded-For)가 220.117.xxx.x로 앞서 확인한 나의 작업 PC의 Public IP가 나오는 것을 확인할 수 있습니다.
$ kubectl logs -lapp=nginx-blue -f 10.244.1.4 - - [02/Sep/2022:14:03:35 +0000] "GET /blue HTTP/1.1" 200 7272 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36" "220.117.xxx.x"
-
테스트 결과와 같이 OCI 문서에 따라 Client IP를 보존하기 위한 관련 설정을 하면, 애플리케이션 Pod에서 실제 Client IP을 확인할 수 있습니다.
이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.