1. ClusterIP
- Pod의 IP는 휘발성이기 때문에, 영구적인 Service의 IP를 통해서 연결
- ClusterIP 타입은 Cluster 타입 내에서만 접근이 가능
- Service는 여러 Pod에 연결이 가능하며, 각 Pod에 Random으로 트래픽은 보내줌
"Pod 들이 직접 서로를 찾지 말고, Service의 고정 IP로 통신해라"
[Client Pod]
|
| svc-1:9000
v
+-------------------+
| Service (ClusterIP)
| name: svc-1
| ClusterIP: 10.x.x.x
| Port: 9000
+-------------------+
|
| forwarding
v
+-------------------+
| Pod pod-1
| IP: 10.244.x.x
| containerPort:8080
+-------------------+
kubernetes의 통신 방식은 Pod ↔ Service 방식으로 통신한다고 생각하면 된다.
왜 Service를 쓰는가??
1. Pod의 IP는 가변적이나, Service(ClusterIP)는 고정적이다.
2. Kubernetes 내부 DNS가 자동 생성되어, 이름 기반 DNS도 제공된다.
port : Service가 받는 포트
targetPort : 실제 Pod 컨테이너 포트
Service:9000 → Pod:8080
ClusterIP는 외부 접근이 가능한가?
- 기본적으로는 불가능
- ClusterIP는 클러스터 내부 전용 IP
- Pod -> Service 접근 가능
- Node 내부 접근 가능
- 외부 PC에서는 접근 불가
그렇가면 외부접근은 어떻게 해야 하는데?
- NodePort
- LoadBalancer
- Ingress
서비스가 어떤 Pod와 연결되어 있는지 확인하는 방법
kubectl get endpoints
e.g)
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-1 1/1 Running 7 (45m ago) 2d17h 20.100.194.84 k8s-worker1 <none> <none>
pod-2 1/1 Running 6 (46m ago) 2d16h 20.110.126.14 k8s-worker2 <none> <none>
[root@k8s-master ~]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.56.30:6443 4d23h
svc-1 20.100.194.84:8080,20.110.126.14:8080 2d17h
svc-2 20.100.194.84:8080,20.110.126.14:8080 2d17h
svc-3 20.100.194.84:8080,20.110.126.14:8080 2d16h
svc-4 20.100.194.84:8080,20.110.126.14:8080 2d16h
pod-1과 pod-2는 svc-1, svc-2, svc-3, svc-4 전부에 물려 있다는 것을 확인.
2. NodePort -> Cluster 외부에서 Node IP 와 Port를 통하여 Pod에 접근하는 기술
- NodePort 타입은 ClusterIP 타입의 기능을 포함하며, 워커노드의 IP를 통해 Cluster 외부에서 연결이 가능
- Node는 사내 내부망이라면, 내부망에 있는 시스템이 임시적인 테스트 목적으로 사용
- NodePort의 할당 범위 : 30000 ~ 32767
- nodePort 속성을 넣지 않으면, Port 할당 범위 내에서 자동부여
Service
apiVersion: v1
kind: Service
metadata:
name: svc-2
spec:
selector:
app: pod
ports:
- port: 9000
targetPort: 8080
nodePort: 30001
type: NodePort
Pod
apiVersion: v1
kind: Pod
metadata:
name: pod-2
labels:
app: pod
spec:
nodeSelector:
kubernetes.io/hostname: k8s-worker2
containers:
- name: container
image: kubetm/app
ports:
- containerPort: 8080

pod -> 요청이 분산되는지 확인
apiVersion: v1
kind: Pod
metadata:
name: pod-2
labels:
app: pod
spec:
nodeSelector:
kubernetes.io/hostname: k8s-worker2
containers:
- name: container
image: kubetm/app
ports:
- containerPort: 8080

Appendix) Service를 추가하여 externalTrafficPolicy 기능 확인
apiVersion: v1
kind: Service
metadata:
name: svc-3
spec:
selector:
app: pod
ports:
- port: 9000
targetPort: 8080
nodePort: 30002
type: NodePort
externalTrafficPolicy: Local
※ externalTrafficPolicy 기본 값 : Cluster
Cluster 모드의 특징
Cluster 모드 동작
예를 들어:
| worker1 | O |
| worker2 | X |
위와 같은 상황에서 외부 사용자가:
worker2:30002
로 접속해도 Kubernetes는:
worker2
↓
cluster 내부 forwarding
↓
worker1 의 Pod
어떤 Node로 들어와도 Pod만 있으면 내부적으로 찾아간다.
externalTrafficPolicy 값을 Local로 두는 경우,
현재 Node에 Pod가 있을 때만 요청을 처리한다.
예시
| worker1 | O |
| worker2 | X |
요청 1
worker1:30002
→ 성공
왜냐면 worker1에 Pod 있음.
요청 2
worker2:30002
→ 실패
왜냐면 worker2에는 Pod 없음.
Kubernetes가 다른 Node로 forwarding 안 함.
옵션으로 Local 을 주는 이유는
- 접근 제어
- IP 기반 인증
- Rate Limit
- WAF
- GeoIP
- Apache access log
- X-Forwarded-For 분석
단점
트래픽 불균형 가능
예:
| worker1 | 3 |
| worker2 | 0 |
| worker3 | 1 |
이면:
- worker2로 온 요청은 실패
- worker1에 요청 몰림 가능
따라서
- AWS NLB
- MetalLB
- External LB
- Ingress Controller
등과 같이 사용.
LB가 Pod 있는 Node로만 보내도록 구성함.
요약
Cluster
외부 요청
↓
아무 Node 가능
↓
다른 Node Pod로 forwarding 가능
Local
외부 요청
↓
현재 Node에 Pod 있으면 처리
없으면 DROP
3. LoadBalancer
- LoadBalancer 타입의 Service는 클라우드 서비스에서 사용 가능
- LoadBalancer 타입으로 Service 생성시 NodePort 타입의 기능을 포함
- LoadBalancer가 생성해주는 IP를 통해 내부의 IP 대역은 노출시키지 않고, 외부 시스템에 연결 가능
- LoadBalancer는 NodePort를 통해 트래픽을 전달
service)
apiVersion: v1
kind: Service
metadata:
name: svc-4
spec:
selector:
app: pod
ports:
- port: 9000
targetPort: 8080
# 외부에서 접근 가능한 로드밸런서를 생성해라
type: LoadBalancer
LoadBalancer는 내부적으로 이렇게 동작
외부 사용자
↓
Cloud Load Balancer
↓
NodePort
↓
Service
↓
Pod
1. LoadBalancer 생성 -> 2. 자동으로 NodePort 생성 -> 3. 각 Node로 트래픽 전달 -> 4. Pod로 분산
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d4h
svc-1 ClusterIP 10.102.93.200 <none> 9000/TCP 2d22h
svc-2 NodePort 10.107.115.131 <none> 9000:30001/TCP 3h43m
svc-3 NodePort 10.97.23.13 <none> 9000:30002/TCP 3h16m
svc-4 LoadBalancer 10.97.102.222 <pending> 9000:30618/TCP 40m
※ 여기서 LoadBalancer의 상태는 왜 pending 상태인가?
- kubeadm
- VirtualBox
- Rocky Linux
- 직접 구성한 Kubernetes Cluster
이 환경에는:
외부 LoadBalancer를 생성해줄 시스템이 없음
그래서 Kubernetes가 계속:
"LoadBalancer 만들어주세요..."
라고 요청만 하고 기다리는 상태가 <pending>.
Kubernetes는 내부적으로:
1. ClusterIP 생성
2. NodePort 생성
3. 외부 LB 생성 요청
현재 상황은 마지막 단계에서 실패 중.
예를 들어 AWS에서는:
Kubernetes
↓
AWS API 호출
↓
ELB/NLB 자동 생성
↓
Public IP 할당
kubectl get svc
하면:
EXTERNAL-IP 52.x.x.x
같이 실제 공인 IP가 나옴.
그런데 왜 PORT는 생겼을까?
잘 보면:
9000:30618/TCP
이렇게 되어있다.
이건 Kubernetes가:
LoadBalancer 생성 실패
↓
그래도 NodePort는 만들어둠
상태라는 뜻.
즉 아래와 같이
NodeIP:30618
로 접근 가능함.
'k8s' 카테고리의 다른 글
| 8. Volume - emptyDir | hostPath | PV/PVC (0) | 2026.05.12 |
|---|---|
| 6. kubectl [create | apply | get | describe | delete | exec] (0) | 2026.05.08 |
| 5. Node Schedule (0) | 2026.05.07 |
| 4. Service (0) | 2026.05.07 |
| 3. labels (0) | 2026.05.07 |