October 30, 2025

[Home-K8S] #19 Envoy Gateway API 사용하기

[Home-K8S] #19 Envoy Gateway API 사용하기

Envoy Gateway

기존에는 nginx-ingress 의 auth-url 과 authelia 를 이용해서 인증을 사용하고 있었습니다. cilium gateway 로 변경하면서 oidc 와 SecurityPolicy 를 이용해서 인증이 된다고 docs 는 없지만 gpt 가 확신을 해서 진행했습니다.

Oauth2-proxy 를 이용하는 방법은 사용하기 싫었기에 찾은 대안은 envoy gateway입니다. 위에서 나온 oidc, SecurityPolicy 는 envoy gateway 의 내용이었습니다.
하여 envoy gateway 로 구성하기로 했습니다.

설치

https://gateway.envoyproxy.io/docs/tasks/quickstart/#installation
flux cd 를 이용해서 helm 으로 설치해 줬습니다.
(특이하게 최신 버전이 v0.0.0-latest 으로 되어 있어요.)

확인

설치한 namespace 에 pod 들이 잘 떠 있는지 확인합니다.

service의 경우 자동으로 LoadBalancer 를 잡았는데, 아닐 경우 config를 설정해 주어야 합니다.

GatewayClass 도 잘 구성되었는지 확인합니다. Accepted = True

cert-manager

ssl 인증을 위한 인증서를 발급 받습니다. 구성된 ClusterIssuer 를 사용합니다.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: https-tls
  namespace: envoy-gateway        # envoy-gateway namespace
spec:
  secretName: dogring-kr-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  commonName: dogring.kr
  dnsNames:
  - dogring.kr
  - "*.dogring.kr"                 # wildcard 인증서
wildcard(*) 인증서를 발급받기 위해서는 clusterIssuer 에서 dns01 을 사용해야 합니다. http01 은 wildcard 사용이 불가하고 서브도메인 모두 입력해주면 됩니다.

Gateway 생성

GatewayClass 가 생성되면 Gateway 도 생성합니다.
http 를 위한 80 번 포트와 https 를 위한 443 포트도 생성합니다.
(ingress 와 달리 다른 포트도 사용할 수 있습니다. )

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: envoy-gateway
  namespace: envoy-gateway
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  gatewayClassName: envoy-gateway
  listeners:
  - name: http                         # 이름 변경 가능
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: All
  - name: https                        # 이름 변경 가능
    port: 443
    protocol: HTTPS
    allowedRoutes:                     # httpRoute 를 사용할 곳
      namespaces:
        from: All
    tls:
      mode: Terminate
      certificateRefs:
      - kind: Secret
        name: dogring-kr-tls
        namespace: envoy-gateway        # 인증서 위치

http Redirect

http로 오는 요청을 https 로 리다이렉트 하는 HTTPRoute 를 추가해 줍니다.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http-to-https-redirect
  namespace: envoy-gateway
spec:
  parentRefs:
  - name: envoy-gateway
    namespace: envoy-gateway
    sectionName: http
  rules:
  - filters:
    - type: RequestRedirect
      requestRedirect:
        scheme: https
        statusCode: 301

HTTPRoute

Service 가 있는 namespace 에서 서비스 할 HTTPRoute 를 만들어 줍니다.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: ghost-route
  namespace: ghost
spec:
  parentRefs:
  - name: envoy-gateway
    namespace: envoy-gateway
  hostnames:
  - dogring.kr
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: ghost-service
      port: 8080
      namespace: ghost

ReferenceGrant

HTTPRoute 를 만들어도 서비스는 외부에서 접근할 수가 없습니다.
정확히는 Gateway는 envoy-gateway namespace 에,HTTPRoute 는 서비스가 있는 namespace 에 있기 때문에 envoy-gateway 가 다른 namespace 의 envoy-gateway를 찾을 수가 없습니다.

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-routes
  namespace: envoy-gateway
spec:
  from:
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    namespace: ghost                      # HTTPRoute Namespace
  - group: gateway.networking.k8s.io
    kind: HTTPRoute
    namespace: app1
  to:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: envoy-gateway                    # Gateway Namespace

이렇게 구성하면 내부망에서 접근이 가능합니다. 노드가 하나라면 외부에서도 접근이 가능할 수도 있지만, 저는 안되더라구요.

externalTrafficPolicy

포트포워딩, cilium, envoy gateway, route 설정 등등 전부 확인해 보았는데도 외부에서 접근이 안되었습니다. 그래서 찾다보니 externalTrafficPolicy 옵션을 따로 지정해 줘야 한다는 것을 확인했습니다.
(LLM 이 없었으면 진짜 docs 하나하나 읽고 있었을 텐데 다행입니다.)

envoy proxy 의 config 를 생성해서 필요한 옵션들을 적용해 줍니다.
local 과 Cluster의 차이는 봐도 아직 잘 이해는 안되었습니다.

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
  name: envoy-proxy-config
  namespace: envoy-gateway
spec:
  provider:
    type: Kubernetes
    kubernetes:
      envoyService:
        type: LoadBalancer
        externalTrafficPolicy: Cluster        # default: local

설정한 옵션들을 GatewayClass 에 적용합니다.

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: envoy-gateway
spec:
  controllerName: gateway.envoyproxy.io/gatewayclass-controller
  parametersRef:
    group: gateway.envoyproxy.io
    kind: EnvoyProxy
    name: envoy-proxy-config
    namespace: envoy-gateway

결론

cilium gateway 의 eBPF 를 사용할 수 없는 것은 리소스에 영향은 좀 있을 거 같지만 Oauth2-proxy 를 같이 사용하는 것보다는 적게 사용하는 것으로 보입니다.

다음 포스팅에서는 Dex idp 를 구성하고 envoy-gateway 의 인증을 같이 사용하는 것으로 작성합니다.

Comments