본문 바로가기

Container/Kubernetes

[K8S] Gateway API

Gateway API는 Kubernetes 네트워크 트래픽을 제어하는 새로운 표준 API로, 기존의 Ingress 및 Service Mesh를 대체하거나 보완하는 역할을 한다.

  •  Ingress보다 더 강력한 기능 제공 (다양한 트래픽 라우팅 기능)
  •  L4 (TCP, UDP) + L7 (HTTP, HTTPS) 트래픽 제어 가능
  • 클러스터 내외부 트래픽을 유연하게 관리 가능
  • 여러 Gateway 구현체(NGINX, Envoy, Traefik 등)와 호환됨

rf. 기존 Kubernetes의 Ingress는 L7(HTTP/S) 트래픽만 처리 가능
rf. Gateway API는 L4(Layer 4)와 L7(Layer 7) 모두 지원

 

Gateway API는 기존 Ingress보다 더 많은 리소스 개념을 도입하여 트래픽을 유연하게 관리할 수 있도록 한다.

 

 1. 멀티 테넌시 지원

  • 여러 네임스페이스에서 공유된 Gateway를 사용 가능
  • 각 팀이 자신만의 HTTPRoute를 설정 가능

2. 확장성과 유연성 증가

  • TCP, UDP, gRPC, WebSocket 등 다양한 프로토콜 지원
    • HTTPHTTPSTCPUDP, and TLS protocols (대부분의 Transport 계층 지원)
  • Ingress보다 더 복잡한 트래픽 라우팅 및 보안 정책 적용 가능

3. 다양한 Gateway 컨트롤러 지원

  • NGINX, Envoy, HAProxy, Traefik 등 다양한 Gateway 컨트롤러에서 지원
  • 표준 API를 사용하므로 클러스터 간 일관된 설정 가능
GatewayClass 트래픽을 처리할 Gateway의 종류를 정의 (NGINX, Envoy 등)
Gateway 실제로 트래픽을 받아들이는 진입점 (LoadBalancer 역할)
- Gateway를 정의하기 위한 API Resource 
HTTPRoute HTTP/HTTPS 요청을 특정 서비스로 라우팅
TCPRoute / UDPRoute L4(TCP/UDP) 트래픽을 특정 서비스로 라우팅
GRPCRoute gRPC 트래픽을 처리할 때 사용
ReferenceGrant 다른 네임스페이스의 리소스에 접근할 수 있도록 권한 부여


✅ 기존 Ingress는 단일 객체였지만, Gateway API는 다양한 트래픽 관리 기능을 제공

 

📝 GatewayClass → Gateway → HTTPRoute 순서로 정의됨

1. GatewayClass 생성

apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: my-gateway-class
spec:
  controllerName: example.com/gateway-controller
  # gateway-controller도 deploy 해야 한다.

 

 

2. Gateway 생성

  • Ingress와 유사하게 외부 트래픽을 받아들이는 진입점 역할을 한다.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-gateway
spec:
  gatewayClassName: my-gateway-class # gatewayClassName을 사용하여 특정 GatewayClass를 참조
  listeners:
    - protocol: HTTP
      port: 80
      name: http
      # 80번 포트에서 HTTP 트래픽을 수신하는 Gateway 생성
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prod-web
spec:
  gatewayClassName: example
  listeners: # 트래픽 리스너 설정
  - protocol: HTTP
    port: 80
    name: prod-web-gw # 리스너 이름
    allowedRoutes: # Gateway가 허용할 수 있는 Route 리소스를 지정
      namespaces:
        from: Same
        # prod-web Gateway가 있는 네임스페이스에서만 HTTPRoute 연결 가능

📝 allowedRoutes

  • namespaces.from:All : 모든 네임스페이스에서 HTTPRoute를 정의할 수 있음
  • namespaces.from:Same: 같은 네임스페이스에서만 HTTPRoute를 정의할 수 있음
  • namespaces.from:Selector: 특정 네임스페이스만 허용할 수 있도록 라벨 기반 필터링 가능
allowedRoutes:
  namespaces:
    from: Selector
    selector:
      matchLabels:
        team: frontend
        # 라벨이 team: frontend인 네임스페이스만 HTTPRoute를 추가 가능

3. HTTPRoute 생성 (L7 프로토콜)

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: my-route
spec:
  parentRefs:
    - name: my-gateway # my-gateway를 통해 /app 경로로 들어오는 요청을 my-app-service로 전달
  rules:
    - matches:
        - path:
            type: Prefix
            value: "/app"
      backendRefs: # 해당 서비스로 라우팅된다.
        - name: my-app-service
          port: 80

 

https://gateway-api.sigs.k8s.io/guides/migrating-from-ingress/#migrating-from-ingress

 

참고:

 

 

[ 실습 ]

Gateway API Installation

참고 : https://gateway-api.sigs.k8s.io/guides/#installing-a-gateway-controller

 

1. Gateway API resources 설치

controlplane ~ ➜  kubectl kustomize "https://github.com/nginx/nginx-gateway-fabric/config/crd/gateway-api/standard?ref=v1.5.1" | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created

 

2. NGINX Gateway Fabric CRDs deploy

controlplane ~ ➜  kubectl apply -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v1.6.1/deploy/crds.yaml

3. NGINX Gateway Fabric deploy

controlplane ~ ➜  kubectl apply -f https://raw.githubusercontent.com/nginx/nginx-gateway-fabric/v1.6.1/deploy/nodeport/deploy.yaml

4. Deployment 및 svc 확인

controlplane ~ ➜  kubectl get pods -n nginx-gateway 
NAME                            READY   STATUS    RESTARTS   AGE
nginx-gateway-96f76cdcf-q5trh   2/2     Running   0          45s

controlplane ~ ➜  kubectl get svc -n nginx-gateway nginx-gateway -o yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app.kubernetes.io/instance":"nginx-gateway","app.kubernetes.io/name":"nginx-gateway","app.kubernetes.io/version":"1.6.1"},"name":"nginx-gateway","namespace":"nginx-gateway"},"spec":{"externalTrafficPolicy":"Local","ports":[{"name":"http","port":80,"protocol":"TCP","targetPort":80},{"name":"https","port":443,"protocol":"TCP","targetPort":443}],"selector":{"app.kubernetes.io/instance":"nginx-gateway","app.kubernetes.io/name":"nginx-gateway"},"type":"NodePort"}}
  creationTimestamp: "2025-02-26T07:57:54Z"
  labels:
    app.kubernetes.io/instance: nginx-gateway
    app.kubernetes.io/name: nginx-gateway
    app.kubernetes.io/version: 1.6.1
  name: nginx-gateway
  namespace: nginx-gateway
  resourceVersion: "1962"
  uid: baba3dce-3119-4c96-a6af-ebc31f88d7cf
spec:
  clusterIP: 172.20.197.231
  clusterIPs:
  - 172.20.197.231
  externalTrafficPolicy: Local
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: http
    nodePort: 31883
    port: 80
    protocol: TCP
    targetPort: 80
  - name: https
    nodePort: 31439
    port: 443
    protocol: TCP
    targetPort: 443
  selector:
    app.kubernetes.io/instance: nginx-gateway
    app.kubernetes.io/name: nginx-gateway
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

 

5. nginx-gateway service를 HTTP 30080, HTTPS 30081 port로 expose 시키기

controlplane ~ ➜  kubectl patch svc nginx-gateway -n nginx-gateway --type='json' -p='[
  {"op": "replace", "path": "/spec/ports/0/nodePort", "value": 30080},
  {"op": "replace", "path": "/spec/ports/1/nodePort", "value": 30081}
]'
service/nginx-gateway patched

controlplane ~ ➜  kubectl get svc -n nginx-gateway 
NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
nginx-gateway   NodePort   172.20.197.231   <none>        80:30080/TCP,443:30081/TCP   4m26s

 

[ 실습 2 ] - Gateway 만들기

1. Create a Kubernetes Gateway resource 

controlplane ~ ➜  cat nginx-gateway.yaml 
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: nginx-gateway
  namespace: nginx-gateway
spec:
  gatewayClassName: nginx
  listeners:
  - name: http
    protocol: HTTP
    port: 80
    allowedRoutes:
      namespaces:
        from: All
        
controlplane ~ ➜  kubectl apply -f nginx-gateway.yaml 
gateway.gateway.networking.k8s.io/nginx-gateway created

controlplane ~ ➜  kubectl get gateway -n nginx-gateway 
NAME            CLASS   ADDRESS   PROGRAMMED   AGE
nginx-gateway   nginx             True         13s

 

2. HttpRoute 만들기

controlplane ~ ➜  kubectl get pods,svc
NAME               READY   STATUS    RESTARTS   AGE
pod/frontend-app   1/1     Running   0          4m57s

NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/frontend-svc   ClusterIP   172.20.99.251   <none>        80/TCP    4m57s
service/kubernetes     ClusterIP   172.20.0.1      <none>        443/TCP   37m

controlplane ~ ➜  vi frontend-route.yaml 
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: frontend-route
spec:
  parentRefs:
  - name: nginx-gateway
    namespace: nginx-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: frontend-svc
      port: 80
      
controlplane ~ ➜  kubectl apply -f frontend-route.yaml 
httproute.gateway.networking.k8s.io/frontend-route created

 

 

반응형

'Container > Kubernetes' 카테고리의 다른 글

[K8S] CKA 시험 정리  (0) 2025.02.26
[K8S] StorageClass  (0) 2025.02.26
[K8S] Autoscaling - VPA  (0) 2025.02.26
[K8S] Autoscaling - HPA  (0) 2025.02.26
[K8S] Mutating/Validating Admission Controller  (0) 2025.02.24