도입부: 쿠버네티스를 운영하다 보면 “트래픽은 들어오는데 왜 장애지?” 같은 순간을 자주 만납니다. 이 글에서는 네트워킹 구성요소(Ingress/Service/DNS/NetworkPolicy)와 상태검증(Probe)·관측을 한 흐름으로 묶어, 안정성·보안·가용성 관점에서 책임 경계를 어떻게 나눌지 정리합니다.
1) 쿠버네티스 네트워킹을 “음식 배달 앱”으로 이해하기
제가 본 자료(음식 배달 앱 비유)는 쿠버네티스 네트워킹을 “요청이 들어오고, 내부에서 목적지를 찾고, 허용된 경로로만 통신하게 만드는” 구조로 설명합니다. 핵심 구성요소는 아래처럼 역할이 분리됩니다.
- Ingress / LoadBalancer: 클러스터 “바깥”에서 “안”으로 들어오는 진입점입니다. (도메인/경로 기반 라우팅, TLS 종료 등 L7 기능이 주로 여기에 붙습니다.)
- Service: Pod는 스케일링/재시작으로 IP가 바뀌지만, Service는 고정된 접근 지점(가상 IP/이름) + 로드밸런싱을 제공합니다.
- Pod: 실제 애플리케이션이 실행되는 단위입니다.
- DNS(CoreDNS): “이름으로 찾기”를 담당합니다. 보통
my-svc.my-ns.svc.cluster.local같은 형태로 서비스 디스커버리가 이뤄집니다. - NetworkPolicy: “누가 누구와 통신할 수 있는지”를 정의하는 네트워크 보안 규칙입니다. 쿠버네티스 네트워크는 기본적으로 “잘 열려있기” 때문에, 운영 환경에서는 필요한 만큼 닫아 격리를 만들어야 합니다.
정리하면, 운영 관점의 메시지는 딱 한 문장으로 귀결됩니다.
Ingress로 들어오고, Service로 분산되고, DNS로 발견하고, NetworkPolicy로 통제한다.
2) Service가 “안정적인 엔드포인트”라는 말의 진짜 의미
Service의 본질은 “Pod가 바뀌어도 클라이언트가 같은 방법으로 접근하게 해준다”입니다. 즉 Pod의 불안정성을 Service가 흡수합니다.
- Pod 교체/스케일링으로 IP가 바뀌어도 Service는 동일
- Service 뒤에 있는 엔드포인트는 동적으로 변하지만 로드밸런싱으로 흡수
- 서비스 간 호출은 DNS 이름으로 단순화
다만 실무에서는 Service만으로 부족해지는 순간도 있습니다. 예를 들어:
- L7 라우팅(경로/호스트 기반), TLS, 인증/인가가 필요해지면 Ingress(또는 Gateway/API Gateway) 계층이 필수가 됩니다.
- 클라이언트 IP 보존, 세션 유지(sticky session) 같은 요구사항이 생기면 설계 포인트가 늘어납니다.
즉, “Service가 안정적이다”는 말은 **네트워크 레벨에서의 안정적 ‘접근 지점’**을 의미하지, 애플리케이션이 정상이라는 의미는 아닙니다. 그 다음 이야기가 바로 Probe와 관측입니다.
3) Pod가 Running이어도 서비스는 고장일 수 있습니다
운영을 하다 보면 흔히 이런 상황을 봅니다.
- Pod 상태:
Running - Service 라우팅: 정상 (트래픽은 계속 들어옴)
- 실제 사용자 경험: 오류/타임아웃/데이터 불일치
자료에서는 특히 이런 포인트를 강조합니다.
- liveness probe는 “프로세스가 살아있냐”를 확인하는데 가깝고,
- 저장소 I/O, 데이터 경로 장애(예: 디스크 문제, 파일시스템 hang, 특정 의존성의 부분 장애)는 놓칠 수 있습니다.
- 그래서 “Probe만 잘 설정하면 된다”가 아니라, 별도 알림/관측 체계가 반드시 필요합니다.
즉, 네트워킹이 “연결”을 만든다면, Probe/관측은 “정상 동작을 증명”합니다.
4) readiness / liveness / startupProbe: 책임이 다릅니다
쿠버네티스의 Probe는 비슷해 보이지만 의도가 다릅니다.
- readinessProbe: “지금 이 Pod가 트래픽을 받아도 되는가?”
- 실패하면: Service 엔드포인트에서 제외(트래픽 차단)
- livenessProbe: “이 Pod는 재시작이 필요한가?”
- 실패하면: 컨테이너 재시작
- startupProbe: “초기 기동 중에는 느려도 봐주자(오탐 방지)”
- 느린 초기화/웜업이 있는 앱에서 liveness/readiness 오탐을 줄이는 안전장치
여기서 제가 특히 공감한 경고는 이 부분입니다.
liveness를 DB 같은 외부 의존성에 연결하면 장애를 ‘치료’가 아니라 ‘증폭’시킬 수 있습니다.
예를 들어 DB가 일시적으로 느려졌을 때 liveness가 실패하도록 해두면, 앱은 재시작을 반복하며 더 많은 커넥션/부하를 만들고 장애가 길어질 수 있습니다. 외부 의존성 문제는 보통 “재시작”이 답이 아니기 때문입니다.
예시: “트래픽 차단(readiness)”과 “프로세스 생존(liveness)”를 분리하기
아래 예시는 전형적인 방향성을 보여줍니다(핵심은 readiness는 ‘서빙 가능 여부’, liveness는 **‘프로세스가 정상 루프를 도는지’**에 가깝게 둔다는 점입니다).
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api
spec:
replicas: 3
selector:
matchLabels:
app: my-api
template:
metadata:
labels:
app: my-api
spec:
containers:
- name: app
image: my-api:1.0.0
ports:
- containerPort: 8080
startupProbe:
httpGet:
path: /healthz/startup
port: 8080
failureThreshold: 30
periodSeconds: 2
readinessProbe:
httpGet:
path: /healthz/ready
port: 8080
periodSeconds: 5
failureThreshold: 2
livenessProbe:
httpGet:
path: /healthz/live
port: 8080
periodSeconds: 10
failureThreshold: 3
/healthz/ready: 캐시/워커/필수 초기화가 끝났는지 등 “서빙 준비”를 체크(실패 시 트래픽만 막음)/healthz/live: 이벤트 루프/스레드 데드락 같은 “프로세스 자체 생존”에 집중(실패 시 재시작)/healthz/startup: 초기 구간은 넉넉하게 보호
(각 엔드포인트의 구현은 조직/서비스 특성에 따라 달라지지만, 외부 의존성(예: DB down)을 liveness로 바로 연결하지 않기는 강력한 기본값이라고 생각합니다.)
5) NetworkPolicy: “AI 시대라서 더 중요해진 기본기”
대화에서 “AI로 인해 보안을 많이 신경써야 할 것 같다”는 이야기가 나왔는데, 쿠버네티스 관점에서는 이 우려가 특히 NetworkPolicy로 연결되기 쉽습니다.
AI/LLM 기능이 들어가면 보통 다음이 늘어납니다.
- 외부 API 호출(egress) 증가 (모델 API, 벡터DB, 서드파티)
- 비밀정보(API 키)·민감 데이터 접근 경로 증가
- 서비스 간 통신 관계가 복잡해짐
이때 NetworkPolicy의 운영 철학은 간단합니다.
- 기본적으로 네트워크는 열려있다
- 운영에서는 가능하면 필요한 것만 열어라(least privilege)
다만 트레이드오프도 분명합니다.
- 보안↑ 대신 운영 복잡도↑ (정책 관리, 장애 시 “왜 막혔지?” 추적)
- 특히 AI 워크로드는 egress가 많아 “차단”이 가용성 리스크가 되기 쉬움
그래서 저는 NetworkPolicy를 “한 번에 완벽히”보다는,
- 핵심 네임스페이스/핵심 데이터 경로부터 격리하고
- 관측(Flow log, 네트워크 모니터링)과 함께 점진적으로 조이는 방식이 현실적이라고 봅니다.
6) 운영에서의 책임 경계: 라우팅 vs 상태검증/알림
마지막으로, 자료들을 종합했을 때 제가 정리한 “책임 경계”는 이렇습니다.
- Ingress/Service/DNS:
- “요청을 어디로 보낼지”를 책임집니다. (라우팅/디스커버리/분산)
- NetworkPolicy:
- “보내도 되는지”를 책임집니다. (허용/차단/격리)
- Probe(readiness/liveness/startup):
- “지금 서빙해도 되는지 / 재시작이 필요한지”를 책임집니다. (트래픽 차단 vs 재시작)
- 관측(메트릭/로그/트레이싱) + 알림:
- “Pod가 Running인데도 왜 장애인지”를 밝혀내는 최후의 보루입니다.
- 특히 liveness가 잡아내지 못하는 데이터 경로/스토리지/I/O 문제는 관측 없이는 놓치기 쉽습니다.
결국 “연결(네트워킹)”과 “정상성(프로브·관측)”은 따로가 아니라, 같이 설계해야 운영 품질이 올라갑니다.
마무리
쿠버네티스의 핵심은 컴포넌트 이름을 외우는 게 아니라, 트래픽 경로(Ingress/Service/DNS)와 통신 통제(NetworkPolicy), 그리고 상태 판단(Probe)·관측을 어떻게 분리하고 연결할지를 운영 관점에서 설계하는 데 있습니다. 여러분 팀에서는 “라우팅”과 “상태검증/알림”의 경계를 어디까지로 두고 있는지 한 번 점검해보시면 좋겠습니다.
