HTTP 경로 리다이렉트(Redirect)와 리라이트(Rewrite)¶
HTTPRoute 리소스는 필터를 사용하여 클라이언트에게 리다이렉트를 발행하거나 업스트림으로 전송되는 경로를 리라이트할 수 있다. 이 가이드는 이러한 기능의 사용 방법을 보여준다.
리다이렉트 필터와 리라이트 필터는 상호 호환되지 않는다. 규칙에서 두 필터 타입을 동시에 사용할 수 없다.
리다이렉트(Redirect)¶
리다이렉트는 클라이언트에게 HTTP 3XX 응답을 반환하여 다른 리소스를
가져오도록 지시한다.
RequestRedirect 규칙 필터는
필터링된 HTTPRoute 규칙과 일치하는 요청에 대해 게이트웨이가
리다이렉트 응답을 보내도록 지시한다.
지원되는 상태 코드¶
게이트웨이 API는 다음과 같은 HTTP 리다이렉트 상태 코드를 지원한다.
-
301 (Moved Permanently): 리소스가 새 위치로 영구적으로 이동했음을 나타낸다. 검색 엔진과 클라이언트는 새 URL을 사용하도록 참조를 업데이트한다. HTTP에서 HTTPS로의 업그레이드나 영구적인 URL 변경과 같은 영구 리다이렉트에 사용한다.
-
302 (Found): 리소스가 일시적으로 다른 위치에서 사용 가능함을 나타낸다. 상태 코드를 지정하지 않으면 이것이 기본 상태 코드이다. 원래 URL이 향후 다시 유효해질 수 있는 임시 리다이렉트에 사용한다.
-
303 (See Other): 요청에 대한 응답을 GET 메서드를 사용하여 다른 URL에서 찾을 수 있음을 나타낸다. 이는 일반적으로 POST 요청 후 확인 페이지로 리다이렉트하여 중복 폼 제출을 방지하는 데 사용된다.
-
307 (Temporary Redirect): 302와 유사하지만, 리다이렉트를 따를 때 HTTP 메서드가 변경되지 않음을 보장한다. 리다이렉트에서 원래 HTTP 메서드(POST, PUT 등)를 보존해야 할 때 사용한다.
-
308 (Permanent Redirect): 301과 유사하지만, 리다이렉트를 따를 때 HTTP 메서드가 변경되지 않음을 보장한다. HTTP 메서드를 보존해야 하는 영구 리다이렉트에 사용한다.
리다이렉트 필터는 다양한 URL 구성 요소를 독립적으로 대체할 수 있다. 예를 들어,
HTTP에서 HTTPS로의 영구 리다이렉트(301)를 발행하려면
requestRedirect.statusCode=301과 requestRedirect.scheme="https"를 설정한다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-redirect
spec:
parentRefs:
- name: redirect-gateway
sectionName: http
hostnames:
- redirect.example
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
리다이렉트는 설정된 URL 구성 요소를 리다이렉트 설정과 일치하도록 변경하면서
원래 요청 URL의 다른 구성 요소는 보존한다. 이 예제에서
GET http://redirect.example/cinnamon 요청은
location: https://redirect.example/cinnamon 헤더가 포함된 301 응답을 반환한다.
호스트네임(redirect.example), 경로(/cinnamon), 포트(암시적)는
변경되지 않는다.
메서드 보존 리다이렉트¶
리다이렉트 중에 HTTP 메서드가 보존되어야 하는 경우, 상태 코드 307 또는 308을 사용한다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: method-preserving-redirect
spec:
parentRefs:
- name: redirect-gateway
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /api/v1
filters:
- type: RequestRedirect
requestRedirect:
path:
type: ReplaceFullPath
replaceFullPath: /api/v2
statusCode: 307
HTTP 메서드를 보존해야 하는 영구 리다이렉트의 경우, 상태 코드 308을 사용한다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: permanent-method-preserving-redirect
spec:
parentRefs:
- name: redirect-gateway
hostnames:
- api.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /old-api
filters:
- type: RequestRedirect
requestRedirect:
path:
type: ReplaceFullPath
replaceFullPath: /new-api
statusCode: 308
POST-Redirect-GET 패턴¶
POST-Redirect-GET 패턴을 구현하려면, 상태 코드 303을 사용하여 POST 요청을 GET 엔드포인트로 리다이렉트한다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: post-redirect-get
spec:
parentRefs:
- name: redirect-gateway
hostnames:
- forms.example.com
rules:
- matches:
- path:
type: Exact
value: /submit-form
method: POST
filters:
- type: RequestRedirect
requestRedirect:
path:
type: ReplaceFullPath
replaceFullPath: /thank-you
statusCode: 303
HTTP에서 HTTPS로의 리다이렉트¶
HTTP 트래픽을 HTTPS로 리다이렉트하려면, HTTP와 HTTPS 리스너를 모두 가진 게이트웨이(Gateway)가 필요하다.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: redirect-gateway
spec:
gatewayClassName: foo-lb
listeners:
- name: http
protocol: HTTP
port: 80
- name: https
protocol: HTTPS
port: 443
tls:
mode: Terminate
certificateRefs:
- name: redirect-example
certificateRefs 섹션의 redirect-example).
HTTP 리스너에 연결되어 HTTPS로 리다이렉트하는 HTTPRoute가 필요하다.
여기서 sectionName을 http로 설정하여 http라는 이름의
리스너만 선택하도록 한다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-redirect
spec:
parentRefs:
- name: redirect-gateway
sectionName: http
hostnames:
- redirect.example
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
또한 HTTPS 리스너에 연결되어 HTTPS 트래픽을 애플리케이션 백엔드로 전달하는 HTTPRoute도 필요하다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: https-route
labels:
gateway: redirect-gateway
spec:
parentRefs:
- name: redirect-gateway
sectionName: https
hostnames:
- redirect.example
rules:
- backendRefs:
- name: example-svc
port: 80
경로 리다이렉트¶
경로 리다이렉트는 HTTP 경로 수정자(HTTP Path Modifier)를 사용하여 전체 경로 또는 경로
접두사를 교체한다. 예를 들어, 아래의 HTTPRoute는 /cayenne로 시작하는 경로를 가진
모든 redirect.example 요청을 /paprika로 302 리다이렉트한다.
특정 요구사항에 따라 지원되는 상태 코드(301, 302, 303, 307, 308) 중
어떤 것이든 사용할 수 있다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-redirect
spec:
hostnames:
- redirect.example
rules:
- matches:
- path:
type: PathPrefix
value: /cayenne
filters:
- type: RequestRedirect
requestRedirect:
path:
type: ReplaceFullPath
replaceFullPath: /paprika
statusCode: 302
https://redirect.example/cayenne/pinch와
https://redirect.example/cayenne/teaspoon에 대한 요청 모두
location: https://redirect.example/paprika 리다이렉트를 수신하게 된다.
다른 경로 리다이렉트 타입인 ReplacePrefixMatch는 matches.path.value와
일치하는 경로 부분만 교체한다. 위의 필터를 다음과 같이 변경하면:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-redirect
spec:
hostnames:
- redirect.example
rules:
- matches:
- path:
type: PathPrefix
value: /cayenne
filters:
- type: RequestRedirect
requestRedirect:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /paprika
statusCode: 302
location: https://redirect.example/paprika/pinch와
location: https://redirect.example/paprika/teaspoon
응답 헤더가 포함된 리다이렉트가 발생한다.
리라이트(Rewrite)¶
리라이트는 업스트림으로 프록시하기 전에 클라이언트 요청의 구성 요소를 수정한다.
URLRewrite 필터는
업스트림 요청의 호스트네임 및/또는 경로를 변경할 수 있다.
예를 들어, 다음 HTTPRoute는
https://rewrite.example/cardamom 요청을 수신하여
host: rewrite.example 대신 host: elsewhere.example
요청 헤더와 함께 example-svc 업스트림으로 전송한다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-rewrite
spec:
hostnames:
- rewrite.example
rules:
- filters:
- type: URLRewrite
urlRewrite:
hostname: elsewhere.example
backendRefs:
- name: example-svc
weight: 1
port: 80
경로 리라이트도 HTTP 경로 수정자(HTTP Path Modifier)를 활용한다.
아래의 HTTPRoute는 https://rewrite.example/cardamom/smidgen 요청을
example-svc 업스트림의 https://elsewhere.example/fennel로 프록시한다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-rewrite
spec:
hostnames:
- rewrite.example
rules:
- matches:
- path:
type: PathPrefix
value: /cardamom
filters:
- type: URLRewrite
urlRewrite:
hostname: elsewhere.example
path:
type: ReplaceFullPath
replaceFullPath: /fennel
backendRefs:
- name: example-svc
weight: 1
port: 80
대신 type: ReplacePrefixMatch와 replacePrefixMatch: /fennel을 사용하면
업스트림에 https://elsewhere.example/fennel/smidgen을 요청하게 된다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-filter-rewrite
spec:
hostnames:
- rewrite.example
rules:
- matches:
- path:
type: PathPrefix
value: /cardamom
filters:
- type: URLRewrite
urlRewrite:
hostname: elsewhere.example
path:
type: ReplacePrefixMatch
replacePrefixMatch: /fennel
backendRefs:
- name: example-svc
weight: 1
port: 80