관리 메뉴

피터의 개발이야기

Ingress-Nginx로 HTTP가 아닌TCP나 UDP 트래픽 노출하기 본문

Kubernetes/network

Ingress-Nginx로 HTTP가 아닌TCP나 UDP 트래픽 노출하기

기록하는 백앤드개발자 2024. 11. 18. 23:23
반응형

ㅁ 들어가며

 Kubernetes 환경에서 Ingress-Nginx는 주로 HTTP 및 HTTPS 트래픽을 처리하는 데 사용된다. 하지만 때로는 HTTP가 아닌 TCP나 UDP 트래픽을 외부로 노출해야 할 필요가 있다. 이번 글에서는 Ingress-Nginx를 사용하여 이러한 TCP/UDP 서비스를 어떻게 노출할 수 있는지 정리하였다.

 

ㅁ TCP/UDP노출이 필요한 경우

ㅇ 많은 애플리케이션이 HTTP나 HTTPS 외에 TCP나 UDP 프로토콜을 사용한다.

 - 데이터베이스 (MySQL, PostgreSQL 등)
 - 메시징 시스템 (RabbitMQ, Kafka 등)
 - 게임 서버
 - IoT 디바이스 통신

ㅇ 이러한 서비스들이 Kubernetes 클러스터 외부에서 접근할 수 있어야 할 때가 있다.

 

Ingress-Nginx의 TCP/UDP 서비스 노출 방법

  Kubernetes Ingress 리소스는 공식적으로 외부 HTTP(s) 트래픽을 서비스로 라우팅하는 것만 지원하지만, ingress-nginx는 HTTP가 아닌 프로토콜에서 외부 TCP/UDP 트래픽을 수신하고 ConfigMap에 지정된 TCP/UDP 포트 매핑을 사용하여 이를 내부 서비스로 라우팅하도록 구성할 수 있다. 

 

ConfigMap 생성

  먼저, TCP 또는 UDP 서비스를 위한 ConfigMap을 생성해야 한다. 이 ConfigMap은 외부 포트와 내부 서비스를 매핑한다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  9000: "default/example-go:8080"

ㅇ TCP 서비스를 위한 ConfigMap이다.

ㅇ 외부 포트 9000을 default 네임스페이스의 example-go 서비스의 8080 포트로 매핑한다.

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: udp-services
  namespace: ingress-nginx
data:
  53: "kube-system/kube-dns:53"

ㅇ UDP 서비스의 경우도 동일하다.

ㅇ 외부 UDP 포트 53을 kube-system 네임스페이스의 kube-dns 서비스의 53 포트로 매핑한다.

 

Ingress-Nginx 컨트롤러 설정 수정

 Ingress-Nginx 컨트롤러가 이 ConfigMap을 사용하도록 설정해야 한다. 이는 컨트롤러의 배포 설정을 수정하여 수행할 수 있다.

 

args:
  - /nginx-ingress-controller
  - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
  - --udp-services-configmap=$(POD_NAMESPACE)/udp-services

ㅇ Ingress-Nginx 컨트롤러의 Deployment나 DaemonSet에 인자를 추가한다.

ㅇ 이렇게 하면 컨트롤러가 TCP 및 UDP 서비스를 위한 ConfigMap을 읽고 적용한다.

 

서비스 배포

실제 TCP 또는 UDP 서비스를 Kubernetes 클러스터에 배포해야 한다. 이는 일반적인 Kubernetes 서비스 배포 방식과 동일하다.

예를 들어, TCP 서비스의 경우:

apiVersion: v1
kind: Service
metadata:
  name: example-go
  namespace: default
spec:
  ports:
  - port: 8080
    targetPort: 8080
  selector:
    app: example-go
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-go
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: example-go
  template:
    metadata:
      labels:
        app: example-go
    spec:
      containers:
      - name: example-go
        image: example-go:latest
        ports:
        - containerPort: 8080

 

 

ㅁ MySQL 예시

ㅇ MySQL 데이터베이스를 외부에 노출하는 경우 샘플이다.

 

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
data:
  3306: "default/mysql:3306"

ㅇ ConfigMap 생성

 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  template:
    spec:
      containers:
      - name: controller
        args:
        - /nginx-ingress-controller
        - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services

ㅇ Ingress-Nginx 컨트롤러 수정

 

apiVersion: v1
kind: Service
metadata:
  name: mysql
  namespace: default
spec:
  ports:
  - port: 3306
    targetPort: 3306
  selector:
    app: mysql
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: password

ㅇ MySQL 서비스 배포

ㅇ 이렇게 설정하면 Ingress-Nginx의 3306 포트를 통해 MySQL 데이터베이스에 외부에서 접근할 수 있게 된다.

 

ㅁ 마무리

 Ingress-Nginx를 사용하여 TCP/UDP 서비스를 노출하는 것은 HTTP가 아닌 프로토콜을 사용하는 애플리케이션을 Kubernetes 클러스터에서 운영할 때 유용한 방법이다. 이 방식은 기존의 Ingress 리소스를 사용하지 않고도 다양한 프로토콜을 지원할 수 있게 해준다.

 

ㅁ 함께 보면 좋은 사이트

Ingress-Nginx Controller - Exposing TCP and UDP services

(NGINX Ingress Controller) - TCP, UDP service 노출해 redis cluster와 연결하기

반응형
Comments