스터디/K8S 스터디

[k8s 스터디] #09 Service

박수빈98 2025. 5. 26. 17:13

k8s는 컨테이너 기반 구조이기 때문에 파드가 여러 노드에서 생성되고 삭제되며, 그에 따라 파드의 IP도 자주 변경된다.
이처럼 동적으로 변하는 IP를 일일이 추적해서 통신하는 것은 현실적으로 어렵기 때문에,

이를 해결하기 위한 중간 계층의 네트워크 접근 지점이 필요하다.


바로 그 역할을 하는 것이 k8s의 Service 리소스이다.

Service는 파드들의 고정된 접근 지점(가상 IP, DNS 이름)을 제공하고,
내부 로드밸런싱을 통해 파드 간 통신과 외부 노출까지 효과적으로 처리해준다.

이번 포스팅에서는 다음과 같은 질문을 통해 Service의 개념과 동작 원리를 실습을 기반으로 이해하고자 한다

  • 왜 Kubernetes에서는 Service 리소스가 꼭 필요한가?
  • Service는 어떤 방식으로 파드 집합을 식별하고 트래픽을 전달하는가?
  • ClusterIP, NodePort, LoadBalancer는 어떤 차이가 있는가?
  • Service는 내부에서 어떻게 호출되고, 외부에서는 어떤 방식으로 접근하는가?
  • 파드에서 ports 정의 없이도 targetPort로 트래픽을 수신할 수 있는 이유는 무엇인가?

Service

Pod 집합에 안정적인 네트워크 접근 지점을 제공하는 추상 리소스

  • DNS 이름 부여
  • 고정 IP 제공
    • 내부 클러스터 IP(ClusterIP) 할당
  • 부하 부산
    • 연결된 여러 Pod에 트래픽 분산 (Round Robin)
      • 내부의 파드끼리 통신하기 위한 것 외부에서는 이걸로 못들어옴
  • 외부 접근
    • 필요 시 외부에서 접근 가능(NodePort, LoadBalancer)
    • NodePort의 경우 외부에서 노드들의 퍼블릭 주소로만 요청하면 그걸 Kube-proxy가 알아서 서비스에 맞는 파드로 포워딩 해줌
    • LoadBalancer의 경우는 EKS 같이 클라우드 환경에서 사용하는 타입
### ▶ Service
apiVersion: v1  # Kubernetes core API 그룹의 버전 v1 사용
kind: Service  # 이 YAML은 Service 리소스를 정의함
metadata:
  namespace: anotherclass-123  # 이 서비스가 속한 네임스페이스
  name: api-tester-1231  # 서비스 이름 (DNS 이름 등으로 사용됨)
  labels:  # 서비스 리소스 자체에 대한 메타데이터
    part-of: k8s-anotherclass  # 프로젝트 그룹 라벨
    component: backend-server  # 백엔드 역할임을 나타냄
    name: api-tester  # 서비스 식별용 이름
    instance: api-tester-1231  # 서비스 인스턴스 구분값
    version: 1.0.0  # 버전 정보
    managed-by: dashboard  # 이 리소스가 생성된 관리 도구 (예: 웹 대시보드)
spec:
  selector:  # 이 서비스가 연결할 대상 Pod을 결정하는 라벨 셀렉터
    part-of: k8s-anotherclass  # 아래의 라벨과 일치하는 Pod을 선택함
    component: backend-server
    name: api-tester
    instance: api-tester-1231
  ports:
    - port: 80  # 클러스터 내부에서 이 서비스에 접근할 때 사용하는 포트 (가상포트)
      targetPort: http  # 실제 Pod 내부 컨테이너의 포트 이름 또는 번호 (예: containerPort: 8080)
      nodePort: 31231  # 클러스터 외부에서 접근 가능한 고정 포트 (Node의 물리 포트)
  type: NodePort  # 외부 사용자도 Node IP + nodePort 조합으로 접근 가능하게 함

 

nodePort 가 31231이니까

외부에선 A노드 ip 1.1.1.1 이라 하면 1.1.1.1:31231로 접근하면 Kube-Proxy가 서비스로 요청 프록시 해줌

만약 클라이언트가 클러스터 내부에 있다면 https://api-tester-1231:80로 접근 가능

실시간 확인 명령어

목적  명령어
서비스 목록 확인 kubectl get svc
서비스 상세 보기 kubectl describe svc <이름>
엔드포인트 보기 kubectl get endpoints <이름>
연결된 Pod 보기 kubectl get pods -l app=myapp

 

실습

서비스 확인

 

서비스 상세 보기

 

엔드포인트 보기

 

연결된 Pod 보기

 

 

▶ 1. Pod 내부에서 Service 명으로 API 호출

// Version API 호출
curl http://api-tester-1231:80/version

kubectl exec -n anotherclass-123 -it api-tester-1231-74465f56d6-dldd5 -- /bin/sh

파드 내부에서는 name으로 요청을 보낼 수 있음

 

▶ 2. Deployment에서 Pod의 ports 전체 삭제, Service targetPort를 http -> 8080으로 수정

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
spec:
  template:
    spec:
      nodeSelector:
        kubernetes.io/hostname: k8s-master
      containers:
        - name: api-tester-1231
          ports:                // 삭제
          - name: http          // 삭제
            containerPort: 8080 // 삭제
---
apiVersion: v1
kind: Service
metadata:
  namespace: anotherclass-123
  name: api-tester-1231
spec:
  ports:
    - port: 80
      targetPort: http -> 8080 // 변경
      nodePort: 31231
  type: NodePort

2. 그리고 다시 Pod 내부에서 Service 명으로 API 호출

curl http://api-tester-1231:80/version

이런 경우는 서비스가 http로 타켓 포트를 사용했음 Deployment의 name: http를 통해서

근데 이걸 지우면

디플로이먼트의 포트는 none이 됨 하지만 이렇다고 해서 8080 요청을 못받는게 아님

백엔드가 8080을 리슨하고 있으면 그게 받음

그래도 잘 동작함

 

 

마무리

질문에 대한 답

왜 Kubernetes에서는 Service 리소스가 꼭 필요한가?
파드는 재시작되거나 노드가 바뀌면 IP가 바뀌므로, 고정된 네트워크 접근 지점이 필요하기 때문이다.

Service는 어떤 방식으로 파드 집합을 식별하고 트래픽을 전달하는가?
Service는 selector로 라벨이 일치하는 파드들을 찾아 연결하고, 내부 로드밸런싱을 통해 트래픽을 분산시킨다.

ClusterIP, NodePort, LoadBalancer는 어떤 차이가 있는가?
ClusterIP는 내부 접근 전용, NodePort는 노드 IP + 포트로 외부 접근 가능, LoadBalancer는 클라우드에서 외부 LB를 생성해 직접 접근을 지원한다.

Service는 내부에서 어떻게 호출되고, 외부에서는 어떤 방식으로 접근하는가?
내부에서는 서비스 이름과 포트로 DNS처럼 호출하고, 외부에서는 Node IP와 nodePort 조합으로 접근한다.

파드에서 ports 정의 없이도 targetPort로 트래픽을 수신할 수 있는 이유는 무엇인가?
컨테이너가 실제 해당 포트를 리슨하고 있기만 하면, Service는 포트 이름 없이도 트래픽을 정상적으로 전달할 수 있기 때문이다.

 

Service 리소스가 파드의 IP 변경 문제를 해결하는 방식을 알게 되었다.

쿠버네티스는 컨테이너 방식의 장점은 장점대로 활용하고,

단점은 보완하며 정말 편리하게 만들어 진 것 같다고 느꼈다.