Kubernetes Ingress
Ingress
- 쿠버네티스 인그레스(Ingress)는 클러스터 외부의 트래픽을 내부 서비스로 라우팅하는 중요한 API 객체입니다.
- 클러스터 내의 서비스에 외부에서 접근하기 위해 NodePort나 LoadBalancer를 사용할 수 있지만, Ingress를 이용하면 더 효율적이고 유연하게 트래픽을 관리할 수 있습니다.
- Ingress는 경로 기반 및 호스트 기반의 라우팅 규칙을 설정할 수 있습니다.
- TLS 인증서를 활용해 HTTPS 트래픽을 처리할 수 있어 복잡한 웹 애플리케이션 환경에서도 효과적인 트래픽 관리가 가능합니다.
https://kubernetes.io/docs/concepts/services-networking/ingress/
Ingress-Controller
- 인그레스 컨트롤러(Ingress Controller)는 Ingress 리소스를 실제로 관리하고 트래픽을 라우팅하는 컴포넌트입니다.
- 인그레스 객체 자체는 트래픽을 처리하는 기능을 수행하지 않으며, Ingress Controller가 필요한 설정과 처리를 담당합니다.
- 대표적인 Ingress Controller로는
NGINX
,Traefik
,HAProxy
등이 있으며, 각 컨트롤러는 고유한 기능과 설정 옵션을 제공합니다. - 인그레스 컨트롤러는 클러스터에 설치되어 외부에서 들어오는 HTTP/HTTPS 요청을 적절한 서비스로 라우팅하는 역할을 합니다.
- 쿠버네티스에서는 Ingress Controller를 사용해 다양한 방식으로 트래픽을 효율적으로 제어하고 관리할 수 있습니다.
Ingress 기본 사용
Nginx 인그레스 컨트롤러 설치
- 기본적으로 가장 많이 사용되는 Nginx Ingress Controller를 설치합니다.
- 간편한 테스트를 위해서 NodePort 타입(externalTrafficPolicy: Local) 설정합니다.
# Ingress-Nginx 컨트롤러 생성
cat <<EOT> ingress-nginx-values.yaml
controller:
service:
type: NodePort
nodePorts:
http: 30080
https: 30443
nodeSelector:
kubernetes.io/hostname: "k3s-s"
metrics:
enabled: true
serviceMonitor:
enabled: true
EOT
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
kubectl create ns ingress
helm install ingress-nginx ingress-nginx/ingress-nginx -f ingress-nginx-values.yaml --namespace ingress --version 4.11.2
# 확인
kubectl get all -n ingress
kc describe svc -n ingress ingress-nginx-controller
# externalTrafficPolicy 설정
kubectl patch svc -n ingress ingress-nginx-controller -p '{"spec":{"externalTrafficPolicy": "Local"}}'
인그레스 내부 통신 흐름
인그레스 컨트롤러 파드는 K8S API서버로부터 서비스의 엔드포인트 정보(파드 IP)를 획득 후 바로 파드의 IP로 연결합니다.
X-Fowarded-For(XFF)
- XFF 헤더는 원래 클라이언트의 IP 주소를 추적하기 위해 프록시나 로드 밸런서를 거친 요청에 추가되는 HTTP 헤더입니다.
- 파드는 외부 클라이언트의 IP 획득을 위해서 사용됩니다.
Kubernetes Gateway API
쿠버네티스 공식문서에도 더이상 Ingress를 업그레이드 하지 않고, Gateway API를 사용하라고 권장하고 있습니다.
Kubernetes Gateway API vs API Gateway
Kubernetes Gateway API와 API Gateway는 이름이 비슷하지만(순서 주의!), 각기 다른 역할을 합니다.
API Gateway
API Gateway는 여러 서비스 사이에 위치하며, 다양한 API를 하나로 모아 관리합니다. 주요 기능은 다음과 같습니다:
API 서버들의 엔드포인트 단일화 및 관리
- 인증과 권한 부여: 서비스 사용자를 확인하고 권한을 부여합니다.
- 라우팅: 클라이언트 요청을 적절한 서비스로 전달합니다.
- 고급 기능: 서킷 브레이커, 트래픽 관리 등 시스템 안정성을 위한 기능을 제공합니다.
Kubernetres Gateway API
Kubernetes Gateway API는 Kubernetes 클러스터 내부에서 네트워크 트래픽을 관리하는 API입니다. 기존 Ingress보다 더 많은 기능을 제공하며, 클러스터 내 서비스 간의 연결을 돕습니다.
Kubernetes 클러스터 내부에서 실행되는 서비스에 대한 트래픽 관리
- 유연한 네트워크 설정: L4 및 L7 네트워크 설정을 지원합니다.
- 확장성: 여러 도메인과 프로토콜을 관리할 수 있습니다.(GPRC,TCP,UDP)
- 호환성: 여러 컨트롤러와 호환되어 Kubernetes 생태계에서 활용성이 높습니다.
인그레스의 한계와 책임 역할 분리
Kubernets의 Ingress는 HTTP 라우팅을 위해 지금도 많이 사용되고 있지만 몇 가지 한계가 존재하였습니다.
- 기능 제한: 주로 L7 레벨에서 동작하며, L4 네트워크 설정과 고급 기능을 지원하는 데 한계가 있습니다.
- 확장성 부족: 복잡한 라우팅 요구사항과 대규모 클러스터 환경에 적합하지 않습니다.
- 역할 분리 부족: 인프라 제공자와 개발자 간의 책임이 명확하지 않아 관리가 복잡합니다.
책임과 역할 분리
Gateway API는 역할을 명확히 분리하여 문제를 해결합니다:
인프라 소유자의 통제를 유지하면서 사용자에게 유연성을 제공. 개발자는 자유롭게 HTTP Routing 설정을 할 수 있음.
- 인프라 제공자: 네트워크 설정과 제어를 담당합니다.(Gateway Class)
- 클러스터 운영자: 네트워크 설정과 트래픽 흐름을 관리합니다. (Gateway)
- 애플리케이션 개발자: 서비스와 관련된 네트워크 설정을 관리합니다. (HTTPRoute)
이렇게 역할을 분리함으로써 관리 효율성을 높이고 개발자는 더 유연하게 작업할 수 있습니다.
Gateway API 핵심 컴포넌트
1. 게이트웨이 클래스(GatewayClass) - 네트워크 인프라 템플릿
GatewayClass는 네트워크 인프라의 템플릿 역할을 합니다. 클러스터에서 사용할 수 있는 Gateway의 유형을 정의하고, 특정 클라우드 제공자의 게이트웨이 컨트롤러 연결합니다. ingress의 ingressClass, pv의 storageclass와 유사하다고 할 수 있습니다.
2. 게이트웨이(Gateway) - 트래픽 엔트리포인트
Gateway는 L4 계층의 통신을 제어하며, TCP/UDP와 같은 전송 계층의 프로토콜을 처리합니다.
여러 경로(Route)를 Gateway에 연결하여 다양한 프로토콜(HTTP,HTTPS,TPC 등)을 처리하고 트래픽을 적절한 서비스로 전달합니다.
3. HTTPRoute - 라우팅 규칙 정의
HTTPRoute는 L7 계층의 통신을 제어하며, 애플리케이션 계층에서 HTTP/HTTPS 요청처리합니다.
트래픽을 세밀하게 제어할 수 있도록 도와줍니다. 예를 들어, 특정 URL 경로는 A 서비스로, 다른 경로는 B 서비스로 라우팅하는 등의 세부적인 트래픽 제어가 가능합니다
Gateway API 실습 : Gloo Gateway
현재 다양한 게이트웨이 컨트롤러를 지원하고 있습니다. 이번 포스팅에서는 Gloo Gateway를 실습을 진행해보겠습니다.
https://gateway-api.sigs.k8s.io/implementations/
Gloo Gateway 란?
Gloo Gateway Architecture
Gloo Gateway는 Solo.io에서 개발한 차세대 API 게이트웨이로, Envoy Proxy를 기반으로 구축된 솔루션입니다. Kubernetes 네이티브 환경에서 API 트래픽을 관리, 보호, 관찰하는 데 중점을 둡니다.
https://docs.solo.io/gateway/latest/about/architecture/
주요 기능
- Envoy 기반: Gloo Gateway는 Envoy Proxy를 활용해 고급 라우팅, 보안, 관찰 기능을 제공합니다. HTTP/1, HTTP/2, gRPC 등 다양한 프로토콜을 지원하며, 클라우드 네이티브 애플리케이션과 쉽게 통합할 수 있습니다.
- API Gateway와 Ingress 기능 통합: Gloo Gateway는 API Gateway와 Kubernetes Ingress 기능을 통합하여 설치와 관리를 간소화합니다.
- 확장성과 유연성: 멀티 클러스터 환경과 다양한 클라우드 플랫폼을 지원해 마이크로서비스 아키텍처에서 중요한 역할을 합니다.
- 보안 기능: TLS 종료, 인증 및 권한 부여, WAF 등의 보안 기능으로 외부 공격으로부터 서비스를 보호합니다.
- 고급 트래픽 관리: 라우팅, 로드 밸런싱, 요청 및 응답 변환, 속도 제한 등의 기능으로 트래픽을 세밀하게 제어할 수 있습니다.
실습 환경 구성
실습 환경은 다음과 같습니다.
- Mac OS m1
- Orbstack(Docker)
- kind(Kubernetes )
M1 환경에서(arm), Gloo Gateway를 설치하려면, rosetta 옵션을 비활성화 해주어야 합니다.
Docker Descktop
orbstack
# rosetta 비활성화
orb config set rosetta false
# orb 설정 확인
orb config show
# orbstack 재시작
orb stop
orb start
Kind로 실습할 쿠버네티스 클러스터를 구성합니다.
cat <<EOT> kind-1node.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
EOT
# Install KinD Cluster
kind create cluster --image kindest/node:v1.30.0 --config kind-1node.yaml --name myk8s
# 노드에 기본 툴 설치
docker exec -it myk8s-control-plane sh -c 'apt update && apt install tree psmisc lsof wget bsdmainutils bridge-utils net-tools dnsutils tcpdump ngrep iputils-ping git vim -y'
# 노드/파드 확인
kubectl get nodes -o wide
kubectl get pod -A
Gateway API CRDs 설치 및 확인
# CRDs 설치 및 확인
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
kubectl get crd
Gloo Geteway 설치
Glooctl 설치
# [신규 터미널] 아래 bash 진입 후 glooctl 툴 사용
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 get crd | grep 'networking.k8s.io'
kubectl get crd | grep -v 'networking.k8s.io'
kubectl get pod,svc,endpointslices -n gloo-system
httpbin
http 요청을 테스트 하기 위해 httpbin
을 설치합니다.
# Install Httpbin Application
kubectl apply -f https://raw.githubusercontent.com/solo-io/solo-blog/main/gateway-api-tutorial/01-httpbin-svc.yaml
gloo-proxy-http 서비스를 외부 30001포트로 노출합니다.
# 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
HTTPRoute Configuration
다양한 라우팅 룰을 설정합니다.
httproute-simple.yaml
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 Rewrite
- Exact
- 요청 경로가 지정된 경로와 정확히 일치해야 함
- /example 설정 시, /exmaple 요청만 매칭, /example/ 또는 /example/other은 매칭되지 않음
- PathPrefix
- 요청 경로가 지정된 경로로 시작해야 함
- /example 설정 시, /example/, /example/, /example/other와 같은 모든 경로가 매칭.
# 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: /
가장 일반적으로 사용되는 룰로, 클라이언트에서 요청한 URL이 변경되어, 서버로 요청됩니다.
업스트림 베어러 토큰을 사용한 변환
인증에 사용되는 Bearer 토큰을 클라이언트 헤더에서 요청하지 않고, HTTPRoute로 설정합니다.
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
# Add a Bearer token to supply a static API key when routing to backend system
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: Authorization
value: Bearer my-api-key
클라이언트에서 토큰을 직접 노출하지 않고 프록시를 통해 주입됨을 확인할 수 있습니다.
Migrate
룰에 정의한 Header 값으로 특정 서비스로 라우팅 할 수 있습니다.
rules:
- matches:
- path:
type: PathPrefix
value: /api/my-workload
# Add a matcher to route requests with a v2 version header to 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
- path:
type: PathPrefix
value: /api/my-workload
backendRefs:
- name: my-workload-v1
namespace: my-workload
port: 8080
정의한 요청 헤더를 통해 특정한 서비스를 전달 할 수 있기 때문에, 카나리 배포 등에 활용할 수 있습니다.
'Kubernetes > Network' 카테고리의 다른 글
eBPF & Cilium CNI - KANS 8주차 (3) | 2024.10.27 |
---|---|
Istio & Service Mesh- KANS 7주차 (4) | 2024.10.20 |
kube-proxy IPVS 모드의 동작 원리 이해 - KANS 5주차 2 (1) | 2024.10.06 |
MetalLB를 활용한 LoadBalancer 서비스의 동작 원리 이해 - KANS 5주차 1 (2) | 2024.10.06 |
Calico CNI 기본 네트워크 이해 & 네트워크 모드 - KANS 3주차 (4) | 2024.09.22 |