NGINX Gateway Fabric HTTPS 설정 가이드

이 포스트는 NGINX Gateway Fabric 의 HTTPS 트래픽 처리를 위한 SSL/TLS 구성 방법에 관해 다룹니다. 인증서 파일을 사용해 Secret 리소스를 생성하고, Gateway 리소스 및 HTTPRoute 리소스 구성 방법과 Secret 리소스 참조를 위한 ReferenceGrant 리소스 구성 방법을 알아보겠습니다.

Redirect, Rewrite를 활용한 NGINX Gateway Fabric의 트래픽 라우팅 구성 방법이 궁금하시다면 NGINX Gateway Fabric 트래픽 라우팅: Redirect 및 Rewrite 포스트를 참고하세요.

목차

1. NGINX Gateway Fabric이란?
2. 버전 정보

3. NGINX Gateway Fabric HTTPS 구성
4. NGINX Gateway Fabric HTTP to HTTPS 리다이렉트 구성
5. 결론

1. NGINX Gateway Fabric이란?

NGINX Gateway Fabric은 NGINX를 데이터플레인으로 사용하여 Kubernetes의 Gateway API를 구현하는 프로젝트입니다. Gateway API는 Kubernetes의 네트워크 트래픽을 관리하고 제어하기 위한 표준화된 인터페이스로, 기존의 Ingress API를 대체하거나 확장하는 데 목적을 두고 있습니다.

NGINX Gateway Fabric은 기본적으로 기존의 Ingress Controller와 같이 Kubernetes 클러스터 외부의 트래픽을 관리하는 역할을 하며, Gateway API 표준 리소스인 Gateway, HTTPRoute를 통해 복잡한 Annotation이나 Custom Resource를 사용하지 않고도 구성할 수 있습니다.

2. 버전 정보

  • Kubernetes : v1.30.3
  • NGINX Gateway Fabric : 1.6.0 (Stable release)

3. NGINX Gateway Fabric HTTPS 구성

먼저 NGINX Gateway Fabric을 통해 HTTPS 트래픽 수신을 위한 리소스를 구성하고, 실제로 요청을 전송하여 확인해 보겠습니다.

각 리소스는 다양한 네임스페이스에 구성되며, 최종적으로 구성될 리소스의 정보는 다음과 같습니다.
예제에 사용된 yaml 파일들은 NGINX STORE GitHub 리포지토리에서 확인하실 수 있습니다.

NGINX Gateway Fabric HTTPS 구성

먼저 NGINX Gateway Fabric을 통해 연결될 예시 백엔드 리소스인 nginx-hello Service, Deployment를 배포합니다.

NGINX Gateway Fabric HTTPS 백엔드
nginx-hello-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-hello-svc
  namespace: demo
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: nginx-hello
nginx-hello.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-hello
  namespace: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-hello
  template:
    metadata:
      labels:
        app: nginx-hello
    spec:
      containers:
      - name: nginx-hello
        image: nginxdemos/nginx-hello:plain-text
        ports:
        - containerPort: 80

SSL/TLS 인증서를 사용하여 Gateway 리소스가 참조할 tls 타입의 Secret 리소스를 생성합니다.
cert 네임스페이스에 fullchain.pem 인증서 파일과 privkey.pem 키 파일을 사용하여 nginx-store-secret 이름으로 생성했습니다. 해당 인증서는 devopssong.nginxstore.kr 도메인의 인증서입니다.

NGINX Gateway Fabric HTTPS 인증서 Secret
$ kubectl create secret tls nginx-store-secret -n cert --cert=fullchain.pem --key=privkey.pem

secret/nginx-store-secret created

$ kubectl get secrets -n cert

NAME                 TYPE                DATA   AGE
nginx-store-secret   kubernetes.io/tls   2      15s

클러스터에 들어오는 트래픽의 진입점이 되는 Gateway 리소스를 구성합니다.

NGINX Gateway Fabric HTTPS Gateway
gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: https-gw                          # nginx-gateway 네임스페이스에 배포
  namespace: nginx-gateway
spec:
  gatewayClassName: nginx                 # NGINX Gateway Fabric 사용을 위한 Class 설정
  listeners:
  - name: http                            # listener 이름 지정
    hostname: "devopssong.nginxstore.kr"  # hostname 지정
    port: 80
    protocol: HTTP
    allowedRoutes:                        # demo 네임스페이스의 HTTPRoute 리소스 연결을 위한 구성
      namespaces:
        from: Selector
        selector:
          matchLabels:                    # 해당 레이블이 존재하는 네임스페이스에서 연결될 수 있음
            kubernetes.io/metadata.name: demo
  - name: https                           # listener 이름 지정
    hostname: "devopssong.nginxstore.kr"
    port: 443
    protocol: HTTPS
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            kubernetes.io/metadata.name: demo
    tls:                                 # HTTPS 구성을 위한 TLS 인증서 설정
      certificateRefs:
      - group: ""                        # 빈값으로 설정 시 K8S Core API Group
        kind: Secret                     # Secret 리소스 지정   
        name: nginx-store-secret         # Secret 리소스 이름 지정
        namespace: cert                  # 리소스가 배포된 네임스페이스 지정

“devopssong.nginxstore.kr” 도메인의 HTTP/HTTPS 요청을 80/443번 포트로 처리하는 Gateway 구성입니다. NGINX Gateway Fabric이 배포된 네임스페이스인 nginx-gateway 네임스페이스에 배포되었으며, 다른 네임스페이스에 배포할 수도 있습니다.

nginx-gateway 네임스페이스 외부에 배포된 리소스(demo 네임스페이스의 HTTPRoute, cert 네임스페이스의 Secret)를 참조하기 위한 설정이 적용되어 있습니다.
allowedRoutes 설정을 통한 외부 네임스페이스의 HTTPRoute 연결 구성에 대한 자세한 내용은 NGINX Gateway Fabric 트래픽 라우팅: Redirect 및 Rewrite 포스트의 3. NGINX Gateway Fabric 트래픽 라우팅 항목을 참고하세요.

앞서 구성한 Gateway 리소스를 통해 수신한 트래픽을 백엔드 Pod/Service로 라우팅하기 위한 HTTPRoute 리소스를 demo 네임스페이스에 생성합니다.

NGINX Gateway Fabric HTTPS - HTTPRoute
route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: route                   # 리소스 이름 지정
  namespace: demo
spec:
  parentRefs:                   # 앞서 구성한 Gateway 리소스를 명시
    - name: https-gw
      namespace: nginx-gateway
  rules:                        # 트래픽 라우팅 규칙 설정
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:                # 연결될 백엔드 서비스 명시
    - name: nginx-hello-svc
      port: 80

마지막으로 ReferenceGrant 리소스를 생성합니다. 이 리소스는 Gateway 리소스와 SSL/TLS 인증서가 포함된 Secret 리소스가 서로 다른 네임스페이스에 배포된 경우 구성이 필요하며, 동일한 네임스페이스에 배포된 경우 별도로 구성이 필요하지 않습니다.

NGINX Gateway Fabric HTTPS - ReferenceGrant
cert-ref.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: access-to-cert-secret # 리소스 이름 지정
  namespace: cert
spec:
  from:                       # 리소스를 참조할 Gateway 지정
  - group: gateway.networking.k8s.io
    kind: Gateway
    namespace: nginx-gateway
  to:                         # 참조되는 Secret 리소스를 지정
  - group: ""                 # 빈값으로 설정 시 K8S Core API Group 
    kind: Secret
    name: nginx-store-secret  # 생략 시 Gateway 리소스에서 cert 네임스페이스의 모든 Secret 에 접근 가능

위와 같이 spec.to.name에 특정 Secret 리소스 이름을 명시할 경우 Gateway 리소스는 해당 Secret만 참조할 수 있으며, 명시하지 않은 경우 ReferenceGrant 리소스가 배포된 네임스페이스의 모든 Secret을 참조할 수 있습니다.

배포한 리소스들을 확인합니다.

$ kubectl get httproutes.gateway.networking.k8s.io

NAME             HOSTNAMES                     AGE
route                                          39s

$ kubectl get gateways.gateway.networking.k8s.io -n nginx-gateway

NAME       CLASS   ADDRESS           PROGRAMMED   AGE
https-gw   nginx   175.196.***.***   True         9d

$ kubectl get referencegrants.gateway.networking.k8s.io -n cert

NAME                    AGE
access-to-cert-secret   9d

HTTP, HTTPS 요청을 각각 전송하여 연결을 확인합니다.

$ curl http://devopssong.nginxstore.kr

Server address: 10.244.1.6:8080
Server name: nginx-hello-5979b5bb97-bsv5t
Date: 03/Feb/2025:01:29:43 +0000
URI: /
Request ID: 910f541135b47ae0bf5069f2572c7957

$ curl https://devopssong.nginxstore.kr

Server address: 10.244.1.6:8080
Server name: nginx-hello-5979b5bb97-bsv5t
Date: 03/Feb/2025:01:29:47 +0000
URI: /
Request ID: b1518759ae9f09b396d14567a5af97e3

HTTP/HTTPS 요청 모두 정상적으로 응답하는 것을 확인할 수 있습니다.

브라우저 접속 시에도 정상적으로 SSL/TLS 인증서가 적용되어 연결됩니다.

4. NGINX Gateway Fabric HTTP to HTTPS 리다이렉트 구성

NGINX Gateway Fabric을 통해 수신하는 HTTP 트래픽을 자동으로 HTTPS로 리다이렉트 하기 위해서는 HTTPRoute 리소스를 2개로 나눠 구성해야 합니다.

최종적으로 구성될 리소스는 다음과 같습니다.
기존에 demo 네임스페이스에 배포되었던 HTTPRoute 리소스를 2개로 분리하여 구성합니다.

NGINX Gateway Fabric HTTPS with redirect 구성

HTTPS 트래픽을 라우팅하는 HTTPRoute 리소스를 배포합니다.

https-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: https-route
  namespace: demo
spec:
  parentRefs:
    - name: https-gw
      namespace: nginx-gateway
      sectionName: https         # Gateway 리소스의 listener 이름을 지정
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: nginx-hello-svc
      port: 80

이전에 배포된 리소스에서 sectionName 설정이 추가되었습니다. 해당 값은 앞서 배포한 Gateway 리소스에서 명시한 listener 이름으로 구성합니다.

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: https-gw
  namespace: nginx-gateway
spec:
  gatewayClassName: nginx
  listeners:

......

  - name: https
    hostname: "devopssong.nginxstore.kr"
    port: 443
    protocol: HTTPS

......

HTTP 트래픽을 리다이렉트하는 HTTPRoute 리소스를 배포합니다.

http-redirect-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: http-redirect-route
  namespace: demo
spec:
  parentRefs:
    - name: https-gw
      namespace: nginx-gateway
      sectionName: http         # Gateway 리소스의 listener 이름을 지정
  rules:                        # HTTPS 리다이렉트 설정
  - filters:
    - type: RequestRedirect
      requestRedirect:
        scheme: https
        port: 443
        statusCode: 301

앞서 구성한 리소스와 같이 sectionName에 HTTP 트래픽을 수신하는 http listener 이름을 명시하고, HTTPS 리다이렉트 설정을 구성합니다. 301 상태 코드를 명시하지 않으면 기본 설정인 302 상태 코드를 반환합니다.

구성한 리소스를 배포하고 확인합니다. 이전에 배포한 HTTPRoute 리소스를 제거하고 배포했습니다.

$ kubectl get httproutes.gateway.networking.k8s.io -n demo

NAME                  HOSTNAMES                     AGE
http-redirect-route                                 7s
https-route                                         7s

HTTP 요청을 전송하여 리다이렉트 되는 것을 확인합니다.

$ curl http://devopssong.nginxstore.kr -L -v


* Host devopssong.nginxstore.kr:80 was resolved.
* IPv6: (none)
* IPv4: 175.196.***.***
*   Trying 175.196.***.***:80...
* Connected to devopssong.nginxstore.kr (175.196.***.***) port 80
> GET / HTTP/1.1
> Host: devopssong.nginxstore.kr
> User-Agent: curl/8.9.1
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently
< Server: nginx
< Date: Mon, 03 Feb 2025 01:56:55 GMT
< Content-Type: text/html
< Content-Length: 138
< Connection: keep-alive
< Location: https://devopssong.nginxstore.kr/
* Ignoring the response-body
<
* Connection #0 to host devopssong.nginxstore.kr left intact
* Clear auth, redirects to port from 80 to 443
* Issue another request to this URL: 'https://devopssong.nginxstore.kr/'
* Host devopssong.nginxstore.kr:443 was resolved.
* IPv6: (none)
* IPv4: 175.196.***.***
*   Trying 175.196.***.***:443...
* Connected to devopssong.nginxstore.kr (175.196.***.***) port 443
* schannel: disabled automatic use of client certificate
* ALPN: curl offers http/1.1
* ALPN: server accepted http/1.1
* using HTTP/1.x
> GET / HTTP/1.1
> Host: devopssong.nginxstore.kr
> User-Agent: curl/8.9.1
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Mon, 03 Feb 2025 01:56:55 GMT
< Content-Type: text/plain
< Content-Length: 159
< Connection: keep-alive
< Expires: Mon, 03 Feb 2025 01:56:54 GMT
< Cache-Control: no-cache
<
Server address: 10.244.1.6:8080
Server name: nginx-hello-5979b5bb97-bsv5t
Date: 03/Feb/2025:01:56:55 +0000
URI: /
Request ID: 7b40aaf92f2e0d9ad8147e50f400f301
* Connection #1 to host devopssong.nginxstore.kr left intact

HTTP 요청이 정상적으로 HTTPS로 리다이렉트 하는 것을 확인할 수 있습니다.

5. 결론

이번 포스트에서는 NGINX Gateway Fabric 의 HTTPS 트래픽 처리를 위해 필요한 리소스들을 구성하는 방법을 알아봤습니다. SSL/TLS 인증서/키 파일을 사용하여 Kuberenetes의 tls 타입의 Secret을 생성하는 방법과, 실제 트래픽 처리에 필요한 Gateway, HTTPRoute 리소스를 구성하는 방법을 알아봤습니다.
추가로 외부 네임스페이스의 Secret 리소스 참조를 위한 ReferenceGrant 리소스 구성 방법과 HTTP to HTTPS 리다이렉트 구성 방법도 알아봤습니다.

이와 같은 구성으로 NGINX Gateway Fabric이 HTTPS 트래픽을 처리할 수 있으며, 트래픽 암호화를 통해 클라이언트와 백엔드 간의 데이터 보호를 보장할 수 있습니다. 특히, Gateway 리소스는 클러스터의 단일 진입점 역할을 하여, 클라이언트와 내부 서비스 간의 통신을 보다 간단하고 효율적으로 보호할 수 있습니다.

NGINX Gateway Fabric에서도 사용할 수 있는 NGINX Plus 전용의 풍부한 메트릭, 실시간 모니터링 대시보드, 그리고 동적 업스트림 구성을 체험해 보고 싶으시다면 NGINX STORE를 통해 문의해 무료로 상업용 NGINX 구독을 체험해 보세요.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required