Kubernetes에서 서비스를 외부로 노출할 때는 보통 Ingress를 많이 사용합니다.
하지만 최근에는 Ingress보다 더 확장성 있고 명확한 라우팅 모델을 제공하는 Gateway API를 사용할 수 있습니다.
이번 글에서는 로컬 Kubernetes 환경에서 port-forward 없이 서비스에 접근하기 위해 Gateway API와 Envoy Gateway를 구성한 과정을 정리합니다.
구성에 사용한 주요 요소는 다음과 같습니다.
- Gateway API
- Kubernetes에서 외부 트래픽을 서비스로 라우팅하기 위한 표준 API입니다.
- GatewayClass, Gateway, HTTPRoute 같은 리소스를 사용해 라우팅 구성을 정의합니다.
- Envoy Gateway
- Gateway API를 구현하는 컨트롤러입니다.
- Gateway API 리소스를 해석하고, Envoy Proxy를 통해 실제 HTTP 트래픽 라우팅을 처리합니다.
기존에는 Ingress와 Ingress Controller를 사용해 서비스를 노출하는 경우가 많았습니다.
이번 구성에서는 Gateway API 기반 라우팅을 사용하기 위해 Envoy Gateway를 적용했습니다.
참고 자료:
- https://gateway-api.sigs.k8s.io/guides/getting-started/simple-gateway/
- https://gateway.envoyproxy.io/docs/tasks/traffic/http-routing/
1. Envoy Gateway 배포
먼저 Envoy Gateway를 설치합니다.
Envoy Gateway는 Gateway API 기반의 HTTP 라우팅을 제공하는 컨트롤러입니다.
설치
Helm을 사용해 Envoy Gateway를 설치합니다.
helm install eg oci://docker.io/envoyproxy/gateway-helm \
--version v1.8.0 \
-n envoy-gateway-system \
--create-namespace
위 명령어는 다음 작업을 수행합니다.
- envoy-gateway-system 네임스페이스 생성
- Envoy Gateway Helm Chart 설치
- Gateway API 리소스를 처리할 Envoy Gateway 컨트롤러 배포
배포 상태 확인
설치가 완료되면 Envoy Gateway Deployment가 정상적으로 준비되었는지 확인합니다.
kubectl wait --timeout=5m \
-n envoy-gateway-system \
deployment/envoy-gateway \
--for=condition=Available
condition=Available 상태가 되면 Envoy Gateway가 정상적으로 배포된 것입니다.
2. 선택: quickstart로 HTTP 라우팅 테스트
실제 애플리케이션 라우팅을 설정하기 전에, Envoy Gateway 공식 quickstart 예제로 Gateway API 라우팅이 정상 동작하는지 먼저 확인할 수 있습니다.
kubectl apply \
-f https://github.com/envoyproxy/gateway/releases/download/v1.8.0/quickstart.yaml \
-n default
quickstart 리소스를 적용한 뒤 Gateway에 할당된 주소를 확인합니다.
export GATEWAY_HOST=$(kubectl get gateway/eg -o jsonpath='{.status.addresses[0].value}')
이후 다음 명령어로 HTTP 요청을 테스트합니다.
curl --verbose \
--header "Host: www.example.com" \
http://$GATEWAY_HOST/get
정상적으로 응답이 온다면 다음 항목들이 정상적으로 동작하고 있다고 볼 수 있습니다.
- Envoy Gateway 설치
- Gateway API 리소스 처리
- Gateway와 HTTPRoute 연결
- HTTP 요청 라우팅
테스트가 끝난 뒤에는 quickstart 리소스가 실제 설정과 충돌하지 않도록 삭제합니다.
kubectl delete \
-f https://github.com/envoyproxy/gateway/releases/download/v1.8.0/quickstart.yaml \
-n default
3. Gateway API 구성 방식
Gateway API는 주로 다음 리소스를 조합해 외부 트래픽을 서비스로 연결합니다.
- GatewayClass
- 어떤 컨트롤러가 Gateway를 처리할지 정의합니다.
- 여기서는 Envoy Gateway가 제공하는 eg GatewayClass를 사용합니다.
- Gateway
- 외부에 열 프로토콜, 포트, Listener, 라우트 허용 범위를 정의합니다.
- HTTPRoute
- Gateway로 들어온 HTTP 요청을 실제 Kubernetes Service로 전달합니다.
이번 예제에서는 app 네임스페이스에 있는 api-gateway Service를 외부에서 접근할 수 있도록 설정합니다.
실제 프로젝트에서는 네임스페이스와 서비스 이름을 자신의 환경에 맞게 변경하면 됩니다.
4. api-gateway 노출 설정
먼저 api-gateway를 노출하기 위한 Gateway를 생성합니다.
Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: app-gateway
namespace: app
spec:
gatewayClassName: eg
listeners:
- protocol: HTTP
port: 80
name: http
allowedRoutes:
namespaces:
from: Same
이 Gateway는 다음 내용을 정의합니다.
- gatewayClassName: eg
- Envoy Gateway가 이 Gateway를 처리하도록 지정합니다.
- protocol: HTTP
- HTTP 트래픽을 처리합니다.
- port: 80
- 80번 포트로 들어오는 HTTP 요청을 처리합니다.
- allowedRoutes.namespaces.from: Same
- 같은 네임스페이스에 있는 Route만 이 Gateway에 연결할 수 있도록 제한합니다.
Gateway 리소스를 적용합니다.
kubectl apply -f k8s/gateway/app-gateway.yaml
HTTPRoute
이제 Gateway로 들어온 요청을 실제 api-gateway Service로 전달하는 HTTPRoute를 생성합니다.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app-http-route
namespace: app
spec:
parentRefs:
- name: app-gateway
rules:
- backendRefs:
- name: api-gateway
port: 8000
현재 구성에서는 app-gateway로 들어온 모든 HTTP 요청을 api-gateway Service의 8000 포트로 전달합니다.
HTTPRoute 리소스를 적용합니다.
kubectl apply -f k8s/gateway/app-httproute.yaml
5. Grafana 노출 설정
Grafana도 동일한 방식으로 Gateway와 HTTPRoute를 생성해 외부에서 접근할 수 있도록 설정할 수 있습니다.
Grafana가 monitoring 네임스페이스에 있고, Service 이름이 grafana라고 가정하면 다음과 같이 작성할 수 있습니다.
Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: grafana-gateway
namespace: monitoring
spec:
gatewayClassName: eg
listeners:
- protocol: HTTP
port: 80
name: http
allowedRoutes:
namespaces:
from: Same
HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: grafana-http-route
namespace: monitoring
spec:
parentRefs:
- name: grafana-gateway
rules:
- backendRefs:
- name: grafana
port: 80
리소스를 적용합니다.
kubectl apply -f k8s/gateway/grafana-gateway.yaml
kubectl apply -f k8s/gateway/grafana-httproute.yaml
이 설정을 적용하면 grafana-gateway로 들어온 HTTP 요청이 monitoring 네임스페이스의 grafana Service로 전달됩니다.
6. Gateway 상태 확인
Gateway 리소스가 정상적으로 생성되었는지 확인합니다.
kubectl get gateway -A
HTTPRoute가 Gateway에 정상적으로 연결되었는지도 확인합니다.
kubectl get httproute -A
좀 더 자세한 상태를 확인하려면 describe 명령어를 사용할 수 있습니다.
kubectl describe gateway app-gateway -n app
kubectl describe httproute app-http-route -n app
여기에서 Accepted, ResolvedRefs와 같은 조건이 정상인지 확인합니다.
7. api-gateway 접근 테스트
Gateway에 할당된 주소를 확인한 뒤, api-gateway의 헬스 체크 엔드포인트로 요청을 보내봅니다.
kubectl get gateway app-gateway -n app
Gateway 주소를 확인한 뒤 다음과 같이 요청합니다.
curl http://<APP_GATEWAY_ADDRESS>/health
정상적으로 응답이 반환된다면 다음 흐름이 제대로 연결된 것입니다.
Client
→ Gateway
→ HTTPRoute
→ api-gateway Service
→ api-gateway Pod
이제 api-gateway에 접근하기 위해 매번 kubectl port-forward를 실행하지 않아도 됩니다.
8. Grafana 접근 테스트
Grafana도 동일하게 grafana-gateway에 할당된 주소로 접근합니다.
kubectl get gateway grafana-gateway -n monitoring
브라우저에서 다음 주소로 접속합니다.
http://<GRAFANA_GATEWAY_ADDRESS>
Grafana 로그인 화면이 표시된다면 Gateway API 라우팅이 정상적으로 동작하는 것입니다.
정리
이번 글에서는 Kubernetes 환경에서 Gateway API와 Envoy Gateway를 사용해 서비스를 노출하는 방법을 정리했습니다.
구성 과정은 다음과 같습니다.
- Envoy Gateway 설치
- quickstart 예제로 Gateway API 라우팅 테스트
- GatewayClass, Gateway, HTTPRoute 역할 정리
- api-gateway용 Gateway와 HTTPRoute 생성
- Grafana용 Gateway와 HTTPRoute 생성
- Gateway와 HTTPRoute 상태 확인
- curl과 브라우저를 통해 접근 테스트
Gateway API는 기존 Ingress보다 역할이 더 세분화되어 있습니다.
Gateway는 외부에서 들어오는 트래픽의 진입점을 정의하고, HTTPRoute는 해당 트래픽을 어떤 Service로 전달할지 정의합니다.
Envoy Gateway는 이러한 Gateway API 리소스를 실제 Envoy 기반 라우팅 구성으로 변환해 트래픽을 처리합니다.
따라서 Gateway API와 Envoy Gateway를 함께 사용하면 Kubernetes에서 HTTP 라우팅 구성을 더 명확하게 관리할 수 있습니다.
References
'Devops > Kubernetes' 카테고리의 다른 글
| Helm으로 Argo CD 설치 후 Gateway API와 TLS로 접속 구성하기 (0) | 2026.05.26 |
|---|---|
| Kubernetes kubelet의 컨테이너 로그 로테이션 설정 정리 (0) | 2026.05.25 |
| Kubernetes 로컬 환경에 Private Registry 배포하고 이미지 Push/Pull 설정하기 (0) | 2026.05.20 |
| 로컬 Kubernetes에서 MetalLB로 LoadBalancer IP 할당하기 (0) | 2026.05.20 |
| Kubernetes에서 NFS 스토리지 구성하기 (0) | 2026.05.20 |