[Kubernetes] Service 오브젝트란?

Dev StoryTeller·2025년 1월 14일

인프라 알아보기

목록 보기
7/12

해당 글은 쿠버네티스 교과서 책과 공식 홈페이지(https://kubernetes.io/ko/)를 참조하여 작성되었습니다

배경?

Service는 Deployment 오브젝트로 동일 파드가 여러개 있을 경우, 이를 어떻게 통신하느냐의 문제를 해결해준다
파드와 연결하려면 단순히 IP를 통해 통신하면 된다
하지만 파드는 쉽게 삭제/생성될 수 있는 것이 특징이다
만약 파드 A와 IP로 통신중이었는데, A가 삭제되고 A'이 재생성되면 어떻게 통신할까?
다시 A'의 IP를 찾아 통신을 해야할 것이다
매번 이런 작업을 하기란 불가능에 가깝다. 그렇다면 이런 복제된 파드들을 쉽게 관리할 방법은 없을까?


서비스 오브젝트 란?

그렇게 나온 것이 바로 서비스 오브젝트이다
원하는 파드 집합이 퍼블릭 인터넷 / 클러스터 내부에서 통신할 수 있도록 중간다리 역할을 해준다
간단히 말해 네트워크 통신 역할을 담당한다!라고 보면 되겠다

서비스가 생성되면 통신을 위한 고정 IP 또는 내부에서 사용할 수 있 도메인 네임이 주어지며, 이를 통해 통신이 가능하다


동작 방식!

서비스의 동작 방식은 간단하다. 해당 오브젝트로 요청을 보내면 관리하고 있는 오브젝트 집합에 요청을 적절히 전달한다
그렇다면 관리하는 파드 집합은 어떻게 정할 수 있을까?
이것을 관리하는 것이 바로 Endpoint 이다


Endpoint 란

Endpoint란 네트워크 엔드포인트 서비스 목록을 정의하며, 일반적으로 트래픽이 어떤 파드에 보내질 수 있는지를 나타낸다
요청이 들어온다면 Service는 요청을 대표로 받는 입구 역할을 하고, 실제로 적절히 분산하는 역할은 Endpoint가 담당한다
이를 그림으로 그려보자면 다음과 같다
[그림]

위처럼 Endpoint는 관리할 파드들의 주소를 가지고 있고, Service로부터 요청이 들어오면 적절한 파드에 전달한다

이처럼 서비스가 온전히 동작하기 위해서는 ServiceEndpoint 오브젝트가 생성되어야 한다
이때 작성 방법은 Selector 지정, Endpoint 직접 지정으로 나뉜다


Selector 지정

각 파드들에 부여한 레이블을 가지고 골라내는 방법이다
파드와 같이 유동적인 IP를 가지는 오브젝트들은 Endpoint로 직접 관리하기 어렵기에, 레이블에 해당하는 오브젝트를 서비스가 알아서 생성하도록 한다

spec:
  selector:
    app: service-1

위처럼 작성하면 app: service-1 레이블을 가진 파드들을 모아 Endpoint 오브젝트를 자동으로 생성하며,
해당 파드들이 IP가 삭제 및 변경될 시에 Endpoint의 관리 목록도 같이 변경된다


Endpoint 직접 지정?

물론 Selector를 사용한다면 자동으로 Endpoint 오브젝트가 관리되지만, 그 방법은 파드를 대상으로 한다. 때문에,

  • 파드가 아닌 다른 클러스터/네임스페이스의 Service에 연결하고 싶은 경우
  • 외부에 트래픽을 전달하고 싶은 경우

위처럼 다른 오브젝트를 관리해야 하고 싶다면 직접 Endpoint를 작성하면 된다
다만 Service에 의해 자동으로 생성되고 관리되지 않으므로, IP가 유동적이지 않은 오브젝트에 사용해야 한다

apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
  name: numbers-api-1
  labels:
    # "kubernetes.io/service-name" 레이블을 서비스의 이름과 동일하게 설정해야 한다
    # 그래야 서비스와 연결되어 작동한다
    kubernetes.io/service-name: numbers-api
addressType: IPv4
ports:
  - name: ''
    appProtocol: http
    protocol: TCP
    port: 80
endpoints:
  # 해당하는 파드들의 주소를 적어준다
  - addresses:
      - "10.42.0.85"

서비스 검색?

이제 서비스 오브젝트가 내부적으로 어떻게 동작하는지 알아보았다
그러나 서비스도 결국 오브젝트! 라우팅을 하든 뭘 하든 결국 통신을 위해서는 서비스를 찾아야 한다
이를 서비스 검색(Discovery)이라고 하며, 검색의 방법은 환경 변수를 통한 방법, 도메인 이름을 통한 방법 2가지가 있다


환경변수를 통한 검색

이미 활성화되어 있는 서비스에 파드가 생성되면 해당 파드 내에 자동으로 환경변수가 추가되는데,
바로 이 환경변수를 통해 서비스를 찾을 수 있다
이때 key 값은 {서비스 이름}_SERVICE_HOST, {서비스 이름}_SERVICE_PORT 등 _ 스타일로 추가된다

예를 들어 numbers-api 서비스에 파드가 추가된다고 했을 때, 해당 파드에는 다음의 환경변수가 추가된다

NUMBERS_API_SERVICE_HOST=10.43.9.240
NUMBERS_API_SERVICE_PORT=80
NUMBERS_API_PORT=tcp://10.43.9.240:80
NUMBERS_API_PORT_80_TCP_ADDR=10.43.9.240
NUMBERS_API_PORT_80_TCP_PORT=80
NUMBERS_API_PORT_80_TCP_PROTO=tcp
NUMBERS_API_PORT_80_TCP=tcp://10.43.9.240:80

주의점!!
다만 환경변수로 검색 시에, 파드를 먼저 생성하고 서비스를 나중에 추가하면 파드에는 아무것도 추가되지 않는다
이유는 파드가 생성될 때 자신이 속한 활성 서비스를 보고 변수가 추가되는데, 순서가 반대가 되면 없는 것으로 판단하기 때문!
반드시 서비스 미리 생성 -> 파드 생성 순으로 진행하자!!


도메인 이름을 통한 검색

쿠버네티에는 DNS 역할을 하는 CoreDNS라는 서버가 존재한다
해당 DNS 서버는 서비스에 대해 DNS 레코드 세트를 생성하는데, 예를 들어 my-ns 네임스페이스에 numbers-api라는 서비스가 생기면
컨트 플레인과 CoreDNS가 이를 조합하여 해당 서비스에 numbers-api.my-ns라는 DNS 레코드 쌍을 만든다
이를 통해 서비스를 찾을 수 있다

같은 네임스페이스에 속한다면 numbers-api라는 이름으로 검색할 수 있고,
만약 다른 NS라면 numbers-api.my-ns와 같이 네임스페이스까지 붙여줘야 한다


이번 편에서는 Service 오브젝트에 대해 알아보았다
아직 DNS가 정확히 어떻게 진행되는지에 대한 궁금증이 남아있지만, 우선 기본적인 오브젝트부터 알고 나가야한다
다음으로는 ConfigMapSecret에 대해 알아보도록 하자

profile
개발을 이야기하는 개발자입니다

0개의 댓글