[NSX] Additional session is not created when multiplexing is enabled although virtual servers have the different service ports
NSX의 Load Balancer를 사용할 때, 서로 다른 Virtual Server가 동일한 Server Pool을 사용하도록 설정할 수 있습니다.
또한, Server Pool에 Back-end Server에서 Listening 하고 있는 Port를 지정하지 않고, Virtual Server에 Default Pool Member Ports 값을 대신 지정하여 사용할 수도 있습니다.
문제는 위와 같은 환경 구성을 사요할 때, Server Pool에 Multiplexing 기능을 활성화 하는 경우 예기치 않은 문제가 발생하는 경우가 있어 이에 대해 공유하고자 합니다.
[Symptom]
Virtual Server <VIP>:443 -> Server Pool <Back_End_Server_IP>:80 으로 통신하는 세션에
Virtual Server :8091로 호출하면 Server Pool <Back_End_Server_IP>:80 으로 전달되어 8091 서비스 통신이 안되는 현상
[Troubleshooting Notes]
1. 고객사와 유사한 환경 구성
1-1. 4개 Virtual Server 생성
※ Ports와 Default Pool Member Ports 값을 동일하게 입력 필요
VIP 172.31.1.60, Ports 80, Default Pool Members Ports 80
VIP 172.31.1.60, Ports 443, Default Pool Members Ports 443
VIP 172.31.1.60, Ports 8091, Default Pool Members Ports 8091
VIP 172.31.1.60, Ports 8092, Default Pool Members Ports 8092
1-2. 1개 Server Pool 생성(TCP Multiplexing Enabled)
※ Port 정보 입력하지 않아야 함
1-3. 웹 서버 구성
Nginx 설정에 총 4개의 Listening Port 구성
※ 80 포트의 경우에는 Session을 오랫동안 유지하기 위해서 Javascript로 Timeout을 적용
# cat /etc/nginx/conf.d/default.conf server { listen 443 ssl http2; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> server_name web-ssl-01.contoso.com; access_log /var/log/nginx/host.access.log main; ssl_certificate "/etc/nginx/server-chained.crt"; ssl_certificate_key "/etc/nginx/server.key"; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; location / { root /usr/share/nginx/html; index index.html index.htm; } } server { listen 80; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> server_name localhost; access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index_80.html; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> } } server { listen 8091; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> server_name localhost; access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } } server { listen 8092; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> server_name localhost; access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } } |
Index_80.html
# cat index_80.html <html> <head> <title>JS Hello World</title> </head> <body> <script> for(var i=0; i < 5000000000; i++); </script> <p>test</p> </body> </html> |
2. 문제 재현 테스트
먼저, 웹 브라우저에서 http://172.31.1.60 으로 80 포트에 접속
이 때 LB에서 Session 정보를 확인해보면, 다음과 같이 정상적으로 확인 가능
edge-node-01> get load-balancer 77d271b2-4c38-4212-9925-5a2a37c5931c session-tables Thu Jun 20 2024 UTC 13:59:39.608 Session-Tables TABLE ID PROTO CADDR CPORT VADDR VPORT SADDR SPORT DADDR DPORT l7lb-0 0000000000000012 http 192.168.1.2 59045 172.31.1.60 80 172.31.1.254 4105 172.31.1.61 80 |
이 후, 웹브라우저에 새 탭을 띄우고, http://172.31.1.60:8091 로 8091 포트에 접속
8091 포트에 접속하면 원래 8091 포트로 접속할 때 확인되어야 하는 html 화면이 아닌 80 포트에 접속할 때 보이는 Index_80.html이 확인
이 때, LB의 Session Table 정보를 확인해보면, Client가 8091 포트에 연결한 기록이 LB 와만 있고, LB와 Back-end Server 간에는 없음
즉, Client와 8091 포트 간의 연결은 실제로 LB와 Back-end Server의 80 포트 간의 연결을 그대로 이용하는 것으로 추정
edge-node-01> get load-balancer 77d271b2-4c38-4212-9925-5a2a37c5931c session-tables Thu Jun 20 2024 UTC 13:59:50.529 Session-Tables TABLE ID PROTO CADDR CPORT VADDR VPORT SADDR SPORT DADDR DPORT l7lb-0 0000000000000012 http 192.168.1.2 59045 172.31.1.60 80 172.31.1.254 4105 172.31.1.61 80 l7lb-0 0000000000000014 http 192.168.1.2 59052 172.31.1.60 8091 - 0 - 0 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> |
3. 개발팀과 재현 테스트 및 Debugging 결과 Bug로 확인
4. Fix된 버전을 이용하여 문제 재현 테스트
80 port 접속 이후에 8091 port에 접속하면 정상적으로 Nginx 페이지 확인
Session Table 정보를 봐도, 80과 8091 연결이 각각 정상적으로 맺어진 것을 확인
edge-node-01> get load-balancer 77d271b2-4c38-4212-9925-5a2a37c5931c session-tables Tue Jul 02 2024 UTC 09:34:10.850 Session-Tables TABLE ID PROTO CADDR CPORT VADDR VPORT SADDR SPORT DADDR DPORT l7lb-0 0000000000000000 http 192.168.1.2 53470 172.31.1.60 80 172.31.1.254 4096 172.31.1.61 80 l7lb-0 0000000000000002 http 192.168.1.2 53472 172.31.1.60 8091 172.31.1.254 4097 172.31.1.61 8091 |
[Conclusion]
1. 문제 해결을 위한 Workaround
1-1. 각 Virtual Server 별로 Back-end Server는 동일하지만 서로 다른 Server Pool을 생성
1-2. Server Pool에서 TCP Multiplexing 비활성화
2. Fix된 Code는 4.2.1에 반영 예정