부제: Pod IP는 수시로 바뀐다 — Service는 그 앞에 세우는 ‘고정된 접속 창구’다
A3에서
Pod는 죽고 살기를 반복하며 끊임없이 교체된다는 걸 봤다. 자기치유로 새 Pod가
채워질 때마다 그 Pod의 IP도 새로 바뀐다. 그러면 문제가 하나 생긴다.
클라이언트는 대체 어디로 요청을 보내야 하나? Pod IP는 계속 바뀌는데.
이 질문에 답하는 것이 Service다. 이번 편은 Service와 그 노출 방식들을
개념마다 한 줄씩 못박는다. (앞선 편들처럼, 깊은 네트워킹은 뒤로 미루고 쓰기에
어긋나지 않을 만큼만 정리하고 넘어간다.)
한 줄 정의부터
| 용어 | 한 줄 정의 |
|---|---|
| Service | 수시로 바뀌는 Pod IP 앞에 세우는 고정된 접속 창구(L4 로드밸런서) |
| ClusterIP | 클러스터 안에서만 통하는 고정 가상 IP(기본형) |
| NodePort | 모든 노드 IP의 정적 포트(30000–32767)로 밖에 노출 |
| LoadBalancer | 클라우드의 외부 L4 로드밸런서를 붙여 하나의 공인 IP로 노출 |
| Ingress(리소스) | HTTP 경로·호스트 기준(L7) 으로 여러 서비스를 하나의 대문에서 라우팅 |
| ingress/egress(방향) | 트래픽이 들어옴/나감 방향 — NetworkPolicy로 통제(대문자 Ingress와 다름) |

Service — 바뀌는 Pod 앞의 고정 창구
Service의 핵심은 간접 계층(indirection) 이다. 클라이언트는 Pod를 직접
가리키지 않고, Service라는 고정된 이름·IP를 바라본다. Service는 뒤에서
라벨로 묶인 Pod들을 찾아 트래픽을 나눠 보낸다. Pod가 교체되면 Service가
자기 뒤의 목록(엔드포인트)을 알아서 갱신한다.
이걸 로컬 클러스터에서 직접 시연해 캡처했다.

- ① 고정 IP + 엔드포인트 —
expose한 줄로web-svc가 생기고 ClusterIP
10.96.9.48을 받는다. 그 뒤에는 실제 Pod IP 두 개(10.244.0.17/.18)가
엔드포인트로 매달린다. - ② 이게 핵심 — Pod 하나(
.18)를 지웠더니 새 Pod가 다른 IP(.19)로
떴다. 그런데 ClusterIP는10.96.9.48그대로고, 엔드포인트 목록만
.17,.19로 자동 갱신됐다. 클라이언트 입장에선 아무것도 바뀌지 않았다 —
이게 "고정 창구"의 값이다. - ③ 노출 확장 + DNS —
type을NodePort로 바꾸니80:30967처럼 모든
노드의 정적 포트가 열렸다. 그리고 클러스터 안에서는 IP 대신
web-svc.demo-a4.svc.cluster.local같은 이름으로 부른다(CoreDNS가 해석).
노출 범위 4단계 — 안에서 밖으로
Service를 ‘얼마나 밖으로 열지’가 타입을 가른다. 안쪽부터 바깥쪽으로:
- ClusterIP (기본) — 클러스터 내부 전용. 서비스 간 통신용. 밖에서는 못 본다.
- NodePort — 모든 노드의 정적 포트(30000–32767)로 개방. "일단 밖에서
두드려는 볼 수 있게". 실무 상시 노출용으로는 투박하다. - LoadBalancer — 클라우드의 외부 L4 로드밸런서를 자동으로 붙여 하나의
공인 IP로. 상용 환경에서 서비스 하나를 밖에 낼 때의 표준. - Ingress — 여기서 계층이 한 칸 올라간다. 위 셋이 L4(IP:포트)라면 Ingress는
L7(HTTP) 이다./api는 이 서비스로,/shop은 저 서비스로 — 경로·호스트
기준 라우팅을 하나의 대문에서 처리한다. 도메인·TLS·가상호스팅이 여기 붙는다.
같은 단어 다른 뜻 — ingress / egress
이 시리즈의 두 번째 함정이다(첫 번째는 A2의
Namespace였다).
- Ingress(대문자, 리소스) — 방금 본 L7 HTTP 라우팅 오브젝트.
"어느 경로를 어느 서비스로 보낼지" 정하는 대문. - ingress / egress(소문자, 방향) — 트래픽이 들어오는 방향 / 나가는
방향을 가리키는 일반 용어. 주로NetworkPolicy에서 "이 Pod로 들어오는
트래픽(ingress)은 누구까지 허용, 나가는(egress)은 어디까지 허용"을 정할
때 쓴다. 라우팅 리소스와는 무관하다.
같은 철자를 보고 "라우팅 얘기구나"와 "방향 얘기구나"를 문맥으로 갈라 읽어야 한다.
OSI 7계층에 얹어 보기 — 왜 ClusterIP가 L4인가
앞의 노출 4단계에 자꾸 L4, L7 딱지가 붙었다. 이걸 OSI 7계층에 직접 얹으면
규칙이 눈에 들어온다.

규칙은 의외로 단순하다.
- 주소(IP)만 붙은 것 = L3(네트워크 계층).
Pod IP,Node IP가 여기다.
IP는 "어느 호스트로 라우팅할지"를 다루는 3계층 개념이다. - 포트(Port)까지 붙은 것 = L4(전송 계층).
NodePort,Service port,
LoadBalancer처럼IP:포트로 특정 프로세스까지 지목하면 4계층이다. - HTTP 경로·호스트면 = L7(응용 계층).
Ingress가 여기다.
문제의 ClusterIP가 재미있다. 주소값 10.96.9.48 자체는 분명 IP, 즉 L3다.
그림에서도 L3 자리에 유령(점선)으로 한 번 놓았다. 그런데 ClusterIP는 그냥
떠도는 IP가 아니라 IP:Port 쌍이 고정돼 있고, 그 뒤에서 kube-proxy가
포트 단위로 로드밸런싱(DNAT) 을 한다. 동작이 포트 레벨(L4) 이라는 뜻이다.
그래서 "주소는 L3지만 서비스로서는 L4 로드밸런서"로 분류하고, 그림에서
ClusterIP를 L3에서 L4로 승격(▲) 시켜 올렸다.
한 줄로: IP만 있으면 L3,
:Port고정이면 L4. ClusterIP는 IP지만:Port가
고정(+kube-proxy)이라 L4. — "그 kube-proxy가 iptables로 정확히 어떻게
꽂는가"의 기계적 내부는 네트워킹 갈래(B)에서 판다.
정리
- Pod IP는 계속 바뀐다 → Service = 그 앞의 고정 창구(라벨로 Pod를 묶고 엔드포인트 자동 갱신)
- 노출 4단계: ClusterIP(내부) → NodePort(노드 정적 포트) →
LoadBalancer(외부 L4) → Ingress(L7 HTTP 라우팅) - 실제로 Pod를 갈아도 ClusterIP는 고정, 엔드포인트만 갱신되는 걸 콘솔로 확인
- ingress/egress(방향) 과 Ingress(리소스) 는 이름만 같고 다른 것
나를 오래 걸리게 했던 "ClusterIP는 IP니까 3계층 아닌가?"라는 질문은 위 OSI
절에서 정리했다 — 주소는 L3지만 :Port 고정 + kube-proxy라서 서비스로서는
L4. 다만 "그 kube-proxy가 iptables/IPVS로 정확히 어떻게 트래픽을 꽂는가"의
기계적 내부는 개념 편의 범위를 넘어서니, 이 시리즈의 네트워킹 갈래(B) 에서
OSI 계층·iptables·cgroup과 함께 따로 판다. 시리즈 A의 마지막 편(A5)에서는
코드와 값을 떼어놓는 ConfigMap·Secret을 정리한다.
참고
- Kubernetes Docs — Service, Ingress, Service types, Network Policies
- 콘솔 캡처:
docker-desktop로컬 클러스터에서 ClusterIP→NodePort 실제 시연
답글 남기기