DevOps/Study
Istio Hands-on Study [1기] [1주차 연습과제] Kubernetes Gateway API
juyeon22
2025. 4. 16. 22:37
Getting Stared With the Kubernetes Gateway API
Gateway API 란 ?
- 기존 HTTP, HTTPS만 지원하는 Ingress와 다르게, 다양한 프로토콜(L4/L7) 및 고급 네트워크 관리 기능을 지원하는 네트워크 트래픽 관리 API입니다.
- 기존 Ingress는 구현한 벤더별 설정 들에 의존 했지만, Gateway API는 벤더별 의존을 없에고 k8s 내부 표준으로 사용하기 위해 만들었다고 생각합니다.
- Ingress와 다르게
역할 분리
가 명확하게 되어있으며,고급 라우팅
을 적용할 수 있습니다.
Gateway API의 역할 구조
Figure 1 Gateway API 의 역할 사진 출처
- Infrastructure Provider
- Cloud 서비스를 사용하는 경우 CSP 제공자, On-premise 환경인 경우에는 System Engineer Role 역할입니다.
클러스터가 사용할 수 있는 기본 네트워킹 인프라(예: 클라우드 로드밸런서, 온프레미스 하드웨어 로드밸런서, 클러스터 내 프록시 소프트웨어)를 관리하고 제공합니다.
- Cluster Operator
- Kubernetes의 Resource를 관리하는 (DevOps Engineer, SRE) 역할입니다.
- Kubernetes 클러스터의 전반적인 관리, 정책 적용, 네트워크 접근 제어, 애플리케이션 권한 등을 책임지며, 클러스터가 여러 사용자나 팀의 요구사항을 충족하도록 관리합니다.
- Application Developer
- 애플리케이션의 비즈니스 로직에 집중하며, 애플리케이션 노출 및 라우팅 설정에 집중합니다.
Gateway API의 통신 방식
Figure 2 Ingress의 통신 방식 사진 출처
sequenceDiagram
participant User as 외부 사용자
participant GatewayClass as GatewayClass (Gateway API)
participant Gateway as Gateway (Gateway API)
participant HTTPRoute as HTTPRoute
participant Service as Kubernetes Service
participant Pod as Pod (애플리케이션)
Note over GatewayClass,Gateway: 클러스터 관리자가 GatewayClass를 생성 및 관리
Note over Gateway,HTTPRoute: 개발자가 Gateway와 HTTPRoute를 생성 및 연결
User->>Gateway: HTTP/HTTPS 요청 (예: example.com)
Gateway->>GatewayClass: GatewayClass에 따라 트래픽 처리 방식 결정
Gateway->>HTTPRoute: 요청 정보 전달 (호스트/경로 매칭)
HTTPRoute->>Service: 라우팅 규칙에 따라 서비스로 전달
Service->>Pod: 요청 전달 (ClusterIP/Pod IP)
Pod-->>Service: 응답 반환
Service-->>HTTPRoute: 응답 반환
HTTPRoute-->>Gateway: 응답 반환
Gateway-->>User: 응답 반환
Figure 3 Gateway API의 통신 방식
Gateway API의 주요 구성요소
- Gateway Class
Ingress
와 비교 시IngressClass
객체와 매핑되는 객체입니다.- Gateway가 트래픽 처리할
컨트롤러
를 정하고 어떻게 작동할지 참고하는 객체입니다.
- Gateway
Ingress
와 비교 시Ingress
객체와 매핑되는 객체입니다.트래픽의 진입점
역할을 하며, Kubernetes 클러스터 내부로 어떤 트래픽을 인입을 허용할 것 인지 규정하는 객체입니다.- TLS 종료와 인증서 지정 기능 또한 제공하는 객체입니다.
- HTTP/gRPC/TCP/UDP/TLS(L4/L7) Route
Ingress
와 비교 시Ingress
객체의.spec.rules.
항목에 매핑되는 객체입니다.트래픽 Route 규칙
을지정
하는 역할을 하며, Kubernetes 클러스터 내부의 어떤 서비스로 라우팅을 할지 규정하는 객체입니다.
Istio 와 Gateway API 비교
- Gateway API는 Istio Ingress/Egress Gateway와 다르게
North-South
지점에 위치해서 작동합니다. - Istio Service Mesh에서는
North-South
지점 뿐만 아니라,East-South
환경에서도 작동이 필요하기 때문에,GAMMA (Gateway API for Mesh Management and Administration)
가 생성되어East-West
트래픽 관리 방법이 정의됐습니다.
Istio Virtual Service
apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
HTTP Route
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- group: ""
kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- name: reviews-v1
port: 9080
Gateway API를 적용한 Istio 예제 실습
실습환경 구성
# Cluster 생성
kind create cluster --name myk8s --image kindest/node:v1.32.2 --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000 # Sample Application
hostPort: 30000
- containerPort: 30001 # Prometheus
hostPort: 30001
- containerPort: 30002 # Grafana
hostPort: 30002
- containerPort: 30003 # Kiali
hostPort: 30003
- containerPort: 30004 # Tracing
hostPort: 30004
- containerPort: 30005 # kube-ops-view
hostPort: 30005
networking:
podSubnet: 10.10.0.0/16
serviceSubnet: 10.200.1.0/24
EOF
# 클러스터 접속
docker exec -it myk8s-control-plane /bin/bash
# 기본 툴 설치
apt update && apt install tree psmisc lsof wget bridge-utils net-tools dnsutils tcpdump ngrep iputils-ping git vim -y
# Gateway CRD 설치
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.1" | kubectl apply -f -; }
# Istio 설치
export ISTIOV=1.25.1
curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=$ISTIOV sh -
cp istio-$ISTIOV/bin/istioctl /usr/local/bin/istioctl
istioctl install --set profile=minimal -y
# 샘플코드 경로 이동
cd istio-$ISTIOV
# 설치 결과 확인
kubectl get crd | grep .istio.io
# Result (Do Not Copy This!)
authorizationpolicies.security.istio.io
destinationrules.networking.istio.io
envoyfilters.networking.istio.io
gateways.networking.istio.io
peerauthentications.security.istio.io
proxyconfigs.networking.istio.io
requestauthentications.security.istio.io
serviceentries.networking.istio.io
sidecars.networking.istio.io
telemetries.telemetry.istio.io
virtualservices.networking.istio.io
wasmplugins.extensions.istio.io
workloadentries.networking.istio.io
workloadgroups.networking.istio.io
# Prometheus, Kiali, Grafana, jaeger 설치
kubectl apply -f samples/addons
# NodePort 변경 및 nodeport 30001~30003으로 변경 : prometheus(30001), grafana(30002), kiali(30003), jaeger(30004)
kubectl patch svc -n istio-system prometheus -p '{"spec": {"type": "NodePort", "ports": [{"port": 9090, "targetPort": 9090, "nodePort": 30001}]}}'
kubectl patch svc -n istio-system grafana -p '{"spec": {"type": "NodePort", "ports": [{"port": 3000, "targetPort": 3000, "nodePort": 30002}]}}'
kubectl patch svc -n istio-system kiali -p '{"spec": {"type": "NodePort", "ports": [{"port": 20001, "targetPort": 20001, "nodePort": 30003}]}}'
kubectl patch svc -n istio-system tracing -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 16686, "nodePort": 30004}]}}'
# default 네임스페이스에 istio-proxy sidecar 주입
kubectl label namespace default istio-injection=enabled
# 샘플 애플리케이션 배포
kubectl apply -f samples/httpbin/httpbin.yaml
Gateway API를 적용한 Istio 구성
# 테스트를 위한 namespace 생성
kubectl create namespace istio-ingress
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway
namespace: istio-ingress
spec:
gatewayClassName: istio
listeners:
- name: default
hostname: "*.example.com"
port: 80
protocol: HTTP
allowedRoutes:
namespaces:
from: All
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http
namespace: default
spec:
parentRefs:
- name: gateway
namespace: istio-ingress
hostnames: ["httpbin.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
backendRefs:
- name: httpbin
port: 8000
EOF
kubectl get gateway -n istio-ingress
# Result (Do Not Copy This!)
NAME CLASS ADDRESS PROGRAMMED AGE
gateway istio False 13s
# NodePort 로 변경
kubectl annotate gateway -n istio-ingress gateway networking.istio.io/service-type=NodePort --overwrite
# Gateway 설정 확인
kubectl get svc -n istio-ingress gateway-istio
# Result ((Do Not Copy This!)
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gateway-istio NodePort 10.200.1.158 <none> 15021:32525/TCP,80:31697/TCP 2m24s
# NodePort 를 30000번으로 변경
kubectl patch svc -n istio-ingress gateway-istio -p '{"spec": {"type": "NodePort", "ports": [{"port": 80, "targetPort": 80, "nodePort": 30000}]}}'
# HTTP Routie 객체 생성
kubectl apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http
namespace: default
spec:
parentRefs:
- name: gateway
namespace: istio-ingress
hostnames: ["httpbin.example.com"]
rules:
- matches:
- path:
type: PathPrefix
value: /get
- path:
type: PathPrefix
value: /headers
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: my-added-header
value: added-value
backendRefs:
- name: httpbin
port: 8000
EOF
# 테스트를 위해 curl 수행
while true; do curl -s -HHost:httpbin.example.com "http://127.0.0.1:30000/headers" | jq '.headers["My-Added-Header"][0]' ; sleep 0.5; echo; done
Figure 4 Kiali로 확인 결과