NodePort vs. LoadBalancer vs. Ingress: 최적의 서비스 노출 방법 선택
NodePort, LoadBalancer, Ingress를 비교하여 Kubernetes 서비스를 외부에 노출하는 중요한 선택을 안내합니다. 이 가이드는 각 방법의 아키텍처, 운영 계층(L4 vs L7), 사용 사례, 비용 및 복잡성의 주요 차이점을 자세히 설명합니다. 테스트용 간단한 NodePort, 단일 서비스용 전용 LoadBalancer, 중앙 집중식 비용 효율적인 L7 라우팅 및 복잡한 다중 서비스 환경을 위한 강력한 Ingress를 언제 사용해야 하는지 알아보세요.
NodePort vs. LoadBalancer vs. Ingress: 최적의 서비스 노출 방법 선택
Kubernetes는 Pod에 임시 IP를 할당한 후, Service를 사용하여 안정적인 접근 방법을 제공합니다. 클러스터 내부에서는 일반 ClusterIP Service로 충분한 경우가 많습니다. 클러스터 외부에서 연결해야 할 때 질문은 더 흥미로워집니다.
가장 자주 언급되는 세 가지 이름은 NodePort, LoadBalancer, Ingress입니다. 이들은 관련되어 있지만 서로 대체할 수 없습니다. NodePort는 각 노드에서 포트를 엽니다. LoadBalancer는 인프라 제공자에게 외부 로드 밸런서를 요청합니다. Ingress는 HTTP 라우팅 규칙을 정의하며, 이러한 규칙을 실제로 구현하려면 Ingress 컨트롤러가 필요합니다.
1. 서비스 노출 유형: NodePort
NodePort 서비스 유형은 서비스를 외부에 노출하는 가장 간단하고 기본적인 방법입니다. 서비스를 NodePort로 정의하면 Kubernetes는 클러스터의 모든 노드에서 특정 정적 포트를 엽니다. 모든 노드의 해당 포트로 향하는 트래픽은 서비스로 직접 라우팅됩니다.
NodePort 작동 방식
- 지정된 범위(기본값: 30000-32767) 내에서 임의의 포트가 자동으로 선택됩니다.
- 이 포트는 모든 클러스터 노드에서 열립니다.
- Service는 이 NodePort에서 수신 대기하며 트래픽을 적절한 Pod로 전달합니다.
애플리케이션에 접근하려면 http://<Node_IP>:<NodePort>를 사용합니다.
사용 사례 및 제한 사항
| 기능 | 설명 |
|---|---|
| 사용 사례 | 개발, 테스트 환경 또는 외부 로드 밸런싱이 외부 비클라우드 장비에서 처리되는 경우. |
| 복잡성 | 매우 낮음. |
| 비용 | 0 (기본 VM 비용을 무시하는 경우). |
| 제한 사항 | 외부 방화벽 규칙을 수동으로 관리해야 함. 노드 IP는 동적인 경우가 많음. 포트 범위 제한 (30000-32767). |
NodePort 예시
apiVersion: v1
kind: Service
metadata:
name: my-app-nodeport
spec:
type: NodePort
selector:
app: my-web-app
ports:
- port: 80
targetPort: 8080
# 선택 사항: NodePort를 지정하지 않으면 자동으로 선택됨
# nodePort: 30001
경고: NodePort는 노드 IP와 높은 포트를 통해 서비스를 노출합니다. 특히 베어 메탈에서 자체 외부 로드 밸런서 뒤에서 유용할 수 있지만, 프로덕션 웹 앱의 공용 인터페이스로는 부적합합니다.
2. 서비스 노출 유형: LoadBalancer
LoadBalancer 서비스 유형은 클라우드 환경(AWS EKS, GCP GKE, Azure AKS)에서 애플리케이션을 공용 인터넷에 노출하는 표준 방법입니다.
서비스가 LoadBalancer로 정의되면 Kubernetes는 클러스터의 로드 밸런서 통합에 외부 로드 밸런서를 프로비저닝하도록 요청합니다. 관리형 클라우드 클러스터에서는 종종 클라우드 L4 로드 밸런서를 의미합니다. 베어 메탈 클러스터에서는 MetalLB와 같은 프로젝트 또는 다른 로컬 통합을 의미할 수 있습니다. 결과는 일반적으로 Service로 트래픽을 전달하는 안정적인 외부 주소입니다.
클라우드 제공자 통합
LoadBalancer의 주요 차별점은 기본 클라우드 인프라와의 긴밀한 통합입니다. 클라우드 제공자는 로드 밸런서의 수명 주기, 상태 확인 및 라우팅을 처리합니다.
사용 사례 및 비용 영향
| 기능 | 설명 |
|---|---|
| 사용 사례 | 전용 안정적인 IP 주소가 필요한 단순한 공용 애플리케이션. HTTP/S가 아닌 프로토콜(TCP/UDP)에 적합. |
| 복잡성 | 낮음 (구성 측면). |
| 비용 | 각 Service가 별도의 로드 밸런서 리소스를 생성할 수 있으므로 클라우드 환경에서 종종 더 높음. |
| 이점 | 즉각적인 고가용성 및 자동 상태 확인 제공. |
LoadBalancer 예시
apiVersion: v1
kind: Service
metadata:
name: my-app-loadbalancer
spec:
type: LoadBalancer
selector:
app: my-api-service
ports:
- protocol: TCP
port: 80
targetPort: 8080
생성 시 클러스터는 클라우드 제공자가 관리하는 외부 IP 주소(서비스 상태에 표시됨)를 할당합니다.
3. Kubernetes Ingress: 계층 7 라우팅
Ingress는 NodePort 및 LoadBalancer와 근본적으로 다릅니다. Ingress는 Service 유형이 아니라 일반적으로 HTTP 및 HTTPS(계층 7)에 대한 외부 액세스 규칙을 정의하는 API 객체입니다.
Ingress는 중앙 진입점 역할을 하며 호스트 이름과 URL 경로를 기반으로 정교한 라우팅을 허용합니다. 이 접근 방식은 단일 IP 주소 뒤에서 여러 서비스를 관리하는 데 필수적입니다.
Ingress 컨트롤러의 역할
Ingress 규칙이 작동하려면 먼저 Ingress Controller(ingress-nginx, Traefik, HAProxy 또는 클라우드 제공자 컨트롤러 등)를 배포해야 합니다. Istio와 같은 서비스 메시도 게이트웨이 스타일 트래픽 관리를 제공할 수 있지만, 기본 Kubernetes Ingress API와 동일하지 않습니다.
Ingress 컨트롤러 자체는 일반적으로 단일 LoadBalancer 또는 NodePort Service를 사용하여 노출됩니다.
Ingress의 고급 기능
Ingress는 고급 트래픽 관리 기능이 필요할 때 빛을 발합니다.
- 비용 최적화: 애플리케이션 서비스당 하나의 LoadBalancer 대신 단일 클라우드 LoadBalancer(컨트롤러 노출용)를 사용합니다.
- 가상 호스팅: 호스트 이름을 기반으로 트래픽 라우팅(
api.example.com은 Service A로,www.example.com은 Service B로). - 경로 기반 라우팅: URL 경로를 기반으로 트래픽 라우팅(
/v1/users는 Service A로,/v2/posts는 Service B로). - SSL/TLS 종료: 인증서 관리 및 암호 해독을 중앙에서 처리합니다.
Ingress 리소스 예시
이 예시는 api.example.com/v1에 대한 트래픽을 my-api-v1 서비스로 라우팅합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
ingressClassName: nginx # 사용 중인 컨트롤러 지정
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: my-api-v1
port:
number: 80
# ... 다른 서비스/호스트에 대한 규칙
4. 비교 및 선택 가이드
최적의 방법을 선택하려면 환경, 복잡성, 기능 세트 및 운영 비용과 같은 요소를 고려해야 합니다.
기능 비교표
| 기능 | NodePort | LoadBalancer | Ingress |
|---|---|---|---|
| 계층 | L4 (TCP/UDP) | L4 (TCP/UDP) | L7 (HTTP/S) |
| 안정성 (IP) | 불안정 (노드 IP 사용) | 안정적 (전용 클라우드 IP) | 안정적 (컨트롤러 IP 사용) |
| 비용 | 낮음 (운영 오버헤드 높음) | 높음 (서비스당 리소스 비용) | 보통 (컨트롤러용 LoadBalancer 하나) |
| 라우팅 로직 | 단순 포트 전달 | 단순 포트 전달 | 호스트 이름, 경로, SSL 종료 |
| 클라우드 의존성 | 없음 | 제공자 통합에 따라 다름 | 컨트롤러 및 노출 방법에 따라 다름 |
| 프로덕션 준비 | 때때로, 일반적으로 다른 로드 밸런서 뒤에서 | 간단한 L4 노출의 경우 예 | HTTP/S 라우팅의 경우 예 |
결정 기준: 노출 방법 선택
내부 또는 테스트 전용: 클러스터 내 연결을 테스트하거나 외부 네트워킹을 직접 관리하는 경우(예: 베어 메탈 환경) NodePort를 사용합니다.
간단한 전용 L4 노출: 애플리케이션이 HTTP가 아닌 프로토콜(예: 사용자 정의 TCP 프로토콜 또는 UDP)을 사용하거나 즉각적인 전용 L4 액세스가 필요한 단일 공용 애플리케이션이 하나만 있는 경우 LoadBalancer를 사용합니다.
복잡한 다중 서비스 L7 노출: 노출할 여러 서비스가 있고, 경로 기반 또는 호스트 이름 기반 라우팅이 필요하거나, 중앙 집중식 SSL 종료가 필요하거나, 단일 외부 IP를 공유하여 클라우드 비용을 최소화하려는 경우 Ingress를 사용합니다.
많은 프로덕션 HTTP/S 애플리케이션의 경우 Ingress가 인증서와 라우팅을 중앙 집중화하므로 일반적인 선택입니다. 데이터베이스, 메시지 브로커, 게임 서버, 원시 TCP 서비스 또는 HTTP가 아닌 모든 것의 경우 LoadBalancer Service가 더 명확할 수 있습니다. 베어 메탈 클러스터의 경우 NodePort가 여전히 설계의 일부일 수 있지만 일반적으로 적절한 외부 로드 밸런서 또는 방화벽 규칙 뒤에 배치됩니다.
실제 클러스터에서의 조합 방식
혼란스러운 점 중 하나는 이러한 옵션이 서로 위에 쌓일 수 있다는 것입니다. Ingress 객체는 자체적으로 패킷을 노출하지 않습니다. 컨트롤러는 어떻게든 트래픽을 수신하며, 그 "어떻게"는 클라우드 클러스터에서 종종 LoadBalancer Service입니다.
인터넷
-> 클라우드 로드 밸런서
-> ingress-nginx용 LoadBalancer 유형 Service
-> Ingress 컨트롤러 Pod
-> Ingress 규칙
-> ClusterIP Service
-> 애플리케이션 Pod
베어 메탈에서는 경로가 대신 NodePort를 사용할 수 있습니다.
인터넷 또는 사무실 네트워크
-> 외부 로드 밸런서 / 방화벽
-> NodeIP:NodePort
-> Ingress 컨트롤러 Pod
-> 애플리케이션 Service
그렇기 때문에 "LoadBalancer 대신 Ingress를 사용하라"고 말하는 것은 다소 부정확합니다. Ingress는 여전히 로드 밸런서를 사용하는 경우가 많지만, 여러 HTTP 애플리케이션이 하나의 진입점을 공유할 수 있도록 합니다.
실용적인 예시
랩 클러스터를 디버깅하거나, 개인 네트워크에 서비스를 임시로 노출하거나, 이미 관리하는 로드 밸런싱 하드웨어와 통합할 때 NodePort를 사용하십시오. 이것이 진정으로 내부 도구가 아니라면 사용자에게 https://app.example.com:31427을 기억하도록 강요하지 마십시오.
하나의 서비스에 안정적인 외부 주소가 필요하고 L4 전달로 충분할 때 LoadBalancer를 사용하십시오. 공용 TCP API, UDP 서비스 또는 단일 내부 관리 엔드포인트가 이 방식으로 더 간단할 수 있습니다. 또한 애플리케이션 프로토콜이 일반 HTTP 호스트/경로 라우팅에 맞지 않을 때 유용합니다.
웹 애플리케이션이 있을 때 Ingress를 사용하십시오. api.example.com, docs.example.com, app.example.com이 모두 동일한 클러스터에 있는 경우 Ingress는 호스트 라우팅 및 TLS를 관리할 수 있는 단일 장소를 제공합니다. cert-manager를 추가하면 인증서 갱신이 수동 서버 작업 대신 일반적인 클러스터 워크플로우가 될 수 있습니다.
보안 및 운영 확인 사항
노출 객체는 프로덕션 결정의 일부일 뿐입니다. 또한 엔드포인트에 누가 도달할 수 있는지, TLS가 어디서 종료되는지, 소스 IP가 어떻게 보존되는지, 장애가 어떻게 관찰되는지도 물어봐야 합니다.
NodePort를 사용하는 경우 방화벽 규칙을 주의 깊게 확인하십시오. Kubernetes는 모든 노드에서 포트를 열 수 있지만, 네트워크는 여전히 외부 세계가 해당 포트에 도달할 수 있는지 결정합니다. 클라우드 환경에서는 보안 그룹 또는 방화벽 규칙이 NodePort 범위를 허용해야 하는 경우가 많습니다. 베어 메탈에서는 동일한 문제가 경계 방화벽에 있을 수 있습니다. 개인 관리 도구가 VPN에서만 접근 가능하도록 의도한 경우 Kubernetes 외부와 내부에서 이를 강제하십시오.
LoadBalancer를 사용하는 경우 제공자별 주석을 검사하십시오. 이러한 주석은 종종 로드 밸런서가 내부용인지 인터넷 연결용인지, 사용하는 프로토콜, 상태 확인 경로, 클라이언트 소스 IP를 보존하는지 여부를 제어합니다. 이러한 세부 사항은 제공자에 따라 다르므로 한 클라우드에서 복사한 매니페스트가 다른 클라우드에서 동일하게 작동할 것이라고 가정하지 마십시오.
Ingress를 사용하는 경우 운영 중심이 컨트롤러로 이동합니다. 애플리케이션 Pod뿐만 아니라 컨트롤러 Pod의 로그와 메트릭이 필요합니다. 경로가 실패하면 Service와 Pod는 정상이지만 컨트롤러가 규칙을 거부했거나, 잘못된 ingress class를 사용했거나, TLS 시크릿을 놓쳤거나, 잘못된 백엔드 경로로 라우팅했을 수 있습니다. 빠른 체크리스트가 도움이 됩니다.
kubectl get ingress
kubectl describe ingress example-ingress
kubectl get svc -n ingress-nginx
kubectl logs -n ingress-nginx deploy/ingress-nginx-controller
또한 TLS에 대해 명확히 하십시오. Ingress는 일반적으로 컨트롤러에서 HTTPS를 종료하고 백엔드 Service로 HTTP를 보냅니다. 이는 많은 내부 클러스터에 적합하지만, 일부 팀은 애플리케이션 Pod까지 암호화를 요구합니다. 그것이 요구 사항이라면 Ingress가 자동으로 제공한다고 가정하는 대신 의도적으로 백엔드 TLS를 구성하십시오.
일반적인 장애 모드
NodePort가 한 노드에서는 작동하지만 다른 노드에서는 작동하지 않는 경우, 실패한 노드에서 kube-proxy 또는 클러스터 CNI가 정상인지 확인하십시오. 또한 외부 방화벽이 사용하려는 모든 노드 IP로의 트래픽을 허용하는지 확인하십시오.
LoadBalancer Service가 Pending 상태로 남아 있으면 클러스터가 외부 로드 밸런서를 프로비저닝할 수 없는 것입니다. 관리형 Kubernetes에서는 클라우드 컨트롤러 통합, 권한, 서브넷 태그, 할당량 또는 제공자별 설정이 누락되었음을 의미할 수 있습니다. 베어 메탈 Kubernetes에서는 일반적으로 로드 밸런서 구현이 설치되지 않았음을 의미합니다.
Ingress가 기본 백엔드 페이지 또는 컨트롤러의 404를 반환하는 경우 요청이 컨트롤러에 도달했지만 호스트 또는 경로 규칙과 일치하지 않은 것입니다. DNS, Host 헤더, ingressClassName, 경로 유형, Service 이름과 포트가 올바른지 확인하십시오. 잘못된 호스트 이름에 대한 TLS 인증서를 받은 경우 Ingress에서 참조하는 시크릿과 다른 Ingress 규칙이 동일한 호스트를 요구하고 있는지 확인하십시오.
간단한 결정 지름길
프로토콜부터 시작하십시오. HTTP 또는 HTTPS이고 둘 이상의 앱이 결국 진입점을 공유할 수 있는 경우 Ingress를 사용하십시오. 원시 TCP 또는 UDP이고 안정적인 외부 주소가 필요한 경우 LoadBalancer를 사용하십시오. 테스트 중이거나, 자체 네트워크 장비와 통합하거나, 베어 메탈 경로를 구축하는 경우 NodePort가 답의 일부일 수 있습니다.
그런 다음 운영 모델을 확인하십시오. 하나의 공용 API를 실행하는 소규모 팀은 명확하고 디버깅하기 쉽기 때문에 하나의 LoadBalancer를 선호할 수 있습니다. 수십 개의 웹 서비스를 호스팅하는 플랫폼 팀은 일반적으로 공유 라우팅, 인증서 및 정책이 추가 컨트롤러 계층보다 더 중요하기 때문에 Ingress를 선호합니다.
최종 참고 사항
어떤 객체가 더 고급스러워 보이는지가 아니라 프로토콜과 운영에 따라 선택하십시오. NodePort는 구성 요소입니다. LoadBalancer는 간단한 외부 L4 액세스입니다. Ingress는 컨트롤러를 통한 HTTP/S 라우팅입니다. 소규모 클러스터에서는 세 가지 모두 동일한 설계에 나타날 수 있으며, 각각 명확한 역할이 있다면 괜찮습니다.