쿠버네티스(Kubernetes) 네트워킹 완벽 이해: CNI, Service, Ingress의 작동 원리
1. 쿠버네티스 네트워킹은 왜 복잡할까?
쿠버네티스를 처음 접하는 많은 개발자들이 가장 어려워하는 부분이 바로 '네트워킹'입니다. 단일 서버에서 도커 컨테이너 몇 개를 실행할 때와는 차원이 다른 복잡성을 가지고 있기 때문입니다. 쿠버네티스 클러스터는 여러 서버(노드)로 구성되며, 컨테이너(Pod)들은 이 노드들 위에서 수시로 생성되고 사라집니다. 이러한 동적인 환경에서 쿠버네티스는 다음과 같은 근본적인 네트워킹 문제들을 해결해야 합니다.
- Pod 간 통신: 서로 다른 노드에 있는 Pod들은 어떻게 서로를 찾아 통신할 수 있는가?
- 외부와의 통신: 클러스터 외부의 사용자는 어떻게 내부에 있는 Pod에 접근할 수 있는가?
- 서비스 발견: Pod는 IP가 계속 바뀌는데, 어떻게 안정적으로 서비스를 호출할 수 있는가?
- 트래픽 분산: 여러 개의 동일한 Pod에게 어떻게 트래픽을 공평하게 분배할 것인가?
쿠버네티스는 이러한 문제들을 해결하기 위해 직접 네트워크를 구현하는 대신, 강력한 '추상화 모델'과 '표준 인터페이스'를 제공합니다.
2. 모든 것의 기반: CNI(Container Network Interface)
쿠버네티스가 내세우는 네트워킹의 기본 원칙은 "모든 Pod는 자신만의 고유한 IP를 가지며, 다른 모든 Pod와 IP 주소로 직접 통신할 수 있어야 한다"는 것입니다. 하지만 쿠버네티스 자체는 이 원칙을 어떻게 구현할지에 대한 구체적인 방법을 가지고 있지 않습니다. 대신 CNI(Container Network Interface)라는 표준 규격을 정의하고, 실제 네트워크 구현은 CNI 플러그인에게 위임합니다.
Calico, Flannel, Weave Net 등 다양한 CNI 플러그인들이 이 규격에 맞춰 개발되어 있으며, 관리자는 클러스터의 특성(성능, 보안 등)에 맞는 CNI 플러그인을 선택하여 설치하면 됩니다. CNI 플러그인이 설치되면, 쿠버네티스가 새로운 Pod를 생성할 때마다 CNI가 해당 Pod에 고유한 IP를 할당하고 네트워크에 연결해주는 역할을 수행합니다.
3. 안정적인 내부 통신의 핵심: 서비스(Service)
Pod는 언제든지 장애로 인해 재시작되거나, 오토 스케일링에 의해 새로 생성되거나 삭제될 수 있습니다. 이 과정에서 Pod의 IP 주소는 계속해서 바뀝니다. 만약 프론트엔드 Pod가 백엔드 Pod의 IP 주소를 직접 참조하고 있다면, 백엔드 Pod가 재시작될 때마다 프론트엔드 Pod의 설정을 변경해야 하는 끔찍한 상황이 발생합니다.
서비스(Service)는 이러한 문제를 해결하기 위한 추상화 계층입니다. 서비스는 논리적으로 동일한 역할을 하는 여러 개의 Pod 그룹에 대해, 바뀌지 않는 고유한 IP 주소(Cluster IP)와 DNS 이름을 부여합니다. 이제 프론트엔드 Pod는 백엔드 Pod의 실제 IP가 아닌, 백엔드 '서비스'의 고정된 IP나 DNS 이름을 통해 통신하면 됩니다. 서비스는 마치 클러스터 내부의 '로드 밸런서'처럼, 자신에게 들어온 요청을 실제 동작하고 있는 건강한 Pod들에게 알아서 분배해주는 역할을 합니다.
4. 외부 트래픽을 위한 관문: 인그레스(Ingress)
'서비스'가 클러스터 내부 통신을 담당한다면, 인그레스(Ingress)는 외부의 HTTP/HTTPS 요청을 클러스터 내부의 서비스로 연결해주는 '관문(Gateway)' 역할을 합니다. 서비스를 외부에 노출하는 방법으로 `NodePort`나 `LoadBalancer` 타입의 서비스를 사용할 수도 있지만, 이 방법들은 7계층(L7) 라우팅이 불가능하고, `LoadBalancer`의 경우 서비스마다 별도의 클라우드 로드밸런서가 생성되어 비용이 많이 발생할 수 있습니다.
인그레스는 단일 IP 주소를 통해 들어온 요청을 URL 경로(Path-based routing)나 호스트 이름(Host-based routing)에 따라 각기 다른 서비스로 전달하는 '스마트 라우팅' 기능을 제공합니다. 예를 들어 `mysite.com/api` 요청은 `api-service`로, `mysite.com/admin` 요청은 `admin-service`로 전달할 수 있습니다. 인그레스가 실제로 동작하기 위해서는 NGINX Ingress Controller, Traefik 등과 같은 '인그레스 컨트롤러'가 클러스터 내에 설치되어 있어야 합니다.
5. 쿠버네티스 네트워킹 객체 비교
| 객체 (Object) | 핵심 목적 | 주요 기능 | 작동 범위 |
|---|---|---|---|
| Pod | 컨테이너 실행의 최소 단위 | 고유한 IP 주소 할당 | 단일 Pod (내부 컨테이너 간 localhost 통신) |
| Service | Pod 그룹에 대한 안정적인 단일 엔드포인트 제공 | 서비스 디스커버리, 내부 로드 밸런싱 (L4) | 클러스터 내부 (Pod 간 통신) |
| Ingress | 외부 HTTP/HTTPS 트래픽을 서비스로 라우팅 | URL/호스트 기반 라우팅, SSL/TLS 처리 (L7) | 클러스터 외부 -> 내부 |
| NetworkPolicy | Pod 간의 트래픽 흐름 제어 (방화벽) | 특정 Pod에 대한 Ingress/Egress 트래픽 규칙 정의 | 클러스터 내부 (Pod 간 보안) |
쿠버네티스의 네트워킹은 처음에는 복잡해 보일 수 있지만, 그 근간에는 '추상화'라는 강력한 개념이 자리 잡고 있습니다. Pod라는 동적인 대상을 Service라는 정적인 대상으로 추상화하고, 여러 서비스를 Ingress라는 단일 관문으로 추상화하는 과정을 이해하는 것이 핵심입니다. 이러한 네트워킹 모델 덕분에 개발자는 인프라의 복잡성에 얽매이지 않고, 확장 가능하고 탄력적인 애플리케이션을 구축하는 데 집중할 수 있습니다.
댓글
댓글 쓰기