ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Nginx Proxy Server가 이상하다!
    Dev&Ops/DevOps 2024. 6. 22. 12:55

    안녕하세요! zerone-code입니다.

     

    이번 글에서는 최근에 겪었던 네트워크 트러블슈팅에 관련된 내용을 공유해볼까 합니다.

     

    회사에서는 AWS VPC와 Direct Connect를 사용하여 On-premise 환경의 서버와 통신하는 경우가 점차 많아지고 있습니다.

    저희 팀에서는 Network용 Account를 별도로 구성하고 여러 팀에서 해당 환경을 사용하여 On-premise환경의 서버와 통신할 수 있도록 지원을 해주고 있습니다.

     

    이 과정에서 Docker 사설 대역으로 인해 On-premise환경과 통신이 제대로 되지 않는 현상을 겪었습니다. 

    어떤 현상을 어떤 과정으로 분석했고, 어떻게 해결했는지를 자세하게 공유해보도록 하겠습니다.

     

    궁금한 부분은 댓글로 남겨주시면 아는 만큼 성심성의껏 답변해드리도록 하겠습니다.

    잘 읽으셨다면 많은 공감과 구독 부탁드립니다!


    1. Situation

    아래와 같은 구성도로 협업하는 팀의 VPC(오른쪽 VPC들)에 구성된 Service들(EC2, EKS...)에서는 On-premise 환경의 서버를 호출하는 구성입니다. 

     

    협업하는 팀의 VPC는 10대역의 CIDR로 구성되있고, On-premise 환경과 통신을 하기 위해서는 172대역으로 IP를 변경해야합니다.

    그래서 중간에 Network 계정을 구성하고 NLB와 Nginx Proxy Server를 두어 특정 도메인으로 요청이 들어오는 경우에는 Nginx Proxy Server의 Proxy 설정에 따라 지정된 IP로 라우팅이 되도록 설정해뒀습니다.

    (사내에서 사용되는 IDC가 여러개가 있는데, 그 중 Target이 되는 IDC의 Routing 설정상  On-premise에서 10대역으로 라우팅을 하면 다른 IDC로 가기 때문에 중간에 172대역으로 변환을 해야합니다.) 

     

    이 과정에서 Nginx로 a.b.c로 호출된 도메인에 대해 다른 172대역의 IP는 다 Routing이 되는데, 172.17대역의 On-premise 서버로 호출이 되지 않는 현상이 벌어졌습니다. Nginx Proxy 설정도 정상적이었고, NLB에서 트래픽도 정상적으로 들어오는 상황이었습니다. 그리고 VPC의 Routing도 Static으로 VGW로 흘러가도록 잡아둔 상태였는데, 그럼에도 불구하고 요청이 흘러가지 않았습니다.

     

    과연 문제는 뭐였을까요?

     

    2. Analysis

    먼저 확인해 본 것은 Nginx Proxy Server가 정상적으로 동작하고 있는지를 확인해봤습니다. 

    확인을 해보니 아래와 같이 No route to host라는 error.log가 남고 있는 것을 확인할 수 있었습니다.

    더보기

    2024/06/20 12:56:51 [error] 30948#0: *1556311 connect() failed (113: No route to host) while connecting to upstream, client: 10.x.x.x, server: http://a.b.c, request: "POST / HTTP/1.1", upstream: "http://172.17.xxx.xxx:xxxx/", host: "http://a.b.c"

    Nginx Proxy ServerProxy 설정을 확인을 해봤을 떄는 정상적으로 Mapping이 되있는 것을 확인할 수 있었기 때문에 AWS의 설정도 확인을 해봤습니다.

     

    두번째로 AWS Private Subnet의 Route table을 확인해봤습니다.

    VPC Reachability Analyzer에서 Source와 Destination을 지정해주게 되면 경로상 막히는 부분이 없는지를 확인할 수 있습니다. 그래서 Nginx Proxy Server로부터 DXGW를 타기 전까지인 VGW까지 정상적으로 트래픽이 도달하는지를 확인해 본 결과 아래와 같이 정상적으로 도달하는 것을 확인할 수 있었습니다.

    VPC Reachability Analyzer

    인스턴스 외부 즉, Subnet 단위에서는 정상인 것을 확인했기 때문에 Instance 내부에서의 문제로 좁힐 수 있었습니다.

    세번째로 확인한 부분은 traceroute를 통한 routing 확인이었습니다.

    위 그림과 같이 172.31 Private Subnet에 있는 Nginx Proxy Server로부터 타겟이 되는 172.17 대역으로 traceroute를 해본 결과 정상적으로 나가지 못하는 것을 확인할 수 있었습니다.

     

    위 상황을 어떻게 해석해야할지 의문이었습니다. 왜 나가지 못하고 172.17.0.1로 가려고 하는 것일까? 

    172.17.0.1 어디서 많이 본 IP이지 않나요? 
    아마 컨테이너나 Docker를 좀 많이 만져보신 분이고, 눈치가 빠르신 분은 답을 아실 수 있을 것입니다. 

     

    Docker를 설치하게 되면 /etc/docker/daemon.json에서 확인하실 수 있는 Docker Bridge Network의 Default Subnet Range입니다.  여기에서 Docker Bridge Network가 설정되는 자세한 과정을 알고 싶으시면 코드 수준에서 분석한 Docker 사설 대역에 대한 글을 참고해보시면 좋을 것 같습니다.

     

    분석을 해보면 Nginx Proxy Server까지는 정상적으로 도달했으나, Docker를 설치하고 Daemon이 실행되는 과정에서 내부에서 Docker Bridge Network(172.17.0.0/16)로 Iptables를 변경했고, VGW를 통해 172.17대역으로 흘러가야할 트래픽이 Bridge Network로 흘러갔다라는 결론을 내릴 수 있었습니다.

    3. Solution

    해결책으로는 Docker를 해당 환경에 설치하지 않으면 된다는 결론이 났습니다. 따라서 Nginx Proxy Server를 배포할 때, Ansible에서 Docker을 설치하는 과정에서 조건문을 추가하는 것으로 선택적으로 Docker를 설치하도록 함으로서 해결할 수 있었습니다. 

    Ansible 코드

    Docker를 설치하지 않도록 설정하고 Nginx Proxy Server가 다 뜬 다음 iptables 명령어와 traceroute 명령어로 확인을 해봤습니다. iptables 명령어로 확인해본 결과 Docker가 설치되지 않았기 때문에 iptable이 변경된 부분은 확인할 수 없었습니다. 그리고 traceroute 명령어로 확인해본 결과 172.31대역을 타고 나가서 정상적으로 172.17대역으로 나가는 것을 확인할 수 있었습니다.

    iptables 명령어 실행 결과
    172.31 대역의 Target으로 traceroute

    이렇게 설정한 이후, 실제 호출되는 10대역의 VPC에서도 172.17대역의 On-premise 서버로 정상적으로 호출되는 것을 확인할 수 있었습니다.

     

    궁금한 부분은 댓글로 남겨주시면 아는 만큼 성심성의껏 답변해드리도록 하겠습니다.

    잘 읽으셨다면 많은 공감과 구독 부탁드립니다!

    Reference

    코드 수준에서 분석한 Docker 사설 대역 

    https://substack.com/home/post/p-145836197?utm_campaign=post&utm_medium=web

     

     

Designed by Tistory.