Envoy Gateway v1.6.1 / Proxy v1.36.3 온라인 설치 가이드
인터넷이 가능한 환경에서 Envoy Gateway 를 Kubernetes 클러스터에 설치하는 절차입니다. 폐쇄망 절차는 Envoy Gateway v1.36.3 오프라인 설치 가이드를 참고하세요.
전제 조건
- Kubernetes 클러스터 구성 완료 (v1.30+ 권장)
- Helm v3.14.0 이상 설치 완료
kubectlCLI 사용 가능- 외부 저장소 접근 가능 (
docker.ioHelm OCI 레지스트리) - Cilium 사용 시
gatewayAPI.enabled=false로 설치되어 있어야 함 (GatewayClass 충돌 방지)
아키텍처 개요
- Network:
hostNetwork: false - Service:
type: LoadBalancer또는type: NodePort - 트래픽 흐름 (LoadBalancer):
- 트래픽 흐름 (NodePort + VIP):
1단계: Gateway API CRD 설치
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/standard-install.yaml
# 확인
kubectl get crd | grep gateway.networking.k8s.io
Cilium 등 다른 구현체가 이미 설치한 상태라면 이 단계 생략.
2단계: Envoy Gateway Helm 차트 다운로드 (선택, values 검토용)
helm pull oci://docker.io/envoyproxy/gateway-helm \
--version v1.6.1 \
--untar --untardir /tmp/eg
ls /tmp/eg/gateway-helm/ # values.yaml 등 확인
본 레포의
charts/gateway-1.6.1와 동일 버전입니다.
3단계: TLS 사전 구성 (HTTPS 사용 시)
HTTPS 를 사용할 경우 Helm 배포 전에 Gateway 네임스페이스에 TLS Secret 을 생성합니다.
# 네임스페이스 생성
kubectl create ns envoy-gateway-system --dry-run=client -o yaml | kubectl apply -f -
# TLS Secret 생성
kubectl create secret tls gateway-tls \
--cert=cert.pem --key=key.pem \
-n envoy-gateway-system
추가 인증서가 있으면 Secret 을 각각 생성한 뒤 manifests/gateway.yaml 의 listeners 항목에 추가.
HTTP 만 쓸 거면 values-infra.yaml 의 HTTPS 리스너 / TLS 설정을 주석 처리합니다.
4단계: 컨트롤 플레인 설치 (Envoy Gateway)
# OCI 차트 직접 설치
helm upgrade --install eg-gateway oci://docker.io/envoyproxy/gateway-helm \
--version v1.6.1 \
-n envoy-gateway-system
# 상태 확인
kubectl -n envoy-gateway-system get pods
kubectl get gatewayclass # eg (Accepted=True) 확인
5단계: 데이터 플레인 (Gateway 인스턴스) 배포
본 레포의 charts/gateway-infra 차트로 Gateway / HTTPRoute / 정책을 묶어 배포.
helm upgrade --install gateway-infra ./charts/gateway-infra \
-n envoy-gateway-system \
-f ./values-infra.yaml
# 전역 정책 (선택)
kubectl apply -f manifests/policy-global.yaml
6단계: 배포 후 네트워크 구성
Case A: LoadBalancer — 자동 할당
클라우드 환경 또는 MetalLB 가 구성된 경우입니다.
Case B: LoadBalancer — MetalLB 연동 (권장: 온프레미스 VIP 구성)
온프레미스(Bare-metal) 환경에서는 외부 트래픽을 수신하고 장애 전환(ARP Failover) 및 실 IP 보존을 보장하기 위해 MetalLB(L2 모드)를 구축하여 로드밸런서 IP를 광고하는 것을 강력히 권장합니다.
1) MetalLB 설치 및 IP 풀 설정:
- 본 레포의 MetalLB 설치 가이드를 참고하여 설치하고, 노드 대역의 유휴 IP(예: 10.10.10.81-10.10.10.81)를 IPAddressPool로 등록합니다.
- 서비스 타입이 LoadBalancer 상태로 배포되면, MetalLB가 생성된 Envoy Proxy 서비스에 IP풀의 VIP(10.10.10.81)를 EXTERNAL-IP로 자동 할당하게 됩니다.
2) 게이트웨이(Gateway) 리소스 주소 바인딩:
서비스에 IP가 할당된 후 Gateway 리소스의 주소를 바인딩하여 상태를 동기화(Programmed: True)합니다.
# 할당된 VIP(예: 10.10.10.81)를 Gateway 리소스에 바인딩
kubectl patch gateway cluster-gateway -n envoy-gateway-system --type='merge' \
-p '{"spec":{"addresses":[{"type":"IPAddress","value":"10.10.10.81"}]}}'
⚠️ [참고] externalIPs 수동 할당 (비권장 - 임시 검증용) MetalLB 같은 로드밸런서 컨트롤러가 없는 경우에 임시로 노드 IP를 통해 외부 트래픽을 받기 위한 우회 방법입니다. (ARP 광고 및 고가용성이 보장되지 않으며, 실 IP 보존이 불가능합니다.)
서비스(Service) 외부 IP 등록:
SVC_NAME=$(kubectl get svc -n envoy-gateway-system -o jsonpath='{.items[?(@.spec.type=="LoadBalancer")].metadata.name}')
# 전체 워커 노드 IP를 externalIPs에 일괄 등록
kubectl patch svc -n envoy-gateway-system $SVC_NAME --type merge \
-p '{"spec":{"externalIPs":["<WORKER1_IP>","<WORKER2_IP>"]}}'
게이트웨이(Gateway) 주소 바인딩:
# 위에서 등록한 노드 IP들을 Gateway 리소스에도 바인딩
kubectl patch gateway cluster-gateway -n envoy-gateway-system --type='merge' \
-p '{"spec":{"addresses":[
{"type":"IPAddress","value":"<WORKER1_IP>"},
{"type":"IPAddress","value":"<WORKER2_IP>"}
]}}'
Case C: NodePort — VIP(HAProxy) 연동
NodePort 모드는 HTTP 30080 / HTTPS 30443 으로 고정.
L4 스위치(또는 외부 HAProxy)에 워커 노드 IP + 포트(30080/30443)를 Real Server 로 등록.
Keepalived + HAProxy 자체 구성 예시
# /etc/haproxy/haproxy.cfg — VIP 10.10.10.200, 워커 73~75
frontend envoy-http
bind 10.10.10.200:80
mode tcp
default_backend envoy-workers-http
backend envoy-workers-http
mode tcp
balance roundrobin
server worker1 10.10.10.73:30080 check
server worker2 10.10.10.74:30080 check
server worker3 10.10.10.75:30080 check
frontend envoy-https
bind 10.10.10.200:443
mode tcp
default_backend envoy-workers-https
backend envoy-workers-https
mode tcp
balance roundrobin
server worker1 10.10.10.73:30443 check
server worker2 10.10.10.74:30443 check
server worker3 10.10.10.75:30443 check
L4 없이 단일 노드 직접 접속:
방화벽에서 30080 / 30443 포트 허용 필요.
7단계: 서비스 노출 (HTTPRoute)
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app-route
namespace: default
spec:
parentRefs:
- name: cluster-gateway
namespace: envoy-gateway-system
hostnames:
- "my-app.devops.internal"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-app-service
port: 80
8단계: HTTPRoute 트러블슈팅
503 / Connection Refused — 백엔드 포트 불일치
Envoy 는 Service ClusterIP 포트가 아닌 Pod 의 실제 컨테이너 포트로 연결합니다.
kubectl get pod <POD_NAME> -n <NS> -o yaml | grep containerPort
kubectl patch httproute <ROUTE_NAME> -n <NS> --type='json' \
-p='[{"op":"replace","path":"/spec/rules/0/backendRefs/0/port","value":8080}]'
404 — URL Rewrite 필요
rules:
- matches:
- path:
type: PathPrefix
value: /myapp
filters:
- type: URLRewrite
urlRewrite:
path:
type: ReplacePrefixMatch
replacePrefixMatch: /
backendRefs:
- name: my-app-service
port: 8080
Gateway 연결 상태 확인
kubectl get gateway cluster-gateway -n envoy-gateway-system -o yaml
kubectl get httproute -A
kubectl describe httproute <ROUTE_NAME> -n <NS>
주요 실패 원인:
parentRefs.name이 실제 Gateway 이름(cluster-gateway) 과 불일치- Gateway Listener 의
allowedRoutes.namespaces설정이 해당 NS 차단
운영 — 로그 확인
# Data Plane (실제 트래픽 / 접속 오류)
kubectl logs -n envoy-gateway-system -f \
-l gateway.envoyproxy.io/owning-gateway-name=cluster-gateway
# Control Plane (설정 변환 / 배포 실패)
kubectl logs -n envoy-gateway-system -f \
-l app.kubernetes.io/name=envoy-gateway
(심화) 와일드카드 TLS 인증서 적용
*.devops.internal 와일드카드 인증서로 모든 서브도메인 HTTPS 통합 관리.
kubectl create secret tls wildcard-tls-secret \
--cert=fullchain.pem --key=privkey.pem \
-n envoy-gateway-system
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: cluster-gateway
namespace: envoy-gateway-system
spec:
gatewayClassName: eg-cluster-entry
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces: { from: All }
- name: https
port: 443
protocol: HTTPS
hostname: "*.devops.internal"
tls:
mode: Terminate
certificateRefs:
- name: wildcard-tls-secret
kind: Secret
allowedRoutes:
namespaces: { from: All }
검증:
curl -v https://nexus.devops.internal \
--resolve nexus.devops.internal:443:<GATEWAY_IP>
# Server certificate: CN=*.devops.internal 확인
CVE 패치 / Minor 업그레이드
# 사용 가능 버전 확인
helm search repo oci://docker.io/envoyproxy/gateway-helm --versions | head -10
# 동일 라인 patch 업그레이드 (rolling)
helm upgrade eg-gateway oci://docker.io/envoyproxy/gateway-helm \
--version v1.6.1 -n envoy-gateway-system \
--reuse-values
Major / minor 업그레이드는 CRD 변경 동반 — release notes 우선 확인.