본문 바로가기

VMware Cloud Foundation/NSX-T

NSX Advanced LB - HTTP keep-alive timeout 처리

webserver 혹은 app을 운영할 때, client session 처리를 어떻게 할 것인가 고민을 하게 됩니다. 이에 따라서 우리는 여러가지 옵션을 통해서, 신규 세션을 계속 받는 것이 아닌 기존 세션을 재사용을 하거나, 혹은 하나의 세션에 여러 클라이언트가 함께 공유하여 사용을 하는 등 소비되는 워크로드 타입에 맞춰 선택을 하게 됩니다.

 

KeepAlive Timeout 처리를 NSX Advanced LB에서 어떻게 설정하는지, 그리고 Client에게는 어떻게 쉽게 검증하는지를 이번 게시물에서 소개합니다.

 

NSX ALB는 L4-L7에 이르는 다양한 기능들과 함께 WAF, GSLB, LB Auto scaling 등 powerful한 기능을 제공하고 있습니다.

 

그림-1. Virtual Services

그림-1과 같이 직관적으로 Virtual Service(이하 VS)에 대한 정보를 표기합니다.

 

그림-2. VS 설정

그림-2와 같이 VS에 대한 설정 화면에는 어떤 VS Virtual IP 주소를 사용할 것인지, TCP/UDP에 대한 처리 방식, Application Profile을 통한 Virtual Service를 위한 L4, HTTP, HTTPs 등의 각 요구되는 옵션 값을 조정하고, 이를 프로파일 형태로 저장하여 다시 사용할 수 있도록 제공합니다.

 

그림-3. Application Profile

 

그림-3과 같이 Application Profile을 신규로 생성하거나 기존 profile을 수정할 경우, tab menu에서 DDoS 항목을 확인할 수 있으며, ALB에서 제공하는 HTTP timeout 관련 값을 확인할 수 있습니다.

 

좌측 하단의 "Send Keep-Alive header"와 "Use App Keep-Alive Timeout" 2개의 옵션을 조정하여 ALB가 설정한 keepalive timeout을 전송하거나, 혹은 Application에서 제공하는 keepalive timout 값을 클라이언트에게 전달할 수 있습니다.

 

그렇다면 체크만 하면 전송이 완료가 되고, 우리가 쉽게 확인이 가능할까요?

No, No.

 

ALB에서는 application에서 keepalive timeout header를 받지 못할 경우에는 그림-3에 설정된 ALB의 HTTP Keep-Alive Timeout 값을 전달하게 됩니다.

 

웹 서버마다 keepalive를 설정하고 header를 삽입하는 방식은 모두 다르며, 여기서는 node.js를 이용하도록 하겠습니다.

node.js를 이용한 간단한 web server를 올리고, 클라이언트 IP 주소나, 호스트 IP 주소를 웹페이지에 표기하여, X-Forwarded-For 테스트 등을 통해서 클라이언트 IP 주소에 대한 확인 작업에서도 활용할 수 있습니다.

 

우선 web server용 호스트에 Node.js를 설치를 합니다.

 

Node.js 설치(ubuntu linux)

sudo apt-get install -y nodejs

sudo npm install express

sudo npm install ip

sudo npm install request-ip

 

Sample file: index.js

const express = require('express');
const http = express();
const requestIP = require('request-ip');
const port = 8080;
var ip = require("ip");
const hostname = ip.address();
const kptimeout = 15;

http.get('/', (req, res) => {
  var clientIP = requestIP.getClientIp(req)
  const remoteIP = req.headers['x-forwarded-for'] ||  req.connection.remoteAddress
  res.setHeader('Keep-Alive', `timeout=${kptimeout}`);
  res.send(`<h2>You're connecting to ${hostname}</h2><br><h2>Your IP address is ${clientIP}</h2><br><h2>x-forwareded-for remoteIP is ${remoteIP}` )
});

const server = http.listen(port, hostname);
console.log(`Server running at http://${hostname}:${port}/`);

server.keepAliveTimeout = kptimeout * 1000;
server.headersTimeout = 16 * 1000;

 

위 예문과 같은 코드로 .js 파일을 하나 생성합니다.

8080 포트를 사용하며, 호스트 IP, 클라이언트 IP 획득을 위해서 몇 가지 express, request-ip, ip 등을 추가 사용하였습니다.

또한, 응답 구문으로 간단한 html 구문 한 줄을 삽입하여, 웹페이지로 표시가 되도록 하였습니다.

 

node.js에서는 server.keepAliveTimeout 을 통해서 값을 지정할 수 있으며, ms 단위이기 때문에 쉽게 수치 확인을 위해서 초 단위 값을 입력하고 곱하기 1,000을 하여 ms 수치로 진행을 했습니다.

 

webserver에는 위 옵션을 통해서 실제 설정 값이 적용이 되어 우리는 keepalive 연결이 맺어졌다는 것을 알 수 있지만, 클라이언트 측으로 가는 응답에는 timeout 값이 어떻게 되는지는 확인할 방법이 없습니다.

 

이를 위해 응답 헤더에 Keep-Alive 헤더 값을 kptimeout으로 지정하여, 직접 timeout 값 표기를 header에도 삽입을 하였습니다.

 

그러면 어떻게 나오는지 클라이언트에서 확인을 해보겠습니다.

 

그럼-4. node.js 실행

 

구글 크롬 브라우저를 이용해서 웹 서버에 직접 접속을 합니다.

그림-5. 브라우저 화면

그림-5와 같이 구글 클라이언트에서 접속할 경우

  - 클라이언트 IP: 10.109.211.14

  - 웹서버 IP: 172.16.105.11

 

브라우저에 현재 회신된 호스트 IP 정보와 접속을 시도한 클라이언트 IP 정보가 확인되며, 개발자 도구를 이용하여 확인 시 응답 헤더에 keep-alive 시간이 설정한 15초로 나타나는 것을 확인할 수 있습니다.

 

이제 NSX ALB에서 L7 Virtual Service를 구성하여, 웹 서버로 연결을 합니다.

그림-6. ALB의 application profile의 설정 값

ALB에는 keep-alive timeout 값이 30초로 설정이 현재 되어 있는 것을 확인 후, ALB를 통한 접속을 시도합니다.

 

그림-7. ALB VIP로 접속한 화면

 

ALB VIP를 192.168.130.51로 설정이 되어 있습니다. 해당 VIP로 접속할 경우 동일하게 이미 X-Forwarded-For 옵션을 적용했기 때문에 현재 클라이언트 IP를 함께 표기하는 것을 확인할 수 있습니다.

 

우측 개발자 도구 화면에서 응답 헤더에 앞선 직접 클라이언트 -> 웹 서버 접속과 다르게 keep-alive timeout 값은 표기가 되지 않는 것을 확인할 수 있습니다.

 

이제 ALB의 설정된 keepalive timeout 값을 헤더에 삽입하여, 클라이언트측으로 전달을 합니다.

그림-8. keep-alive 값 전달 체크

 

Send Keep-Alive header 만을 체크 표시를 한 후 다시 확인합니다.

그림-9. ALB VIP로 접속 화면

그림-9와 같이 keep-Alive의 timeout 값이 ALB에서 설정된 30초로 표기가 된 것을 확인할 수 있습니다.

 

이제 다시, Use App Keep-Alive Timeout 값을 지정하여, 애플리케이션에서 삽입된 헤더 값을 그대로 클라이언트 측으로 전달을 합니다.

그림-10. ALB의 설정 화면

 

설정된 값으로 다시 브라우저에서 접근을 합니다.

그림-11. 브라우저에서의 화면

그림-11 화면과 같이 ALB의 설정된 keep-alive timeout 값이 아닌, 웹 서버에 설정된 timeout 값이 응답 헤더 값으로 표시되는 것을 확인할 수 있습니다.

 

SNAT가 수행되는 One-arm 모드 형태에서 L7 http x-forwarded-for를 적용하여, 서버 측에서는 클라이언트 IP를 확인할 수 있습니다.

만약 x-forwarded-for를 해제 한다면, 설정된 SNAT 정책에 따라서, VIP 혹은 SE engine interface의 IP가 표시가 될 것입니다.

 

그림-12. ALB에서 X-Forward-For를 해제한 경우

 

이러한 keep-alive 기능은 Mutiplex 기능을 통해 연결 유지 관리 됩니다.

ALB에서 설정되는 keep-alive는 Client <-> NSX ALB 구간에 해당 됩니다.