개발 환경 및 운영/Kubernetes

Kubernetes의 서비스(Service)

haong_ 2025. 1. 1. 20:14

2024.12.23 - [개발 환경 및 운영/Kubernetes] - Kubernetes의 구성요소 알아보기 (Pod, ReplicaSet, Deployment)

지난 시간에는 Kubernetes의 workload인 Pod, ReplicaSet, Deployment에 대해 알아보았다. 이번 시간에는 Kubernetes에서 네트워크를 관리하는 핵심 리소스인 Service에 대해 알아보자.


Service

Pod와 네트워크를 연결하는 Kubernetes 리소스

Pod은 쿠버네티스 클러스터 내부에서만 접근이 가능하며, 동적으로 생성되고 삭제되기 때문에 Pod의 IP 주소는 자주 바뀔 수 있다. 또한 deployment 내의 여러 Pod을 하나의 애플리케이션처럼 접근하고 구동하려면 다른 방법이 필요하다. 이때 Service라고 부르는 오브젝트를 통해 Pod과 클라이언트를 연결하는 고정된 네트워크 엔드포인트를 얻을 수 있다.

주요 역할

  1. 고정 IP 제공: Pod의 IP 주소가 바뀌더라도 클라이언트는 항상 Service의 IP를 통해 접근 가능.
  2. 로드 밸런싱: 여러 Pod에 접근할때 트래픽을 고르게 분산.
  3. 서비스 디스커버리: Pod에 쉽게 접근할 수 있도록 고유한 DNS 부여.

Pod에 어떻게 접근할 것인가에 따라 서비스는 종류가 여러개로 세분화 되어있어, 목적에 맞는 적절한 서비스 종류를 선택해야 한다.

Service의 종류

ClusterIP (기본값)

  • Kubernetes 클러스터 내부에서만 접근 가능.
  • 외부에서 접근할 필요가 없는 내부 서비스에 적합.
apiVersion: v1
kind: Service
metadata:
  name: my-clusterip-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80
  type: ClusterIP
  • spec.selector: 서비스에서 어떤 라벨을 가지는 pod의 집합에 접근할 수 있게 만들지 결정하는 부분. 예시의 app: my-app는 deployment.yaml 에서 labels 하위에 app: my-app 라고 그룹을 만들어줬다면 해당 그룹의 pod들에 접근가능해지는 것.
  • spec.ports.port: Service에 접근할 때 사용할 포트.
  • spec.ports.targetPort: 접근대상이 될 Pod들이 내부적으로 사용하고 있는 포트. 즉 pod 템플릿에 정의된 containerPort 값과 같은 값으로 설정.

ClusterIP 타입 서비스의 트래픽 흐름

NodePort

  • 클러스터 외부에서 노드의 IP와 특정 포트를 통해 접근 가능한 서비스 유형으로, 클러스터의 모든 노드가 같은 포트를 열어 외부에 노출.
  • nodeport의 범위는 30000~32767. 자동 할당이나 명시적 설정 가능.
  • 포트를 직접 노출하기 때문에 보안 설정이 필요함.
apiVersion: v1
kind: Service
metadata:
  name: my-nodeport-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 8080
    targetPort: 80
    nodePort: 30007 # 외부에서 접근 가능한 포트
  type: NodePort

예시에서 NodePort를 30007로 설정했기 때문에 클러스터의 모든 노드에서 30007번 포트가 열림. 클러스터의 아무 노드에 30007 포트로 접근하면 동일한 서비스에 연결된다.

<http://<노드의> IP>:<NodePort>

  • 노드 1 : 192.168.1.10
  • 노드 2 : 192.168.1.11

http://192.168.1.10:30007 or http://192.168.1.11:30007 둘다 동일 서비스에 접근

NodePort 타입 서비스의 트래픽 흐름

실제 운영환경에서는 SSL 인증서, 라우딩 같은 복잡한 설정을 서비스에 적용하기 어렵기 때문에 NodePort로 외부에 서비스를 제공하는 경우는 많지 않음.

LoadBalancer

  • 클라우드 플랫폼의 로드 밸런서를 활용하여 외부에서 pod에 접근.
  • 로드밸런서를 동적으로 생성하는 기능을 제공하는 환경에서만 사용할 수 있어 일반적으로 AWS, GCP 같은 클라우드 환경에서 사용.
  • NodePort 타입은 각 노드의 IP를 알아야했지만, 로드밸런서 타입은 클라우드 플랫폼으로부터 도메인 이름과 IP를 할당받기 때문에 더욱 쉽게 pod에 접근이 가능함. 즉 로드밸런서로 노드를 한번 더 감싸서 pod에만 트래픽을 분산하는게 아니라 노드에도 트래픽을 분산하는 것.
apiVersion: v1
kind: Service
metadata:
  name: my-loadbalancer-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer
  • spec.ports.port: 로드밸런서 타입에서는 이 포트는 로드밸런서에 접근하기 위한 포트가 됨.

LoadBalancer 타입 서비스의 트래픽 흐름

ExternalName

  • 클러스터 내부에서 외부의 DNS 이름을 직접 참조할수 있도록 해주는 서비스 유형.
  • 외부 리소스(API, 데이터베이스 등)를 클러스터 내부에서 사용하려 할 때 유용함.
apiVersion: v1
kind: Service
metadata:
  name: my-database 
spec:
  type: ExternalName
  externalName: database.example.com
  • 클러스터 내부에서 my-database 이름으로 요청을 보내면 database.example.com 으로 접근할 수 있도록 CNAME 레코드 반환.

CNAME은 DNS 레코드 유형 중 하나.

CNAME 레코드

- Canonical Name의 줄임말로, 하나의 도메인 이름을 다른 도메인 이름으로 매핑.
- CNAME 레코드는 IP 주소로 직접 변환하지 않고, 지정된 다른 도메인 이름(A 레코드가 있는 도메인)으로 리다이렉트

my-database → database.example.com → 192.168.1.100

A 레코드
- Address의 줄임말로 도메인 이름을 직접 IP주소로 매핑.

database.example.com → 192.168.1.100

 


이상으로 서비스의 종류 4가지를 보았는데, 다음으로 서비스 속성 중 하나인 externalTrafficPolicy에 대해 보자.

externalTrafficPolicy

트래픽의 분배를 결정하는 속성
  • 외부에서 들어오는 트래픽이 클러스터 내부로 전달될 때, 해당 트래픽을 어떻게 처리할지 결정
  • 외부 클라이언트 요청을 처리할 때 트래픽 라우팅 방식을 설정하는 옵션으로 NodePort, LoadBalancer 서비스 타입에만 적용

사용 가능한 값

  • Cluster(기본 값)
    • 외부에서 들어온 트래픽을 클러스터 전체로 분산하여, 클러스터의 모든 노드에서 pod으로 트래픽 전달 가능.
    • 노드 간의 요청이 리다이렉트 되어 SNAT이 발생하여 클라이언트의 IP가 변경됨 > 요청이 노드의 IP로 변경되므로 pod에서 클라이언트 실제 IP를 기반으로한 로깅, 분석 등이 어려움
  • Local
    • 외부 트래픽은 요청을 받은 노드 내의 pod으로만 분산.
    • 네트워크 hop이 한단계 적고 SNAT도 발생하지 않지만 노드 간의 pod 개수가 불균형 할때 트래픽 분배가 고르게 되지 않을 수 있음.

externalTrafficPolicy의 값에 따른 트래픽 흐름

로깅 및 방화벽 설정이 필요한 경우에는 Local, 높은 가용성이 필요한 경우 Cluster 사용. (이후에 ingress 부분에서 Pod Affinity & AntiAffinity 에서 노드 배치를 통한 리소스 분산에 대한 내용 이어져서 나올 예정)

정리

Service는 Pod를 외부와 연결하고 로드 밸런싱을 제공하는 Kubernetes 네트워크 연결의 기본 단위다. 다음 시간에는 서비스와 같은 네트워크 리소스인 인그레스(ingress)에 대한 내용으로 돌아오겠다.