이 스터디는 CloudNet@에서 진행하는 KANS 스터디를 참여하면서 공부하는 내용을 기록하는 블로그 포스팅입니다.
CloudNet@에서 제공해주는 자료들을 바탕으로 작성되었습니다.
Gateway API
Gateway API는 Kubernetes의 네트워크 라우팅을 확장(L4 및 L7 라우팅)하고 개선하기 위해 설계된 API입니다. 기존의 Ingress API를 대체하거나 보완할 수 있는 방식으로, 더 복잡한 네트워크 트래픽 관리 시나리오를 지원합니다.
즉, 기존의 Ingress에 다양한 기능(헤더 기반 라우팅, 헤더 변조, 트래픽 미러링(쉽게 트래픽 복제), 역할 분리 등)이 추가된 차세대 Kubernetes Ingress, LoadBalancing, service mesh API를 대표 하는 API입니다.
주요 기능
유연한 라우팅
Ingress가 상대적으로 단순한 HTTP 경로 기반 라우팅을 제공하는 것에 비해, Gateway API는 L4 및 L7 트래픽을 모두 지원하며, 더 세분화된 조건 및 매칭을 설정할 수 있습니다.
Multi-Tenancy 지원
Gateway API는 다중 테넌트 환경에서 네트워크 리소스를 더 안전하게 분리하고 관리할 수 있도록 설계되었습니다.
Multi-Tenancy란
하나의 소프트웨어 인프라 또는 시스템이 여러 사용자나 조직(테넌트)에 의해 동시에 공유되는 아키텍처를 의미합니다. 이 개념은 클라우드 서비스, SaaS(Software as a Service) 및 가상화 환경에서 자주 사용되며, 멀티 테넌트 환경에서는 각 테넌트가 독립적인 애플리케이션 인스턴스처럼 서비스를 이용할 수 있지만, 실제로는 동일한 시스템과 자원을 공유합니다.
확장성
인프라와 상관없이 다양한 게이트웨이 구현과 통합될 수 있도록 확장 가능하며, 클라우드 및 온프레미스 환경에서 모두 사용할 수 있습니다.
서비스 메쉬 통합
Gateway API는 서비스 메쉬와 자연스럽게 통합되어, 애플리케이션 레벨에서 네트워크 트래픽을 더 정교하게 관리할 수 있는 기능을 제공합니다.
교차 네임스페이스 지원
서로 다른 네임스페이스의 서비스로 트래픽을 라우팅하여 보다 유연한 아키텍처를 구축할 수 있는 기능을 제공합니다.
역할 지향
클러스터 운영자, 애플리케이션 개발자, 보안 팀 간의 우려를 명확하게 분리합니다. 즉, 담당 업무의 역할에 따라서 동작/권한을 유연하게 제공할 수 있습니다. 위의 그림처럼 'Store Developer'는 'Store' 네임스페이스내에서 해당 store HTTPRuring 관련 정책을 스스로 관리할 수 있습니다.
Resource model
GatewayClass
Gateway의 Class(공통 구성)를 정의하며, 여러 Gateway 인스턴스가 GatewayClass를 기반으로 생성됩니다.
Gateway
Gateway는 GatewayClass를 기반으로 생성되며, Listener를 통해 외부 트래픽을 처리합니다. 즉, Gateway는 트래픽을 수신하고 이를 Route 리소스에 따라 백엔드 서비스로 전달합니다.
HTTPRoute
Gateway의 Listener에서 수신한 트래픽을 백엔드 서비스나 네트워크 엔드포인트로 라우팅하는 HTTP 전용 규칙을 설정합니다. HTTP 경로, 호스트명, 헤더 등의 조건을 기반으로 트래픽을 처리합니다.
Request flow
클라이언트가 요청을 보냄
클라이언트는 외부에서 HTTP, HTTPS 또는 TCP 등의 프로토콜을 사용하여 요청을 보냅니다.
Gateway에서 Listener가 요청을 수신
Gateway는 Listener를 통해 네트워크 트래픽을 수신합니다. 각 Listener는 프로토콜과 포트(예: HTTPS 포트 443)에 대한 트래픽을 처리하도록 설정되어 있습니다. 이때, Gateway는 여러 Listener를 가질 수 있으며, 각 Listener는 서로 다른 트래픽을 처리할 수 있습니다.
Listener가 Route로 트래픽 전달
Listener는 수신한 트래픽을 처리할 때, Route 리소스(HTTPRoute, TCPRoute)를 참조하여 트래픽을 어떻게 처리할지 결정합니다. 이때, 각 Route 리소스는 특정 조건에 맞는 트래픽을 처리하도록 규칙을 정의합니다.(마치 ingress처럼)
Route가 트래픽을 백엔드로 라우팅
Route는 규칙에 맞는 트래픽을 백엔드 서비스로 라우팅합니다.
백엔드가 요청 처리
백엔드 엔드포인트가 실제로 클라이언트의 요청을 처리합니다.
Gloo Gateway
Gloo Gateway는 Cloud Native의 Layer 7 proxy로 Envoy와 Kubernetes Gateway API를 기반의 오픈소스 프로젝트입니다. 또한, Kubernetes 기반 애플리케이션 및 마이크로서비스 환경에서의 트래픽 라우팅, 로드 밸런싱, 인증, 인가, API 통합 등을 효율적으로 관리할 수 있도록 돕습니다.
주요 기능
트래픽 라우팅 및 로드 밸런싱
다양한 백엔드 서비스로의 HTTP, gRPC, TCP 트래픽을 라우팅하고, 로드 밸런싱 및 트래픽 분산을 지원합니다.
API 관리
RESTful API와 gRPC API를 관리하며, API 게이트웨이 역할을 통해 API 인증, 인가, 트래픽 제어를 수행할 수 있습니다.
보안 기능
TLS/SSL 종단 간 암호화, OAuth2, OIDC, JWT 인증을 지원하여 안전한 API 액세스를 보장합니다.
서비스 메쉬 통합
Istio, Consul, Linkerd와 같은 서비스 메쉬와 통합하여 마이크로서비스 간 트래픽을 쉽게 관리할 수 있습니다.
Kubernetes 네이티브
Kubernetes 클러스터에서 네이티브로 동작하며, CRD(Custom Resource Definitions)를 통해 사용자 정의 리소스를 사용해 구성을 제어할 수 있습니다.
아키텍처
Gloo 및 Kubernetes Gateway API custom resources를 Envoy configuration으로 변환 과정
1. Gloo Pod 내의 Config 및 Secret Watcher 컴포넌트는 Kubernetes Gateway API 및 Gloo Gateway 리소스(Gateways, HTTPRoutes, RouteOptions)와 같은 새로운 리소스를 클러스터에서 감시합니다.
2. config 또는 secret watche가 새로운 리소스 또는 업데이트된 리소스를 감지하면, 해당 리소스의 구성을 Gloo Gateway 변환 엔진으로 전송합니다.3. 변환 엔진은 Kubernetes Gateway API 및 Gloo Gateway 리소스를 Envoy 설정으로 변환합니다. (이때, 모든 Envoy 설정은 xDS 스냅샷으로 통합됩니다.)
4. 변환기(Translator)가 처리한 각 리소스에 대한 상태 보고서를 리포터가 수신합니다.
5. 리포터는 리소스 상태를 etcd 데이터 스토어에 다시 기록합니다.
6. xDS 스냅샷은 Gloo Pod 내의 Gloo Gateway xDS 서버 컴포넌트에 제공됩니다.
7. 클러스터의 게이트웨이 프록시는 Gloo Gateway xDS 서버에서 최신 Envoy 설정을 가져옵니다.
8. 사용자는 게이트웨이 프록시가 노출된 IP 주소나 호스트명으로 요청을 보냅니다.
9. 게이트웨이 프록시는 xDS 스냅샷에 제공된 리스너 및 경로별 설정을 사용해 라우팅 결정을 내리고 클러스터 내의 목적지로 요청을 전달합니다.
Config Watcher
Kubernetes Gateway API 및 Gloo Gateway 리소스(Gateways, HTTPRoutes, Upstreams)를 감시합니다. 이에 따라, 새로운 리소스나 업데이트된 리소스를 감지하면 해당 Kubernetes 구성을 Gloo Gateway 변환 엔진으로 전송합니다.
Secret Watcher
Secret Store에서 Secrets의업데이트를 감시합니다.
예를 들어, AWS Lambda에 접근하기 위한 AWS 자격 증명을 Kubernetes Secret에 저장할 수 있으며, Gloo Gateway는 HashiCorp Vault와 같은 다른 비밀 저장소도 감시하도록 구성할 수 있습니다.
Endpoint Discovery
Kubernetes, Cloud Foundry, Consul과 같은 Service Registries에서 Service와 연관된 IP 주소와 호스트명을 감시합니다. 각 엔드포인트는 자체 플러그인이 필요하며, 새로운 엔드포인트가 발견되면 해당 구성이 etcd에 저장됩니다.
Translation engine
사용자가 생성하거나 업데이트한 모든 Kubernetes Gateway API, Kubernetes API, 및 Gloo Gateway 리소스의 Snapshot을 전달 받습니다. 각각 업데이트마다 새로운 변환 루프를 시작하고, 이러한 리소스를 마다 유효한 Envoy 설정으로 변환하고, 변환된 Envoy 설정은 Envoy xDS 스냅샷에 저장됩니다.
Deployment patterns
Gloo Gateway는 각자의 환경에 가장 적합한 방식으로 배포할 수 있도록 유연하게 설계되었습니다.
Simple ingress
Simple Ingress type의 Gateway는 Gloo Gateway Control Plane에 의해 중앙에서 관리되며, 사용자가 정의한 트래픽 관리, 보안 규칙에 따라 트래픽을 매칭하고 전달하도록 구성합니다.
이 설정은 Gloo Gateway를 시작하기에 좋은 방법으로, 모든 워크로드가 단일 클러스터에서 실행되고 서비스 간에 트래픽이 균형을 이루는 작은 환경에 적합합니다.
Sharded Gateway
더 큰 환경이거나 많은 트래픽을 받는 서비스와 적은 트래픽을 받는 Service가 동시에 있는 환경에서는 Sharded Gateway를 사용하여 Service를 서로 분리하고 noisy neighbors로부터 보호할 수 있습니다. 이 아키텍처에서는 일반적으로 여러 개의 Gateway Proxy를 사용하여 클러스터 내의 다양한 서비스로 트래픽을 분산시키는 방식으로 작동합니다.
Gateway Proxy는 Gloo Gateway Control Plane에 의해 관리되지만, 첫번째 Gateway Proxy는 foo 및 bar 네임스페이스에 있는 워크로드의 트래픽을 관리하고, 두 번째 Gateway Proxy는 extra 네임스페이스에 있는 워크로드를 위한 전용 API 게이트웨이로 작동합니다.
Noisy neighbor
서비스가 과도하게 자원을 사용하여 성능 저하를 일으키는 상황을 설명하는 용어입니다. 특히, 클라우드나 공유 인프라 환경에서 자원을 공유하는 여러 애플리케이션 중 하나가 너무 많은 CPU, 메모리, 네트워크 대역폭 등을 사용하면 다른 애플리케이션의 성능이 저하될 수 있는데, 이를 소음이 많은 이웃(Noisy neighbor) 문제라고 합니다.
Sharded gateway with central ingress
이 Gateway Proxy는 클러스터로 들어오는 모든 트래픽에 공통된 트래픽 관리, 보안 규칙등을 적용하도록 구성합니다. 예를 들어, 트래픽을 두 번째 계층의 Gateway Proxy로 전달하기 전에 글로벌 속도 제한(global rate limits)이나 헤더 조작 정책(header manipulation policies)을 설정할 수 있습니다. 즉, 모든 트래픽을 처리하는 게이트웨이에 중앙 IP 주소와 DNS 이름이 필요한 경우 유용합니다.
두 번째 계층의 Gateway Proxy는 특정 애플리케이션에 대한 추가 트래픽 관리, 탄력성, 및 보안 정책을 들어오는 트래픽에 적용할 수 있습니다. 또한, 두 번째 계층의 프록시를 Shard하여 트래픽 서비스를 더 잘 분리함으로써 noisy neighbor를 방지할 수 있습니다.
위의 그림처럼 기존에 설정한 값에 따라 중앙 인그레스 엔드포인트로 다른 유형의 프록시를 사용할 수 있습니다. 예를 들어, 모든 트래픽이 반드시 통과해야 하는 HAProxy나 AWS NLB/ALB 인스턴스를 사용할 수 있습니다.
API gateway for a service mesh
Gloo Gateway는 서비스 메시로 들어오고 나가는 모든 인그레스 및 이그레스 트래픽에 대한 API 게이트웨이로 배포할 수 있습니다.
서비스 메시 내의 서비스들은 상호 TLS(mTLS)를 통해 서로 통신합니다. 이때, Gloo Gateway 프록시는 Istio 사이드카와 함께 구성되며, 메시 내의 서비스들과 신뢰할 수 있는 mTLS 연결을 설정할 수 있습니다.
실습
실습 환경 설정
kind yaml 파일 정의
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
kind cluster 생성
kind create cluster --image kindest/node:v1.30.0 --config kind-1node.yaml --name myk8s
Node 및 Pod 확인
kubectl get nodes -o wide
kubectl get po -A
Gateway API CRDs 설치
Kubernetes Gateway API는 Kubernetes CRD(CustomResourceDefine)으로 구현됩니다.
CRDs 설치
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
CRDs 확인
kubectl get crd
Glooctl Utility
GLOOCTL은 사용자가 Gloo Gateway deployment를 보고, 관리하고, 디버깅 할 수 있는 cli tool입니다.
Glooctl Utility 설치
curl -sL https://run.solo.io/gloo/install | GLOO_VERSION=v1.17.7 sh
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
환경 변수 설정
export PATH=$HOME/.gloo/bin:$PATH
설치 확인
kubectl get crd | grep 'networking.k8s.io'
kubectl get crd | grep -v 'networking.k8s.io'
kubectl get pod,svc,endpointslices -n gloo-system
kubectl get gatewayclasses
Httpbin Application 실습
Httpbin Application 설치
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
Deployment가 성공적으로 배포되었는지, 아니면 아직 진행 중인지, 혹은 실패했는지를 알 수 있는 rollout status를 확인해보겠습니다.
NodePort 설정
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
labels:
app: httpbin
service: httpbin
name: httpbin
namespace: httpbin
spec:
type: NodePort
ports:
- name: http
port: 8000
targetPort: 80
nodePort: 30000
selector:
app: httpbin
EOF
로컬 접속 확인
echo "httpbin web - http://localhost:30000"
규칙 설정
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: httpbin
namespace: httpbin
labels:
example: httpbin-route
spec:
parentRefs:
- name: http
namespace: gloo-system
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: Exact
value: /get
backendRefs:
- name: httpbin
port: 8000
URL을 api.example.com인 hostname으로 접속하면 Maches의 Path 규칙에 따라 라우팅이 설정되도록 HTTPRoute를 설정합니다. 이때, 규조가 ingress와 상당히 비슷한 구조인것을 확인하실 수 있습니다.
httpbin 확인
kubectl get httproute -n httpbin
kubectl describe httproute -n httpbin
local에서 Hostname인 api.example.com으로 접속하면 Maches의 Path 규칙에 따라 라우팅이 설정되는 것을 확인할 수 있습니다.
/etc/hosts 설정
echo "127.0.0.1 api.example.com" | sudo tee -a /etc/hosts
local에서 확인하기 위해서는 mac인 경우 /etc/hosts에 host를 설정해줍니다.
Curl로 접근 확인
'스터디 이야기 > Kubernetes Advanced Networking Study' 카테고리의 다른 글
[KANS] Cilium CNI - eBPF (3) | 2024.10.23 |
---|---|
[KANS] Service Mesh - Istio (7) | 2024.10.17 |
[KANS] Ingress (2) | 2024.10.09 |
[KANS] Service - LoadBalancer (MetalLB) (2) | 2024.10.04 |