Gateway API
gateway api는 k8s에서 트래픽 라우팅을 위해 사용되며, 기존의 Ingress 리소스를 개선하고, 더 유연하게 관리할 수 있는 기능을 제공합니다.
리소스설명
GatewayClass | Gateway의 템플릿 역할. 특정 구현 또는 제공자의 구성을 정의합니다. |
Gateway | 클러스터의 엣지에서 트래픽을 수신하고 라우팅하는 방법을 정의합니다. |
HTTPRoute | HTTP 트래픽에 대한 세부적인 라우팅 규칙을 정의합니다. |
TCPRoute | TCP 트래픽을 위한 라우팅 규칙을 정의합니다. |
TLSRoute | TLS 트래픽에 대한 라우팅 규칙을 정의합니다. |
Gloo Gateway
- Cluster 생성
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
- containerPort: 30001
hostPort: 30001
- containerPort: 30002
hostPort: 30002
- Gateway CPI CRD 설치
$ kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
$ kubectl get crd
- Glooctl Util 설치
$ docker exec -it myk8s-control-plane bash
----------------------------------------
# Install Glooctl Utility
## glooctl install gateway # install gloo's function gateway functionality into the 'gloo-system' namespace
## glooctl install ingress # install very basic Kubernetes Ingress support with Gloo into namespace gloo-system
## glooctl install knative # install Knative serving with Gloo configured as the default cluster ingress
## curl -sL https://run.solo.io/gloo/install | sh
$ curl -sL https://run.solo.io/gloo/install | GLOO_VERSION=v1.17.7 sh
$ export PATH=$HOME/.gloo/bin:$PATH
# 버전 확인
$ glooctl version
----------------------------------------
- Gloo Gateway 설치
$ helm repo add gloo https://storage.googleapis.com/solo-public-helm
$ helm repo update
$ helm install -n gloo-system gloo-gateway gloo/gloo \
--create-namespace \
--version 1.17.7 \
--set kubeGateway.enabled=true \
--set gloo.disableLeaderElection=true \
--set discovery.enabled=false
$ kubectl rollout status deployment/gloo -n gloo-system
$ kubectl get pod,svc,endpointslices -n gloo-system
$ kubectl get gatewayclasses
- gloo gateway flow
- httpbin 설치
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/solo-blog/main/gateway-api-tutorial/01-httpbin-svc.yaml
# 설치 확인
$ kubectl get deploy,pod,svc,endpointslices,sa -n httpbin
$ kubectl rollout status deploy/httpbin -n httpbin
- httpbin 페이지 접속 확인
- gateway 리소스 생성
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/02-gateway.yaml
############
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: http
spec:
gatewayClassName: gloo-gateway
listeners:
- protocol: HTTP
port: 8080
name: http
allowedRoutes:
namespaces:
from: All
############
- gloo-proxy-http 서비스 변경
# gloo-proxy-http NodePort 30001 설정
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/instance: http
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: gloo-proxy-http
app.kubernetes.io/version: 1.17.7
gateway.networking.k8s.io/gateway-name: http
gloo: kube-gateway
helm.sh/chart: gloo-gateway-1.17.7
name: gloo-proxy-http
namespace: gloo-system
spec:
ports:
- name: http
nodePort: 30001
port: 8080
selector:
app.kubernetes.io/instance: http
app.kubernetes.io/name: gloo-proxy-http
gateway.networking.k8s.io/gateway-name: http
type: LoadBalancer
EOF
$ k get svc -n gloo-system gloo-proxy-http
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gloo-proxy-http LoadBalancer 10.96.165.90 <pending> 8080:30001/TCP 2m14s
- 외부 접근을 위해 port-forward 설정
$ kubectl port-forward deployment/gloo-proxy-http -n gloo-system 8080:8080 &
- route 설정 배포
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/03-httpbin-route.yaml
$ kubectl get httproute -n httpbin
- 접근 확인
$ echo "127.0.0.1 api.example.com" | sudo tee -a /etc/hosts
# 웹브라우저로 접속 http://api.example.com:30001/get"
- 정책 적용 확인
$ curl -is http://localhost:8080/delay/1
gateway route 정책에 /get 경로로 접속되도록 설정이 되어 있기 때문에 그 외 경로인 /delay로 접속 시 에러가 발생합니다.
case 1.
[정규식 패턴 매칭] Explore Routing with Regex Matching Patterns
예시) /api/httpbin/delay/1 ⇒ /delay/1
# Here are the modifications we’ll apply to our HTTPRoute:
- matches:
# Switch from an Exact Matcher(정확한 매팅) to a PathPrefix (경로 매팅) Matcher
- path:
type: PathPrefix
value: /api/httpbin/
filters:
# Replace(변경) the /api/httpbin matched prefix with /
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
- 환경 배포
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/04-httpbin-rewrite.yaml
$ kubectl describe httproute -n httpbin
Spec:
Hostnames:
api.example.com
Parent Refs:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: http
Namespace: gloo-system
Rules:
Backend Refs:
Group:
Kind: Service
Name: httpbin
Port: 8000
Weight: 1
Filters:
Type: URLRewrite
URL Rewrite:
Path:
Replace Prefix Match: /
Type: ReplacePrefixMatch
Matches:
Path:
Type: PathPrefix
Value: /api/httpbin/
- 접속 확인
6w ➤ curl -s http://api.example.com:30001/api/httpbin/delay/1
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "api.example.com:30001",
"User-Agent": "curl/8.7.1",
"X-Envoy-Expected-Rq-Timeout-Ms": "15000",
"X-Envoy-Original-Path": "/api/httpbin/delay/1"
},
"origin": "10.244.0.11",
"url": "http://api.example.com:30001/delay/1"
}
case 2.
[업스트림 베어러 토큰을 사용한 변환] Test Transformations with Upstream Bearer Tokens
목적 : 요청을 라우팅하는 백엔드 시스템 중 하나에서 인증해야 하는 요구 사항이 있는 경우는 어떻게 할까요? 이 업스트림 시스템에는 권한 부여를 위한 API 키가 필요하고, 이를 소비하는 클라이언트에 직접 노출하고 싶지 않다고 가정해 보겠습니다. 즉, 프록시 계층에서 요청에 주입할 간단한 베어러 토큰을 구성하고 싶습니다. (정적 API 키 토큰을 직접 주입)
#
kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/05-httpbin-rewrite-xform.yaml
#
kubectl describe httproute -n httpbin
...
Spec:
...
Rules:
Backend Refs:
Group:
Kind: Service
Name: httpbin
Port: 8000
Weight: 1
Filters:
Type: URLRewrite
URL Rewrite:
Path:
Replace Prefix Match: /
Type: ReplacePrefixMatch
Request Header Modifier:
Add:
Name: Authorization
Value: Bearer my-api-key
Type: RequestHeaderModifier
Matches:
Path:
Type: PathPrefix
Value: /api/httpbin/
[Migrate]
gloo gateway에서 route 전략을 어떻게 활용되는지 확인해 보겠습니다.
테스트를 위한 오브젝트 배포
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/06-workload-svcs.yaml
Test Simple V1 Routing
my-workload-v1으로만 트래픽이 흘러들어가는 route 정책을 설정합니다.
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/07-workload-route.yaml
######################
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: my-workload
namespace: my-workload
labels:
example: my-workload-route
spec:
parentRefs:
- name: http
namespace: gloo-system
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /api/my-workload
backendRefs:
- name: my-workload-v1
namespace: my-workload
port: 8080
- 배포된 httproute 확인
$ k describe httproute -n my-workload
Spec:
Hostnames:
api.example.com
Parent Refs:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: http
Namespace: gloo-system
Rules:
Backend Refs:
Group:
Kind: Service
Name: my-workload-v1
Namespace: my-workload
Port: 8080
Weight: 1
Matches:
Path:
Type: PathPrefix
Value: /api/my-workload
- 접근 테스트
Simulate a v2 Dark Launch with Header-Based Routing
Dark Launch : 일부 사용자에게 새로운 기능을 출시하여 피드백을 수집하고 잠재적으로 더 큰 사용자 커뮤니티를 방해하기 전에 개선 사항을 실험하는 훌륭한 클라우드 마이그레이션 기술
header에 반드시 v2가 있어야 my-workload-v2로 접속할 수 있으며, 일반적인 접속은 my-workload-v1으로 보내집니다.
- 정책 배포
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/08-workload-route-header.yaml
################
rules:
- matches:
- path:
type: PathPrefix
value: /api/my-workload
# Add a matcher to route requests with a v2 version header to v2
# version=v2 헤더값이 있는 사용자만 v2 라우팅
headers:
- name: version
value: v2
backendRefs:
- name: my-workload-v2
namespace: my-workload
port: 8080
- matches:
# Route requests without the version header to v1 as before
# 대다수 일반 사용자는 기존 처럼 v1 라우팅
- path:
type: PathPrefix
value: /api/my-workload
backendRefs:
- name: my-workload-v1
namespace: my-workload
port: 8080
- 접근 테스트
## v1
$ curl -is -H "Host: api.example.com" http://localhost:8080/api/my-workload
$ curl -is -H "Host: api.example.com" http://localhost:8080/api/my-workload | grep body
## v2
$ curl -is -H "Host: api.example.com" -H "version: v2" http://localhost:8080/api/my-workload
$ curl -is -H "Host: api.example.com" -H "version: v2" http://localhost:8080/api/my-workload | grep body
Expand V2 Testing with Percentage-Based Routing
성공적인 다크 런칭 이후, 우리는 점진적으로 이전 버전에서 새 버전으로 사용자 트래픽을 옮기는 블루-그린 전략을 사용하는 기간을 원할 수 있습니다. 트래픽을 균등하게 분할하고 트래픽의 절반을 로 보내고 v1나머지 절반을 로 보내는 라우팅 정책으로 이를 살펴보겠습니다 v2.
$ k apply -f https://raw.githubusercontent.com/solo-io/gloo-gateway-use-cases/main/gateway-api-tutorial/09-workload-route-split.yaml
##############
rules:
- matches:
- path:
type: PathPrefix
value: /api/my-workload
# Configure a 50-50 traffic split across v1 and v2 : 버전 1,2 50:50 비율
backendRefs:
- name: my-workload-v1
namespace: my-workload
port: 8080
weight: 50
- name: my-workload-v2
namespace: my-workload
port: 8080
weight: 50
- 분산 확인
'Cloud > Kubernetes' 카테고리의 다른 글
[KANS] Istio example (bookinfo) (1) | 2024.10.20 |
---|---|
[KANS] istio install + expose (0) | 2024.10.20 |
[KANS] Ingress (0) | 2024.10.13 |
[KANS] LoadBalancer (2) | 2024.10.05 |
[KANS] Service : ClusterIP, NodePort (1) | 2024.09.28 |