Rate Limit 사용하여 NGINX Service Mesh 배포하기

의도가 악의적인지(암호 추측 및 DDoS 공격) 무해한지는 중요하지 않습니다. 대량의 HTTP 요청은 서비스를 압도하고 애플리케이션 충돌을 일으킬 수 있습니다. 이 문제에 대한 쉬운 해결책은 각 사용자가 주어진 시간 동안 만들 수 있는 요청 수를 제한하는 Rate Limit 입니다. 그러나 Kubernetes 환경에서는 서비스에 도달하는 총 트래픽 양의 상당 부분이 다른 서비스와의 통신 형태로 Ingress Controller의 범위 밖에 있을 수 있습니다. 이 상황에서는 Service Mesh를 사용하여 Rate Limit 정책을 설정하는 것이 좋습니다.

NGINX Service Mesh로 Rate Limit을 구성하는 것은 10분 이내에 완료할 수 있는 간단한 작업입니다.

목차

1. K8s 보안을 위한 Rate Limit
1-1. Rate-Limiting 정책 적용
1-2. 모든 클라이언트에 Rate Limit 적용

1-3. Burst 요청 허용
1-4. Rate Limit 제거
2. Rate Limit을 위해 NGINX Service Mesh 사용

1. K8s 보안을 위한 Rate Limit

이 실습에서는 NGINX Service Mesh Sidecar가 주입된 3개의 컨테이너(Backend 서비스, Frontend 서비스 및 bash 터미널)를 사용합니다. NGINX Service Mesh Control Plane도 배포되었습니다.

Frontend 서비스는 1초마다 Backend 서비스에 요청을 전송하며, Frontend 서비스의 로그에서 응답을 확인할 수 있습니다:

backend v1
backend v1
backend v1
backend v1

1-1. Rate-Limiting 정책 적용

Backend 서비스가 너무 많은 요청을 받는 것을 원하지 않는다고 가정해 보겠습니다. Rate Limit 정책을 다음 필드가 있는 사용자 정의 리소스로 정의할 수 있습니다.

  • destination – 요청을 받는 서비스 이것이 우리의 Backend 서비스입니다.
  • sources – 요청이 들어오는 클라이언트 목록으로 각각 Rate Limit 이 적용됩니다. 여기서는 Frontend 서비스라는 하나의 Source만 정의합니다.
  • rate – Rate Limit 입니다. 여기서는 분당 요청 10개 또는 6초마다 1개입니다.
apiVersion: specs.smi.nginx.com/v1alpha1
kind: RateLimit
metadata:
  name: backend-rate-limit
  namespace: default
spec:
  destination:
    kind: Service
    name: backend-svc
    namespace: default
  sources:
  - kind: Deployment
    name: frontend
    namespace: default
  name: 10rm
  rate: 10r/m
  burst: 0
  delay: nodelay

이 명령을 실행하여 정책을 활성화합니다.

$ kubectl create -f rate-limit.yaml

Frontend 로그에서 6개 요청 중 5개가 다음 메시지와 함께 거부되었음을 확인할 수 있습니다.

<html>
<head><title>503 Service Temporarily Unavailable</title</head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.19.5</center>
</body>
</html>

1-2. 모든 클라이언트에 Rate Limit 적용

Rate Limit 은 Source 필드에 이름이 정의된 클라이언트(Frontend 서비스)에만 적용됩니다. Backend 서비스는 전송 속도에 관계없이 다른 모든 클라이언트의 요청을 수락합니다. bash 터미널에서 요청을 반복적으로 전송하여 이를 설명할 수 있습니다. 각 요청은 성공을 나타내는 backend v1 응답을 받습니다.

모든 클라이언트에 Rate Limit을 적용하는 방법에는 두 가지가 있습니다. 첫 번째는 이름을 Source 필드에 추가하는 것입니다. 두 번째로 훨씬 간단한 방법은 Source 필드를 완전히 제거하는 것입니다. 이 명령을 실행하여 정책을 편집하면 됩니다.

$ kubectl edit ratelimits.specs.smi.nginx.com backend-rate-limit

편집된 정책을 저장한 후 bash 터미널에서 다시 요청을 하고 Rate Limit을 초과하는 해당 Source의 요청이 위에 표시된 형식화된 503 오류와 함께 거부되는 것을 확인합니다.

1-3. Burst 요청 허용

Rate Limit을 사용자 정의하기 위해 정책에 추가할 수 있는 몇 가지 다른 필드가 있습니다. 우리는 일부 애플리케이션이 여러 요청을 빠르게 연속적으로 전송하는 “bursty”이라는 것을 알고 있습니다. 이를 수용하기 위해 Burst 필드를 추가할 수 있습니다. 여기서 이 값을 3으로 설정합니다. 즉, Backend 서비스는 6초마다 많은 추가 요청을 수락합니다. 그 이상의 요청은 거부됩니다.

delay 필드는 허용된 요청 Burst가 Backend 서비스에 공급되는 방식을 제어합니다. 기본적으로 Burst 요청이 없으면 Burst 요청이 대기열에 저장되고 Rate Limit에 따라 전송되며 새 요청과 인터리빙(Interleaving)됩니다. Burst 요청을 즉시 전송하기 위해 delay 필드를 nodelay 값으로 설정합니다.

delay 필드를 정수로 설정할 수도 있습니다. 예를 들어 Burst 필드를 3으로 설정하고 Burst 필드를 5로 늘린 경우 6초 동안 5개 이상의 Burst 요청이 도착하면 3개가 즉시 전송되고 2개는 대기열에 있으며 나머지는 거부됩니다.

burst: 3 및 delay: nodelay의 로그에서 효과를 관찰할 수 있습니다. 요청이 거부되기 전에 세 가지 추가 요청이 수락되는 것을 볼 수 있습니다.

backend v1
backend v1
backend v1
backend v1
<html>
<head><title>503 Service Temporarily Unavailable</title</head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.19.5</center>
</body>
</html>
. . .

1-4. Rate Limit 제거

데모의 마지막 작업은 이 명령을 실행하여 Rate Limit 정책을 비활성화하고 모든 요청을 수락하는 것입니다.

$ kubectl delete -f rate-limit.yml

2. Rate Limit을 위해 NGINX Service Mesh 사용

burst 및 delay 매개변수에 대한 자세한 내용은 참조 문서를 참조하십시오.


NGINX Serivce Mesh를 테스트 및 사용해 보려면 지금 30일 무료 평가판을 신청하거나 사용 사례에 대해 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.

NGINX STORE 뉴스레터 및 최신 소식 구독하기

* indicates required