Skip to main content

Service & Networking

모든 Pod는 고유 IP를 가진다 — K8s 네트워킹의 핵심 원칙


1. K8s 네트워킹 모델

1.1 세 가지 규칙

  1. 모든 Pod는 고유한 IP를 가짐 (NAT 없이 직접 통신)
  2. 모든 노드의 Pod끼리 NAT 없이 통신 가능
  3. Pod가 보는 자신의 IP = 다른 Pod가 보는 그 Pod의 IP

이 규칙을 구현하는 것이 CNI(Container Network Interface) 플러그인의 역할.

1.2 네트워크 계층

flowchart TB
subgraph External["외부 트래픽"]
Client["클라이언트"]
end
subgraph L7["L7 — Ingress"]
Ingress_NW["Ingress Controller<br/>(Nginx/Traefik)"]
end
subgraph L4["L4 — Service"]
SVC["Service<br/>(ClusterIP/NodePort/LB)"]
end
subgraph L3["L3 — Pod Network"]
Pod_NW["Pod ↔ Pod<br/>(CNI 관리)"]
end

Client --> Ingress_NW --> SVC --> Pod_NW

2. Service

Pod는 죽으면 IP가 바뀜. Service는 Pod 그룹에 안정적인 IP와 DNS 이름을 부여함.

2.1 Service 유형

유형접근 범위사용
ClusterIP (기본)클러스터 내부만내부 서비스 간 통신
NodePort노드IP:포트로 외부 접근개발/테스트
LoadBalancer클라우드 LB 자동 생성✅ 프로덕션 (클라우드)
ExternalName외부 DNS로 매핑외부 서비스 참조
flowchart LR
subgraph ClusterIP_SVC["ClusterIP"]
CIP["10.96.0.100:80"] --> Pod1_C["Pod 1"] & Pod2_C["Pod 2"]
end

subgraph NodePort_SVC["NodePort"]
NP["NodeIP:30080"] --> CIP2["ClusterIP"] --> Pod1_N["Pod 1"] & Pod2_N["Pod 2"]
end

subgraph LB_SVC["LoadBalancer"]
LB_NW["외부 LB IP:80"] --> NP2["NodePort"] --> CIP3["ClusterIP"] --> Pod1_L["Pod 1"] & Pod2_L["Pod 2"]
end

2.2 Service 동작 원리

apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web # 이 레이블을 가진 Pod에 트래픽 분산
ports:
- port: 80 # Service 포트
targetPort: 8080 # Pod 포트
type: ClusterIP

kube-proxy가 각 노드에 iptables/IPVS 규칙을 생성하여, Service IP로 들어오는 트래픽을 실제 Pod IP로 분산함.

2.3 Session Affinity

spec:
sessionAffinity: ClientIP # 같은 클라이언트 → 같은 Pod
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800

3. DNS — CoreDNS

3.1 서비스 DNS

<service>.<namespace>.svc.cluster.local

예: web.default.svc.cluster.local
db.production.svc.cluster.local

같은 네임스페이스에서는 서비스 이름만으로 접근 가능: curl http://web

3.2 Pod DNS

<pod-ip-dashed>.<namespace>.pod.cluster.local

예: 10-244-1-5.default.pod.cluster.local

4. Ingress

4.1 왜 Ingress인가

Service(NodePort/LB)만으로는:

  • 서비스마다 별도 포트/LB 필요
  • TLS 종단을 각 서비스에서 처리
  • 경로/도메인 기반 라우팅 불가

Ingress는 L7 라우팅 + TLS 종단 + 호스트/경로 기반 분배를 한 곳에서 처리.

4.2 Ingress Controller

Ingress 오브젝트를 감시하고 실제 라우팅을 수행하는 컴포넌트. 별도 설치 필요.

Controller특징
Nginx Ingress✅ 가장 많이 사용. 안정적
Traefik동적 설정, Let's Encrypt 자동화
HAProxy고성능, TCP/UDP 지원
Istio GatewayService Mesh와 통합
AWS ALB IngressAWS ALB 자동 프로비저닝

4.3 Ingress 설정 예시

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80

4.4 Gateway API (Ingress 후속)

Ingress의 한계(L4 미지원, 복잡한 라우팅 어려움)를 해결하기 위해 Gateway API가 등장. K8s 공식 후속 표준.

IngressGateway API
L4✅ TCP/UDP
L7
역할 분리없음인프라(GatewayClass) / 클러스터(Gateway) / 앱(HTTPRoute)
상태안정적, 레거시GA, 점진적 전환

5. NetworkPolicy

5.1 Pod 간 트래픽 제어

기본적으로 K8s에서 모든 Pod는 모든 Pod와 통신 가능. NetworkPolicy로 이를 제한.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-policy
namespace: production
spec:
podSelector:
matchLabels:
app: db
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: api # api Pod에서만 DB 접근 허용
ports:
- port: 5432

5.2 CNI별 NetworkPolicy 지원

CNINetworkPolicy비고
Calico가장 많이 사용되는 CNI
Cilium✅ (L7까지)eBPF 기반, 관찰성 우수
Flannel가장 단순하지만 NetworkPolicy 미지원
Weave

6. CNI 비교

CNI기술NetworkPolicy특징추천
FlannelVXLAN가장 단순, 소규모/학습용학습
CalicoBGP/VXLAN✅ 가장 많이 사용, 유연한 정책프로덕션
CiliumeBPF✅ (L7)고성능, 관찰성, Service Mesh 통합✅ 차세대
WeaveVXLAN멀티클라우드 친화

💡 Calico가 현재 표준, Cilium이 차세대. Cilium은 eBPF를 사용하여 kube-proxy를 대체할 수 있고, L7 정책, 네이티브 관찰성까지 제공함. 새로 구축한다면 Cilium을 검토할 가치가 있음.


다음 글

→ #5 Storage — PV, PVC, StorageClass, CSI


📝 참고 자료