Kong API G/W API Service 로드밸런싱
Kong API 에서 로드 밸런싱은 API 요청 트래픽을 여러 업스트림에 분산시키고 서버에 대한 부담을 분산시켜 과부하를 방지하고 서버의 응답성을 향상시키고 오류를 줄입니다. Kong API G/W에서 로드밸런싱을 사용시켜 API 요청을 분산시켜보겠습니다.
목차
1. 로드밸런싱 개요
2. Kong API G/W 로드밸런싱 실습
2.1 Manage 페이지에서의 Kong API G/W 로드밸런싱
2.2 API 요청을 통한 로드밸런싱
1. 로드밸런싱 개요
로드밸런싱을 서버에 들어오는 요청트래픽 부하를 분산해주는 기술을 뜻합니다. 여기서 Kong API에서 사용하는 로드밸런싱은 Route를 통해 Service에 접속하게되면 Load balancer를 통해 특정 서버에 부하가 집중되지 않도록 트래픽을 분산시킵니다. Load banlancing은 Health Check를 통해 서버들의 장애 여부를 판단하고 정상동작중인 서버로만 트래픽을 보냅니다.
로드밸런싱은 알고리즘을 통해 어떻게 트래픽을 보낼지 정할 수 있습니다.
라운드 로빈 방식 : 서버로 들어온 요청을 순서대로 돌아가며 배정합니다
IP 해시 방식 : 클라이언트의 IP 주소를 특정 서버로 매핑합니다.
최소 연결 방식 : 요청이 들어온 시점에 가장 적은 트래픽을 받는 서버에 우선적으로 트래픽을 할당합니다.
라운드로빈, IP 해시 방식 등등 말고도 다른 알고리즘도 가지고있습니다.

출처 : Kong Docs(https://docs.konghq.com/gateway/latest/get-started/load-balancing/)
2. Kong API G/W 로드밸런싱 실습
2.1 Manage 페이지에서의 Kong API G/W 로드밸런싱
먼저 서비스를 만들기 전에 Upstrems를 통해 서버그룹을 만들겠습니다.
Manager 페이지에서 Upstreams를 선택하고 New Upstrem을 클릭합니다.
Upstream을 생성해보도록 하겠습니다.

이름을 작성해주었습니다 호스트헤더, 인증서ID, 태그는 사용하지 않기때문에 비워두었습니다.
알고리즘은 순차적으로 사용하는 라운드로빈방식으로 사용하였습니다.
슬롯은 라운드로빈 방식의 알고리즘이 slots의 갯수만큼 순차적으로 요청을 분산시킵니다.

Hash on은 Hash on에서의 목록을 선택하게 된다면 선택된 목록을 통해 Consistent-hashing 알고리즘을 사용합니다.
Hash Fallback은 위의 Hash on에서 선택된 목록이 해시를 반환하지 않는경우에 기본적으로 해시를 입력할 항목입니다.
Active Health Checks는 애플리케이션 Endpoints가 올바르게 응답하는지 확인하기 위해 애플리케이션에 정기적으로 전송되는 특별한 요청입니다.
Passive Health Checks는 연결 및 트래픽을 처리하는 동안 서버가 어떻게 동작하는지 관찰합니다. 서버가 이상이 있다면 다른 서버로 요청을 전달합니다.
여기에 나온 기능들도 사용하지 않기 때문에 바로 저장합니다.

만들어진 Upstreams를 클릭합니다. 그리고 target 목록을 선택합니다.
New Target을 클릭합니다.

Target Address는 요청을 분산시킬 서버의 IP or URL을 적습니다.(포트포함)
Weight는 현재 서버가 감당할 요청을 적습니다.(현재 10000 slot을 정했다면 91포트를 가지고있는 서버를 Weight 8000으로 정하고 90포트를 가지고있는 서버를 2000으로 정한다면 8:2비율로 로드밸런싱이 됩니다. 예제이기 때문에 둘다 기본값인 100으로 지정하고 사용하였습니다.)
Tags은 사용하지 않았기 때문에 지정하지 않았습니다.
저장합니다. (로드밸런싱은 하나 초과의 서버를 사용해야합니다.)
Upstream에 사용한 서버는 아래와 같은 python 코드를 사용하였습니다.
# 포트 81 flask 서버
from flask import Flask
app = Flask(__name__)
@app.route('/')
def return_number():
return '1' # "/"path로 요청을 하게 되었을 때 1을 반환합니다.
if __name__ == '__main__':
app.run(host='0.0.0.0',port=81, debug=True)
# 포트 80 flask 서버
from flask import Flask
app = Flask(__name__)
@app.route('/')
def return_number():
return '0' # "/"path로 요청을 하게 되었을 때 0을 반환합니다.
if __name__ == '__main__':
app.run(host='0.0.0.0',port=80, debug=True)

Gateway Services를 누르고 New Gateway Service를 클릭하여 서비스를 추가합니다.
Name을 지정한 후에 Upstream URL에 아까 만들었던 Upstreams의 이름을 넣습니다.
저장합니다.

Routes를 지정해주겠습니다.
저장합니다.

이제 curl를 통해 요청을 보내 로드밸런싱이 되는지 확인해보겠습니다.
# port 80 server
$ curl -i localhost:8000/test
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1
Connection: keep-alive
Server: Werkzeug/3.0.3 Python/3.10.12
Date: Fri, 14 Jun 2024 07:52:54 GMT
X-Kong-Upstream-Latency: 4
X-Kong-Proxy-Latency: 1
Via: kong/3.6.1
X-Kong-Request-Id: 15a8df29fd2f0f5c26fd7c122bf29a64
0
# port 81 server
$ curl -i localhost:8000/test
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1
Connection: keep-alive
Server: Werkzeug/3.0.3 Python/3.10.12
Date: Fri, 14 Jun 2024 07:53:51 GMT
X-Kong-Upstream-Latency: 5
X-Kong-Proxy-Latency: 2
Via: kong/3.6.1
X-Kong-Request-Id: bbf37a684d81612090da676f28c16b2e
1
같은 서버로 요청을 여러번 했을 때 target에 등록한 서버가 순차적으로 응답하는것을 보실 수 있습니다.
Kong API 요청을 통해 로드밸런싱을 구성해보도록하겠습니다.
2.2 API 요청을 통한 로드밸런싱
Kong API 요청을 통해 로드밸런싱을 구성해보겠습니다.
# API 요청을 통해 upstream을 만들었습니다.(위의 manage 페이지와 구성 동일)
$ curl -X POST http://localhost:8001/upstreams \
--data name=test1_upstream
{"hash_fallback":"none","hash_fallback_header":null,"hash_fallback_query_arg":null,"hash_fallback_uri_capture":null,"tags":null,"host_header":null,"created_at":1718352076,"updated_at":1718352076,"hash_on_header":null,"hash_on_query_arg":null,"id":"164e512f-e4c5-43d9-853b-5411e27f3ff2","healthchecks":{"threshold":0,"active":{"https_sni":null,"https_verify_certificate":true,"healthy":{"interval":0,"successes":0,"http_statuses":[200,302]},"unhealthy":{"interval":0,"http_statuses":[429,404,500,501,502,503,504,505],"tcp_failures":0,"timeouts":0,"http_failures":0},"type":"http","timeout":1,"concurrency":10,"headers":null,"http_path":"/"},"passive":{"type":"http","unhealthy":{"timeouts":0,"tcp_failures":0,"http_statuses":[429,500,503],"http_failures":0},"healthy":{"successes":0,"http_statuses":[200,201,202,203,204,205,206,207,208,226,300,301,302,303,304,305,306,307,308]}}},"client_certificate":null,"hash_on_cookie":null,"hash_on_cookie_path":"/","algorithm":"round-robin","use_srv_name":false,"slots":10000,"hash_on":"none","name":"test1_upstream","hash_on_uri_capture":null}
# API 요청을 통해 Target 80,81번 포트로된 서버를 추가하였습니다.
$ curl -X POST http://localhost:8001/upstreams/test1_upstream/targets \
--data target='192.168.200.25:80'
$ curl -X POST http://localhost:8001/upstreams/test1_upstream/targets \
--data target='192.168.200.25:81'
{"id":"f4b19f3a-da40-4a7a-983e-21fbd2f656e7","weight":100,"tags":null,"upstream":{"id":"164e512f-e4c5-43d9-853b-5411e27f3ff2"},"created_at":1718352271.238,"updated_at":1718352271.238,"target":"192.168.200.25:80"}{"id":"dfe9d452-372d-4c56-b601-84fffde9e012","weight":100,"tags":null,"upstream":{"id":"164e512f-e4c5-43d9-853b-5411e27f3ff2"},"created_at":1718352271.29,"updated_at":1718352271.29,"target":"192.168.200.25:81"}
Manage 페이지에서 만들어진것을 확인 할 수 있습니다.

Service와 Route를 만들어보도록 하겠습니다.
# service 생성
# url에 http://[만들었던 upstream 이름]를 넣고 만듭니다.
$ curl -X POST http://localhost:8001/services --data name=test1_service --data url=http://test1_upstream
{"host":"test1_upstream","tags":null,"ca_certificates":null,"enabled":true,"created_at":1718353924,"updated_at":1718353924,"port":80,"id":"c2d3e1c3-603f-47c0-9cac-52725552a5a1","protocol":"http","tls_verify":null,"tls_verify_depth":null,"client_certificate":null,"path":null,"retries":5,"name":"test1_service","write_timeout":60000,"connect_timeout":60000,"read_timeout":60000}
# route 생성
# api 요청할 때 url path를 /services/[service 이름]/routes 으로 요청보내줍니다.
$ curl -X POST http://localhost:8001/services/test1_service/routes --data 'paths[]=/test1' --data name=test1_route
{"snis":null,"tags":null,"preserve_host":false,"hosts":null,"created_at":1718354084,"updated_at":1718354084,"service":{"id":"c2d3e1c3-603f-47c0-9cac-52725552a5a1"},"methods":null,"path_handling":"v0","destinations":null,"id":"55022d49-9751-4ae5-a65b-5cf00bd2399d","request_buffering":true,"response_buffering":true,"sources":null,"https_redirect_status_code":426,"strip_path":true,"headers":null,"paths":["/test1"],"name":"test1_route","regex_priority":0,"protocols":["http","https"]}
Manage 페이지에서 만들어졌는지 확인합니다.


이제 curl 요청을 통해 Kong API G/W에서 로드밸런싱 구성이 완료되었는지 확인해보겠습니다.
curl -i localhost:8000/test1
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1
Connection: keep-alive
Server: Werkzeug/3.0.3 Python/3.10.12
Date: Fri, 14 Jun 2024 08:38:57 GMT
X-Kong-Upstream-Latency: 6
X-Kong-Proxy-Latency: 1
Via: kong/3.6.1
X-Kong-Request-Id: d1e2e701626b433a5238503f7f790949
0
$ curl -i localhost:8000/test1
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 1
Connection: keep-alive
Server: Werkzeug/3.0.3 Python/3.10.12
Date: Fri, 14 Jun 2024 08:39:06 GMT
X-Kong-Upstream-Latency: 4
X-Kong-Proxy-Latency: 0
Via: kong/3.6.1
X-Kong-Request-Id: 5c41aa5a3d3f1e3b65f4211ce427ef14
1
성공적으로 Kong API G/W 로드밸런싱이 된 모습을 보실 수 있습니다.
다른 정보를 알고싶으시다면 NGINX STORE 블로그를 방문해주세요.