Service
- Pod는 언제든 죽고 다시 생길 수 있다.
- 그래서 Pod IP를 직접 보고 접근하면 안정적이지 않다.
- Service는 여러 Pod 앞에 붙는 고정 진입점이다.
- 사용자는 Service IP로 접근하고, Service가 뒤쪽 Pod로 트래픽을 분산한다.
정리하면, Pod는 일회성에 가깝고 Service는 고정된 주소 역할을 한다. 그래서 쿠버네티스에서 애플리케이션을 연결할 때는 보통 Pod가 아니라 Service를 바라본다.
Service 타입
| 타입 | 역할 | 사용 상황 |
|---|---|---|
| ClusterIP | 클러스터 내부에서만 접근 가능한 Service IP를 만든다. | 백엔드, DB, 내부 API처럼 외부에 공개하지 않는 서비스 |
| NodePort | 각 Node의 특정 포트를 통해 Service에 접근하게 한다. | 테스트 환경, 간단한 외부 노출 |
| LoadBalancer | 클라우드 로드밸런서를 붙여 외부 트래픽을 받는다. | AWS, GCP, Azure 같은 클라우드 환경 |
| ExternalName | 외부 DNS 이름을 Service처럼 연결한다. | 클러스터 밖의 DB, 외부 API 연결 |
NodePort
- NodePort는 모든 Node에 같은 포트를 열어준다.
- 예를 들어
30080포트를 열면NodeIP:30080으로 접근할 수 있다. - 트래픽은 NodePort → Service → Pod 순서로 들어간다.
- 직접 운영 환경에서 쓰기보다는 테스트나 학습용으로 이해하면 좋다.
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
여기서 port, targetPort, nodePort가 헷갈릴 수 있다.
port: Service가 받는 포트targetPort: 실제 Pod 컨테이너가 받는 포트nodePort: 외부에서 Node로 접근할 때 쓰는 포트
LoadBalancer
- LoadBalancer는 외부 사용자가 접근할 수 있는 공인 IP 또는 DNS를 만든다.
- 클라우드 환경에서는 AWS ELB, GCP Load Balancer 같은 리소스가 자동으로 생성된다.
- 트래픽 흐름은 Load Balancer → Node → Service → Pod 순서로 이해하면 된다.
- 실제 운영에서는 NodePort보다 LoadBalancer나 Ingress를 더 많이 사용한다.
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
Ingress
- Ingress는 HTTP/HTTPS 트래픽을 여러 Service로 라우팅하는 규칙이다.
- 도메인, 경로 기반 라우팅을 처리할 수 있다.
- 예를 들어
/api는 backend-service로,/admin은 admin-service로 보낼 수 있다. - Ingress 자체만 만든다고 동작하는 것은 아니고, Ingress Controller가 필요하다.
Ingress는 입구의 규칙이고, Ingress Controller는 그 규칙을 실제로 처리하는 실행자라고 보면 된다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
쿠버네티스 DNS
- 쿠버네티스 안에서는 Service 이름으로 통신할 수 있다.
- 같은 Namespace라면
service-name만 써도 된다. - 다른 Namespace라면
service-name.namespace-name형태로 접근한다. - 전체 주소는 보통
service-name.namespace-name.svc.cluster.local형태다.
예를 들어 backend라는 Service가 default Namespace에 있다면 아래처럼 호출할 수 있다.
curl http://backend.default.svc.cluster.local
CNI
- CNI는 Container Network Interface의 약자다.
- 쿠버네티스가 Pod 네트워크를 직접 구현하는 것이 아니라 CNI 플러그인을 통해 구현한다.
- 대표적으로 Calico, Cilium, Flannel 같은 플러그인이 있다.
- Pod IP 할당, Pod 간 통신, NetworkPolicy 적용 같은 부분이 CNI와 관련된다.
즉, 쿠버네티스 네트워크를 공부할 때는 Service만 보면 부족하고, 실제 클러스터에서 어떤 CNI를 쓰는지도 같이 봐야 한다.
NetworkPolicy
- 기본적으로 쿠버네티스 Pod는 서로 통신할 수 있다.
- NetworkPolicy는 Pod 간 통신을 제한하는 방화벽 규칙 같은 역할을 한다.
- 예를 들어 frontend Pod만 backend Pod에 접근하게 만들 수 있다.
- NetworkPolicy가 동작하려면 이를 지원하는 CNI 플러그인이 필요하다.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
spec:
podSelector:
matchLabels:
app: backend
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 80
전체 흐름 정리
쿠버네티스 네트워크는 처음 보면 용어가 많아서 복잡해 보인다. 그런데 흐름으로 보면 생각보다 단순하다.
- Pod가 생성되면 Pod IP를 받는다.
- 여러 Pod를 안정적으로 묶기 위해 Service를 만든다.
- 클러스터 내부에서는 ClusterIP로 접근한다.
- 외부에서 접근해야 하면 NodePort, LoadBalancer, Ingress를 사용한다.
- Service 이름 기반 통신은 Kubernetes DNS가 처리한다.
- Pod 네트워크의 실제 구현은 CNI가 담당한다.
- 통신을 제한해야 하면 NetworkPolicy를 사용한다.
마무리
쿠버네티스 네트워크는 Pod IP, Cluster IP, Service, Ingress를 따로 외우면 헷갈린다. 대신 트래픽이 어디서 시작해서 어디로 도착하는지 흐름으로 보면 이해가 쉽다.
가장 기본은 이거다. Pod는 바뀔 수 있고, Service는 고정 진입점이다. 그리고 외부 트래픽이 필요해지면 NodePort, LoadBalancer, Ingress 중 어떤 방식으로 열어줄지 결정하면 된다.
처음에는 ClusterIP와 Service 개념만 제대로 잡아도 충분하다. 그 다음 NodePort, LoadBalancer, Ingress 순서로 확장해서 보면 쿠버네티스 네트워크가 훨씬 덜 복잡하게 느껴진다.
'Kubernetes' 카테고리의 다른 글
| 쿠버네티스 환경에서의 부하분산(로드밸런싱) (0) | 2025.12.12 |
|---|---|
| 쿠버네티스 볼륨 (0) | 2025.12.10 |
| 쿠버네티스 아키텍처 (0) | 2025.12.09 |
| 쿠버네티스 명령어 정리 (kubectl) 및 yaml (0) | 2025.12.08 |
| 쿠버네티스 개념 및 용어 정리 (0) | 2025.12.08 |
