TheKoguryo's 기술 블로그

Version 2023.02.25

4.1.5 NGINX Ingress Controller에서 클라이언트 IP 얻기(OCI Network Load Balancer)

Nginx Ingress Controller를 사용할 때, Pod에 있는 애플리케이션에서 모니터링 등을 위해 실 Client IP를 확인 할 필요가 있습니다. 하지만, 클라이언트의 요청은 Nginx Ingress Controller가 사용하는 OCI Load Balancer를 거쳐 오기 때문에, 실제 Client IP가 아닌, Load Balancer IP가 찍히게 됩니다. 여기서는 실제 Client IP를 얻기 위한 방법을 알아봅니다.

기본 설치 상태에서 애플리케이션 로그 확인하기

  1. NGINX Ingress Controller 디폴트 상태로 설치 합니다.

  2. 테스트 앱을 설치합니다.

  3. 인그레스 주소를 확인하고, 접속합니다.

    $ kubectl get ingress
    NAME                 CLASS    HOSTS   ADDRESS          PORTS   AGE
    ingress-path-basic   <none>   *       146.56.xxx.xxx   80      21m
    
  4. 테스트 앱을 브라우저로 접속합니다.

    예) http://146.56.xxx.xxx/blue

  5. 애플리케이션 로그를 확인합니다.

    예시에서는 클라이언트 주소가 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"
    
  6. 테스트에서 보듯이, 기본 Nginx Ingress Controller 설치상태에서는 애플리케이션 Pod에서 찍히는 Client IP는 실제 클라이언트의 IP가 아님을 알 수 있습니다.

클라이언트 IP를 얻기 위해 관련 설정하기

  1. NGINX Ingress Controller 설치 파일을 다운로드 합니다.

    wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml
    
  2. 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
      ...
      
  3. 변경한 설정파일로 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
          ...
        
  4. Security Rule을 설정합니다.

    • Load Balancer에서 Worker Node(10.0.10.0/24)으로 접근할 수 있도록 Service Subnet의 Security List에 다음 규칙을 추가합니다.

      • Security List 이름: 예) oke-svclbseclist-quick-~~~~

      • 추가할 Egress Rule

        StatelessDestinationIP ProtocolSource Port RangeDestination Port RangeType and CodeAllowsDescription
        No10.0.10.0/24TCPAll30000-32767TCP 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

        StatelessSourceIP ProtocolSource Port RangeDestination Port RangeType and CodeAllowsDescription
        No0.0.0.0/0TCPAll30000-32767TCP traffic for ports: 30000-32767
  5. 웹브라우저에서 관련 사이트를 통해, 자신의 Public IP를 확인합니다.

    image-20220902230229865

  6. 테스트 앱을 브라우저로 접속합니다.

    예) http://146.56.xxx.xxx/blue

    image-20220902230453550

  7. 애플리케이션 로그를 확인합니다.

    예시에서는 클라이언트 주소(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"
    
  8. 테스트 결과와 같이 OCI 문서에 따라 Client IP를 보존하기 위한 관련 설정을 하면, 애플리케이션 Pod에서 실제 Client IP을 확인할 수 있습니다.



이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.

Last updated on 2 Sep 2022