Service
애플리케이션 간 통신을 가능하게 하는 추상화된 네트워크 리소스로, Pod의 네트워크 주소를 추상화하여 안정적인 연결을 제공
Service의 필요성
- 변경되는 Pod의 IP 주소: Pod은 생성, 삭제, 교체가 반복되며, IP 주소가 동적으로 변경되는데, 애플리케이션 간 통신에서 변경된 IP 주소를 추적하는 것은 어려움
- Service를 통한 안정적 연결: Service는 고정된 가상 IP(ClusterIP)를 제공하여, Pod의 실제 IP 변경과 무관하게 애플리케이션이 안정적으로 통신할 수 있도록 함
주요 특징
- 고유한 IP 주소: Service는 자신만의 IP 주소를 가지며, Service가 삭제될 때까지 바뀌지 않음
- 서비스 디스커버리 기능: Service 생성시 IP 주소가 클러스터 내 DNS 서버에 등록되며, 다른 Pod은 DNS 이름으로 Service를 찾을 수 있음
- 레이블 셀렉터: Service는 레이블 셀렉터를 사용하여 특정 레이블을 가진 Pod을 선택
- Pod로 요청 전달: 컨슈머 컴포넌트가 Service IP 주소로 요청을 보내면, 연결된 Pod의 실제 IP 주소로 요청을 전달
- Endpoint 관리: Service는 자동으로 Endpoints 리소스를 생성해, 선택된 Pod의 IP와 포트 정보를 관리
- 로드 밸런싱: Service는 연결된 여러 Pod에 요청을 라운드 로빈 방식으로 분산
Service(NodePort) 동작 방식

Service 유형
ClusterIP
기본적인 Service 유형으로, 클러스터 내부에서만 접근 가능한 가상 IP를 제공
- <ClusterIP>:<Port>로 들어온 트래픽을 <PodIP>:<targetPort>로 전달
ClusterIP 매니페스트
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 8080
- selector: Service와 연결할 대상인 Pod의 라벨을 지정
- port: 클러스터 내부에서 사용할 포트
- targetPort: 해당 서비스로 들어오는 트래픽 처리할 Pod의 포트
NodePort
모든 노드의 특정 포트를 열어, 외부에서 특정 노드의 포트를 통해 Pod에 접근을 가능하도록 하는 Service 유형
- NodePort로 Service를 생성하면 ClusterIP도 자동으로 생성됨
- <NodeIP>:<NodePort> → <ClusterIP>:<Port> → <PodIP>:<targetPort> 순으로 외부 트래픽이 전달됨
NodePort 매니페스트
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- nodePort: 30007
port: 80
targetPort: 8080
- nodePort: 외부 트래픽을 받는 노드의 포트
- port: 클러스터 내부에서 사용할 포트
- targetPort: 해당 서비스로 들어오는 트래픽 처리할 Pod의 포트
LoadBalancer
클라우드 환경에서 외부 LoadBalancer를 통해, Pod에 접근을 가능하도록 하는 Service 유형
- Service를 LoadBalancer로 노출함
- <LoadBalancerIP>:<LoadBalancerPort> → <ClusterIP>:<Port> → <PodIP>:<targetPort>순으로 외부 트래픽이 전달됨
LoadBalancer 매니페스트
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
spec:
type: LoadBalancer
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
- port: 클러스터 내부에서 사용할 포트
- targetPort: 해당 서비스로 들어오는 트래픽 처리할 Pod의 포트
ExternalName
Pod가 클러스터 내부에서 외부 DNS 이름에 접근할 수 있도록하는 Service 유형
- 클러스터 외부의 DNS 이름을 Service의 이름으로 접근할 수 있음
- externalName 필드의 값을 사용하여 DNS CNAME 레코드를 생성
ExternalName 매니페스트
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
type: ExternalName
externalName: example.com
- externalName: 외부 서비스의 DNS 이름
Service 생성하기
nginx-deployment에 의해 생성된 Pod들 목록
$ kubectl get pod -o wide

nginx-deployment에 의해 생성된 Pod들을 Service에 연결하기
- --port: Service에서 노출할 포트
- 기본적으로 ClusterIP로 Service가 생성됨
$ kubectl expose deployment nginx-deployment --port=80
$ kubectl get svc nginx-deployment

Service는 endpoints를 자동으로 생성함
$ kubectl get endpoints nginx-deployment

Service의 IP의 대역과 Endpoints의 대역은 서로 다른 대역
- Port는 Service에서 노출하는 포트이고, TargetPort는 Pod에서 노출하는 포트
$ kubectl describe svc nginx-deployment

다른 Pod에서 Service에 요청 보내기 위해 tester.yaml 생성
apiVersion: v1
kind: Pod
metadata:
name: tester
spec:
restartPolicy: Never
containers:
- name: test-client
image: curlimages/curl:8.11.1
command: [ "sleep" ]
args: [ "2073600" ]
tester Pod 생성하고, 접속하기
$ kubectl apply -f tester.yaml
$ kubectl exec -it tester -- /bin/sh
Service의 DNS 이름으로 다음과 같이 요청을 보내면, 정상적으로 응답을 받음
$ curl http://nginx-deployment.default.svc.cluster.local

참고:
https://stackoverflow.com/questions/52857825/what-is-an-endpoint-in-kubernetes
'DevOps > Kubernetes' 카테고리의 다른 글
[k8s] Volume (0) | 2025.02.18 |
---|---|
[k8s] ConfigMap & Secret (0) | 2025.01.09 |
[k8s] Deployment (0) | 2025.01.09 |
[k8s] Pod (0) | 2025.01.09 |
[k8s] minikube 설치 & kubectl 사용하기 (1) | 2025.01.09 |