트래픽 분할 예제
트래픽 분할 예제 (Traffic Splitting Example)
HTTP 트래픽 분할은 사전 정의된 가중치나 다른 기준에 따라 인입 트래픽을 여러 백엔드 서비스로 보내는 과정이에요. Cilium Gateway API는 트래픽 분할을 기본 지원해서 카나리 테스트나 A/B 시나리오에 유용해요.
본문
HTTP 트래픽 분할은 사전 정의된 가중치나 다른 기준에 따라 인입 트래픽을 여러 백엔드 서비스로 보내는 과정이에요. Cilium Gateway API는 트래픽 분할을 기본 지원해서, 사용자가 인입 트래픽을 여러 백엔드 서비스에 쉽게 분산할 수 있게 해줘요. 이는 카나리 테스트나 A/B 시나리오에 매우 유용해요.
이 특정 예제는 Gateway API를 사용해 인입 트래픽을 다른 백엔드로 로드 밸런싱하는데, 처음에는 같은 가중치로 시작했다가 99/1 가중치 분포로 테스트해요.
Echo 앱 배포하기 (Deploy the Echo App)
echo 서버로 이루어진 디플로이먼트를 사용할 거예요.
이 애플리케이션은 클라이언트에 응답하면서, 응답 본문에 원래 요청을 받은 Pod에 대한 정보를 포함해요. 이 정보를 사용해서 Gateway가 트래픽을 어떻게 조작하는지 보여드릴게요.
$ kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/gateway/echo-basic.yaml
파드가 예상대로 실행 중인지 확인해볼게요.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
echo-1-7d88f779b-m6r46 1/1 Running 0 21s
echo-2-5bfb6668b4-n7llh 1/1 Running 0 21s
Cilium Gateway 배포하기 (Deploy the Cilium Gateway)
splitting.yaml에서 예시 Gateway와 HTTPRoute 정의를 찾을 수 있어요:
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cilium-gw
spec:
gatewayClassName: cilium
listeners:
- protocol: HTTP
port: 80
name: web-gw-echo
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: example-route-1
spec:
parentRefs:
- name: cilium-gw
rules:
- matches:
- path:
type: PathPrefix
value: /echo
backendRefs:
- kind: Service
name: echo-1
port: 8080
weight: 50
- kind: Service
name: echo-2
port: 8090
weight: 50
두 Service 사이의 균등한 50/50 분할을 주목해주세요.
Gateway와 HTTPRoute를 배포해볼게요:
$ kubectl apply -f https://raw.githubusercontent.com/cilium/cilium/1.20.2/examples/kubernetes/gateway/splitting.yaml
앞선 예제는 포트 80에서 수신하는 cilium-gw라는 Gateway를 만들어요. 단일 라우트가 정의되며, 두 개의 서로 다른 backendRefs(echo-1과 echo-2)와 그와 연관된 가중치를 포함해요.
$ kubectl get gateway cilium-gw
NAME CLASS ADDRESS PROGRAMMED AGE
cilium-gw cilium 172.18.255.200 8s
참고
EKS 같은 일부 프로바이더는 IP 주소 대신 완전한 도메인 이름(FQDN)을 사용해요.
균등한 트래픽 분할 (Even traffic split)
이제 Gateway가 준비됐으니 서비스에 HTTP 요청을 보낼 수 있어요.
$ GATEWAY=$(kubectl get gateway cilium-gw -o jsonpath='{.status.addresses[0].value}')
$ curl --fail -s http://$GATEWAY/echo
{
"path": "/echo",
"host": "172.18.255.200",
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
"Accept": [
"*/*"
],
"User-Agent": [
"curl/7.81.0"
],
"X-Envoy-Internal": [
"true"
],
"X-Forwarded-For": [
"172.18.0.1"
],
"X-Forwarded-Proto": [
"http"
],
"X-Request-Id": [
"ee152a07-2be2-4539-b74d-ebcebf912907"
]
},
"httpPort": "3000",
"namespace": "default",
"ingress": "",
"service": "",
"pod": "echo-1-7d88f779b-m6r46"
}
응답의 pod 필드에 쿼리를 받은 Pod의 이름이 포함되는 걸 주목해주세요. 예를 들면:
"pod": "echo-2-5bfb6668b4-2rl4t"
명령을 여러 번 반복해보세요. 응답이 두 Pod와 Node에 걸쳐 균등하게 분산되는 걸 볼 수 있어야 해요. 루프를 돌려 요청을 세면서 트래픽이 여러 Pod에 균등하게 분할되는지 확인해볼게요:
$ while true; do curl -s -k "http://$GATEWAY/echo" >> curlresponses.txt ;done
Ctrl+C로 루프를 멈추세요. 응답이 대략 균등하게 분산됐는지 확인해볼게요.
$ cat curlresponses.txt| grep -c '"pod": "echo-1'
1221
$ cat curlresponses.txt| grep -c '"pod": "echo-2'
1162
불균등한 (99/1) 트래픽 분할 (Uneven (99/1) traffic split)
kubectl edit httproute를 사용하거나 다시 적용하기 전에 원본 매니페스트의 값을 업데이트해서 HTTPRoute 가중치를 업데이트해보세요. 예를 들어 echo-1에 99, echo-2에 1을 설정해볼게요:
backendRefs:
- kind: Service
name: echo-1
port: 8080
weight: 99
- kind: Service
name: echo-2
port: 8090
weight: 1
루프를 돌려 요청을 세면서 트래픽이 여러 Pod에 불균등하게 분할되는지 확인해볼게요:
$ while true; do curl -s -k "http://$GATEWAY/echo" >> curlresponses991.txt ;done
Ctrl+C로 루프를 멈추세요. 응답이 대략 균등하게 분산됐는지 확인해볼게요.
$ cat curlresponses991.txt| grep -c '"pod": "echo-1'
24739
$ cat curlresponses991.txt| grep -c '"pod": "echo-2'
239
더 알아보기 (Learn more)
- Cilium Gateway API — Cilium Gateway API 개요
- HTTP Header Modifier 예제 — HTTP 헤더 수정
- Gateway API (HTTP) — HTTP Gateway 예제