블로그 | NGINX

쿠버네티스 네트워킹 101

NGINX-F5-수평-검정-유형-RGB의 일부
브라이언 엘러트 썸네일
브라이언 엘러트
2022년 1월 4일 게시

NodePort, LoadBalancer, Ingress 컨트롤러...맙소사!

Kubernetes를 프로덕션 수준으로 만드는 것에 대해 고객과 커뮤니티와 이야기를 나눌 때 가장 흔한 질문 중 하나는 "Ingress 컨트롤러가 필요한가?"입니다. 이 질문에 대한 답은 대체로 간단하게 '예'나 '아니요'로 끝나지 않지만, 대신 포드로 트래픽을 유도하는 다양한 방법에 대한 교육이 포함됩니다. 이 블로그에서는 Kubernetes 네트워킹의 기본 사항을 다루어 Ingress 컨트롤러가 필요한지 여부와 시기를 파악하고 이에 대한 정보에 입각한 결정을 내릴 수 있도록 도와드립니다.

쿠버네티스는 외부 트래픽을 포드로 라우팅하기 위한 여러 가지 접근 방식과 계층을 지원하지만, 이러한 접근 방식과 계층은 모두 동일하게 만들어진 것은 아닙니다. 기본 모델은 kube-proxy 인데, 이는 실제 프록시가 아니며 트래픽 부하 분산, API 제어 또는 서비스 동작 모니터링을 위해 설계되지 않았습니다.

다행히도 외부 트래픽을 관리하는 다른 방법이 있지만 계속하기 전에 Kubernetes 구성 요소를 간단히 살펴보겠습니다.

  • Kubernetes 배포는 물리적 머신이나 가상 머신인 노드 로 구성됩니다.
  • 노드가 모여 클러스터를 형성합니다.
  • 각 클러스터는 Kubernetes의 네트워킹 및 인프라 수준에서 가장 낮은 공통 분모인 Pod를 관리합니다. 하나 이상의 Pod가 모여 서비스를 구성합니다.
  • 각 포드 내부에는 하나 이상의 컨테이너가 들어 있습니다(애플리케이션 크기에 따라 다름).

쿠버네티스는 서비스를 구성하는 포드를 감시하고 앱 요구 사항에 맞게 필요에 따라 확장합니다. 하지만 포드에 트래픽을 어떻게 유도하나요? 여기서 두 가지 유형의 Kubernetes 객체, 즉 서비스와 Ingress 컨트롤러가 등장합니다.

쿠버네티스 서비스란?

Kubernetes 문서 에 따르면 서비스는 "Pod 세트에서 실행되는 앱을 노출하는 추상적인 방법"입니다. 서비스는 컨테이너의 클러스터 또는 네트워크에 있는 포드를 연결하는데, 이때 포드의 특정 노드 위치는 중요하지 않습니다. 즉, 위치가 변경되거나 파괴되었다가 다시 시작되더라도 외부 트래픽을 특정 포드로 라우팅할 수 있습니다. 이런 방식으로 서비스는 매우 기본적인 역방향 프록시처럼 작동합니다.

외부 트래픽을 Kubernetes로 라우팅하는 데에는 여러 유형의 서비스와 서비스 객체 유형이 있습니다. 이 둘은 종종 서로 혼동되지만, 사실 각각은 매우 다른 일을 하므로, 각각의 기능, 용도, 단점을 살펴보는 것이 좋습니다.

클러스터IP

ClusterIP는 클러스터 내의 다른 서비스가 액세스할 수 있는 Kubernetes 내의 서비스를 제공하는 기본 서비스입니다. 클러스터 외부에서는 접근할 수 없습니다. ClusterIP 서비스를 노출하는 유일한 방법은 kube-proxy 와 같은 것을 사용하는 것이지만, 이것이 적합한 시나리오는 거의 없습니다. 제한적인 예로는 노트북에서 서비스에 액세스하거나, 서비스를 디버깅하거나, 모니터링과 측정 항목을 살펴보는 것이 있습니다.

노드포트

NodePort 서비스는 클러스터의 모든 노드에서 특정 포트를 열고 해당 포트의 노드로 전송된 모든 트래픽을 해당 앱으로 전달합니다. 이는 앱으로 트래픽을 가져오는 매우 기본적인 방법이며 실제 트래픽 관리 사용 사례에는 많은 제한이 있습니다. NodePort 하나에는 서비스를 하나만 사용할 수 있으며, 30000~32767 범위의 포트만 사용할 수 있습니다. 2768개의 포트가 많은 것처럼 들릴 수 있지만, 대규모로 Kubernetes를 실행하는 조직에서는 곧 포트가 부족해질 것입니다. 또한 NodePort는 레이어 4 라우팅 규칙과 Linux iptables 유틸리티를 사용하여 레이어 7 라우팅을 제한합니다.

라우팅 제한 외에도 NodePort를 사용하는 데에는 세 가지 큰 단점이 있습니다.

  • 다운스트림 클라이언트는 연결하기 위해 각 노드의 IP 주소를 알아야 합니다. 노드의 IP 주소나 가상 머신 호스트가 변경되면 문제가 됩니다.

  • NodePort는 트래픽을 여러 IP 주소로 프록시할 수 없습니다.

  • 다이어그램에서 볼 수 있듯이 NodePort는 Kubernetes 클러스터 내에서 부하 분산을 제공하지 않으므로 트래픽은 서비스 전체에 무작위로 분산됩니다. 이로 인해 서비스 과부하 및 항구 고갈이 발생할 수 있습니다.

    NodePort 객체를 사용하여 Kubernetes 서비스를 노출하는 토폴로지 다이어그램

로드 밸런서

LoadBalancer 서비스는 외부 트래픽을 허용하지만 해당 트래픽에 대한 인터페이스로 외부 로드 밸런서가 필요합니다. 외부 로드 밸런서가 실행 중인 Pod에 매핑되도록 적절히 조정되고 재구성된 경우 이는 레이어 7 라우팅(Pod IP 주소로)을 지원합니다. LoadBalancer는 서비스를 외부에 노출하는 가장 인기 있는 방법 중 하나입니다. 이는 클라우드 플랫폼에서 가장 자주 사용되며 소규모의 정적 배포에 적합한 선택입니다.

관리형 Kubernetes 서비스를 사용하는 경우 클라우드 공급자가 선택한 로드 밸런서를 자동으로 받게 됩니다. 예를 들어, Google Cloud Platform에서는 LoadBalancer 서비스 유형을 사용하여 네트워크 로드 밸런서를 시작할 수 있는 반면, AWS에서는 ALB(Application Load Balancer)가 기본값입니다. 공개하는 각 서비스는 모든 트래픽을 전달하는 자체 공용 IP 주소를 받지만 필터링이나 라우팅은 없으므로 거의 모든 유형의 트래픽(HTTP, TCP/UDP, 웹소켓 등)을 전송할 수 있습니다. 또는 클라우드 제공업체의 툴링을 사용하고 싶지 않은 경우(예: 더 많은 기능이나 플랫폼에 독립적인 툴이 필요한 경우) F5 BIG-IP (외부 로드 밸런서) 및 F5 Container Ingress Services (LoadBalancer 역할을 하는 운영자) 등으로 대체할 수 있습니다. 이 패턴에 대한 자세한 내용은 블로그의 동일한 아키텍처에서 BIG-IP와 NGINX Ingress Controller 배포를 참조하세요.

동적 환경에서는 앱 포드를 확장하여 변화하는 수요 수준에 맞춰야 하기 때문에 LoadBalancer를 사용하여 앱을 노출하는 것이 어려워집니다. 각 서비스에는 고유한 IP 주소가 있으므로 인기 있는 앱은 관리해야 할 IP 주소가 수백 개, 심지어 수천 개에 달할 수 있습니다. 대부분의 경우, 외부 로드 밸런서는 다음 다이어그램과 같이 NodePort를 통해 서비스에 연결합니다. 이를 통해 트래픽이 노드 전체에 고르게 분산되는 것은 보장되지만 여전히 서비스에 대한 로드 밸런싱은 불가능하므로 여전히 서비스 과부하 및 포트 고갈이 발생합니다.

Kubernetes LoadBalancer 및 NodePort 객체를 사용하여 Kubernetes 서비스를 노출하는 토폴로지 다이어그램

Kubernetes Ingress Controller란 무엇입니까?

Kubernetes 문서 에 따르면 "컨트롤러는 클러스터의 상태를 감시하고 필요한 경우 변경을 수행하거나 요청하는 제어 루프입니다. 각 컨트롤러는 현재 클러스터 상태를 원하는 상태에 더 가깝게 옮기려고 시도합니다." 컨트롤러는 Kubernetes에서 다양한 작업의 상태를 관리하는 데 사용됩니다. 여기에는 리소스를 적절히 할당하고, 영구 저장소를 지정하고, Cron 작업을 관리하는 것이 포함됩니다.

라우팅 컨텍스트에서 Ingress 컨트롤러는 NodePort와 LoadBalancer의 한계를 극복하는 방법입니다.

Ingress 컨트롤러는 특정 서비스에 레이블이 지정된 Pod와의 외부 상호작용을 구성하고 관리하는 데 사용됩니다. Ingress 컨트롤러는 동적 Layer 7 라우팅을 일급 시민으로 처리하도록 설계되었습니다. 즉, Ingress 컨트롤러는 훨씬 더 세부적인 제어와 관리를 제공하면서도 작업 부담은 줄였습니다. Ingress 컨트롤러는 Ingress 트래픽을 제어할 뿐만 아니라 서비스 수준 성능 측정 항목을 제공하고 보안 정책의 일부로 활용하는 데도 쉽게 사용할 수 있습니다. Ingress 컨트롤러는 TLS 종료, 여러 도메인 및 네임스페이스 처리, 트래픽 로드 밸런싱 등 기존 외부 로드 밸런서의 많은 기능을 제공합니다. Ingress 컨트롤러는 서비스 수준이 아닌 요청별로 트래픽 부하를 분산할 수 있어 레이어 7 트래픽을 보다 유용하게 볼 수 있으며 SLA를 시행하는 훨씬 더 나은 방법입니다.

그리고 또 다른 보너스가 있습니다! Ingress 컨트롤러는 특정 Pod에서 특정 외부 서비스로만 나가는 트래픽을 허용하는 송신 규칙을 시행하거나, mTLS를 사용하여 트래픽이 상호 암호화되도록 보장할 수도 있습니다. mTLS를 요구하는 것은 의료, 금융, 통신, 정부 등의 산업에서 규제된 서비스를 제공하는 데 필수적이며 종단간 암호화(E2EE) 전략의 핵심 구성 요소입니다. 동일한 도구에서 나가는 트래픽을 제어하면 서비스에 비즈니스 로직을 적용하는 것도 간소화됩니다. 수신과 송신이 모두 동일한 제어 평면에 연결되어 있으면 적절한 리소스 규칙을 설정하는 것이 훨씬 쉽습니다.

다음 다이어그램은 Ingress 컨트롤러가 클라이언트의 복잡성을 어떻게 줄이는지 보여줍니다. 클라이언트는 더 이상 서비스의 IP 주소나 포트를 알 필요가 없습니다. 서비스 전반에 걸친 트래픽 분산이 보장됩니다. 일부 Ingress 컨트롤러는 더 큰 유연성과 제어력을 위해 여러 가지 부하 분산 알고리즘을 지원합니다.

Ingress 컨트롤러를 사용하여 Kubernetes 서비스를 노출하는 토폴로지 다이어그램

Ingress 컨트롤러를 사용하여 로드 밸런서 배포

동일한 아키텍처에서 BIG-IP와 NGINX Ingress Controller를 배포하는 방법 에서 설명한 대로, 많은 조직에서는 Ingress 컨트롤러(또는 대부분의 경우 여러 Ingress 컨트롤러 인스턴스)와 함께 외부 로드 밸런서를 배포하는 데 이점을 얻는 사용 사례가 있습니다. 이는 특히 조직이 Kubernetes를 확장하거나 엄격한 규정 준수 환경에서 운영해야 할 때 일반적입니다. 도구는 일반적으로 여러 팀에서 관리하며 다양한 목적으로 사용됩니다.

  • 로드 밸런서(또는 ADC):

    • 소유자: NetOps(또는 SecOps) 팀
    • 사용 사례: 클러스터 외부의 사용자에게 제공되는 서비스와 앱을 위한 유일한 공개 엔드포인트로서 Kubernetes 외부에 있습니다. 보안을 용이하게 하고 고수준의 네트워크 관리를 제공하도록 설계된 보다 일반적인 어플라이언스로 사용됩니다.
  • 인그레스 컨트롤러:

    • 소유자: 플랫폼 운영 또는 DevOps 팀
    • 사용 사례: 북쪽에서 남쪽으로 향하는 트래픽(HTTP2, HTTP/HTTPS, SSL/TLS 종료, TCP/UDP, WebSocket, gRPC)의 세분화된 부하 분산, API 게이트웨이 기능, 중앙 집중식 보안 및 ID를 위한 Kubernetes 내부입니다.

이 다이어그램은 여러 클러스터에 걸쳐 트래픽을 분산하는 로드 밸런서를 보여 주며, 클러스터에는 서비스에 균등하게 분산되도록 Ingress 컨트롤러가 있습니다.

Ingress 컨트롤러 앞에 로드 밸런서를 배포하는 토폴로지 다이어그램

다음 단계

이 글을 다 읽었는데도 여전히 고민이 되신다면 Linux Foundation 웨비나 'Ingress 컨트롤러가 필요한 이유와 선택 방법'을 시청해 보세요. NGINX 전문가가 Kubernetes 네트워킹에 대한 기본 사항을 설명하고, Ingress 컨트롤러를 자세히 살펴보고, Ingress 컨트롤러 환경에 대해 논의합니다.

Ingress 컨트롤러를 사용하는 방법과 요구 사항에 가장 적합한 컨트롤러를 선택하는 방법에 대한 자세한 내용은 Ingress 컨트롤러 선택 가이드, 1부를 읽어보세요. 귀하의 요구 사항을 블로그에서 확인하세요 .


"이 블로그 게시물에는 더 이상 사용할 수 없거나 더 이상 지원되지 않는 제품이 참조될 수 있습니다. 사용 가능한 F5 NGINX 제품과 솔루션에 대한 최신 정보를 보려면 NGINX 제품군을 살펴보세요. NGINX는 이제 F5의 일부가 되었습니다. 이전의 모든 NGINX.com 링크는 F5.com의 유사한 NGINX 콘텐츠로 리디렉션됩니다."