본문 바로가기

Container/Kubernetes

[k8s]서비스 디스커버리

쿠버네티스의 목적

쿠버네티스는 컨테이너화 된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장 가능한 오픈소스 플랫폼이다. 즉 대량의 컨테이너를 쉽게 관리하기 위한 도구이다. 이 쿠버네티스의 파드는 컨테이너를 실행하는 가장 작은 작업단위이다. 파드에 직접 접근하지 않도록 파드는 노드와 클러스터로 감싸져있다. 이는 서비스 간의 강한 의존성을 제거하기 위한 Decoupling과정으로, 이것의 장점은 앞서 배운 MSA와 비슷하다.

서비스

  • 파드를 네트워크 상에 노출시킬 수 있게 만드는 리소스
  • 파드 접근 정책을 정의하는 추상적 개념
    • spec.selector가 결정한다.

서비스 디스커버리

마이크로서비스 사이에서 서로가 서로를 호출하는 방법(IPC: Inter-Process Communication)이다. 동기 비동기에 따라 IPC는 두 가지로 분류된다. 동기적인 방법으로 REST API가 있고, 비동기적인 방법으로 메시지 큐가 있다.

쿠버네티스 서비스, 특히 파드는 일시적(ephmeral)인 성질을 가지고 수평 확장(scale out)된다. 서비스를 만들어보면, 파드든 노드든 각각 개별의 Cluster IP가 존재한다. 서비스는 각 개체들과 통신하기 위해 어떻게 IP를 알고 호출할까?

이를 가능하게 하는 것이 서비스 디스커버리이다. 좋은 서비스 디스커버리는 고가용성을 보장하고 부하 분산을 할 수 있는 것이다. 서비스 디스커버리 메커니즘을 사용하는 방법은 많다. DNS 이름에 여러 IP를 할당함으로써 한 DNS에 접속했을 때 특정 IP를 찾도록 한다. AWS의 ECS가 Fargate를 통해 부하를 분산해주는 것, 그리고 대표적으로 로드밸런서가 있다. 이러한 서비스 디스커버리 메커니즘은 쿠버네티스에 kube-proxy와 selector를 통해 이루어진다.

파드를 노출할 3가지 서비스를 정리해보겠다.

ClusterIP

default 값으로 cluster 생성시 함께 만들어진다. 내부의 통신을 위한 IP로 사설 IP대역을 사용한다. ClusterIP가 할당되었다는 말은, kube-proxy 해당 서비스를 처리하며, 플랫폼에 의해 로드밸런싱도 하겠다는 소리이다. 다른 말로, spec.clusterIP: None으로 처리하면, 쿠버네티스의 서비스 디스커버리 메커니즘을 사용하지 않고 독립적으로 서비스를 구성하겠다는 소리이다. 이를 헤드리스 서비스(Headless)라 한다.

NodePort

클러스터의 특정 노드를 외부로 노출시켜 파드와 통신할 수 있도록 하는 방법이다.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: cozserver
  ports:
      # 기본적으로 그리고 편의상 `targetPort` 는 `port` 필드와 동일한 값으로 설정된다.
    - port: 8080
      targetPort: 8080
      # 선택적 필드
      # 기본적으로 그리고 편의상 쿠버네티스 컨트롤 플레인은 포트 범위에서 할당한다(기본값: 30000-32767)
      nodePort: 30007

위와 같이 작성할 수 있다. 통신은 localhost -> node -> service -> pod 순으로 진행된다. 포트번호가 헷갈릴 수 있는데, 통신 과정을 생각해보면서 하나하나 생각해보면 쉽다.

  • port: 8080 서비스의 포트번호
  • targetPort: 8080 파드에 노출된 컨테이너의 포트번호
  • nodePort: 30007 노드 포트번호 (default값: 30000-32767)

LoadBalancer

부하 분산을 하는 로드밸런서의 기본적인 형태는 다음과 같다.

apiVersion: v1
kind: Service
metadata:
  name: cozserver-service
  namespace: default
spec:
  selector:
    app: cozserver # 배포하려는 파드를 지정합니다. 당연히 파드가 이미 실행중이어야 합니다.
  type: LoadBalancer
  ports:
  - name: cozserver
    protocol: TCP
    port: 7080
    targetPort: 8080

External IP와 포트번호를 조합하여 접속을 시도하면, 로드밸런서가 알아서 가장 헬시하고 빠른 곳을 찾아 연결해준다.

 

위 세가지의 특징을 간단히 그리면 다음과 같다.

 

'Container > Kubernetes' 카테고리의 다른 글

[k8s]readiness probe로 파드 health check 하기!  (0) 2022.04.26
[k8s]스테이트풀 셋  (0) 2022.04.26
[k8s]쿠버네티스 개념  (0) 2022.04.21