쿠버네티스의 서비스 컴포넌트 살펴보기

Chanmin, Kim·2022년 4월 23일
0

Kubernetes

목록 보기
3/3
post-thumbnail

파드의 임시 IP(Ephemeral IP)로 인한 불편함

쿠버네티스에서 파드와 네트워크를 연결하려면 어떻게 해야 할까요?

파드의 IP주소를 확인한 후 사용할 수도 있지만, 파드는 재실행될 때마다 새로운 임시 IP(ephemeral IP)를 무작위로 부여받는다는 특징이 있습니다.

하지만 서비스를 운영하는 중 파드는 리소스 부족 등의 이유로 인해 제거되었다가 재생성되는 과정을 계속해서 반복하는데요, 파드가 재생성될 때마다 매번 달라지는 임시 IP를 사용하는 것은 굉장히 비효율적인 작업이 될 수 있습니다.

서비스의 역할

이처럼 파드의 임시 IP 대신 정적으로 변화하지 않는 고정된 IP를 제공해주는 것이 바로 서비스 로, 서비스는 파드로 보내지는 요청을 앞단에서 관리할 수 있는 역할을 합니다.

서비스의 유형은 다음과 같이 분류됩니다.

  • ClusterIP
  • NodeIP
  • LoadBalancer

ClusterIP 타입 서비스의 트래픽 전달 과정

ClusterIP는 가장 기본적인 서비스 유형입니다.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP

ClusterIP는 앞단에 인그레스(Ingress)를 둘 수 있으며, 클러스터 안에서만 사용할 수 있는 IP를 부여합니다.

1단계 : Ingress → Service

제일 먼저 유저로부터 요청(트래픽)이 들어오면, 인그레스(Ingress)가 제일 먼저 트래픽을 받아 서비스에 전달합니다.

인그레스는 L7 계층에서 로드밸런싱 및 다양한 기능을 제공하는 쿠버네티스 컴포넌트로, 자세한 내용은 별도의 글에서 다룹니다.

유저가 전송한 트래픽을 인그레스에서 서비스로 전달하면, 서비스는 해당 트래픽을 조건에 맞는 파드로 라우트합니다.

  • 인그레스와 서비스를 연결하는 템플릿 예시
# ingress.yaml
...
spec:
  ...
  backend:
    serviceName: microservice-service-1
    # 트래픽을 전달할 서비스의 포트
    servicePort: 3001
#Service.yaml

apiVersion: v1
kind: Service
metadata:
  name: microservice-service-1
spec:
  selector:
    app: microservice-1
  ports:
    - protocol: TCP
      # 서비스가 트래픽을 받도록 공개할 포트
      port: 3001
      # 서비스가 트래픽을 전달할 대상(Ex. 파드)의 포트
      targetPort: 3000 

2단계 : Service → Pod

이제 인그레스에서 트래픽을 넘겨받았으니 이를 파드에 전달해줄 차례인데요, 아래와 같은 아키텍처를 구현하기 위해 서비스와 파드는 어떻게 연결할 수 있을까요?

이 때는 라벨과 셀렉터를 사용합니다.

파드에서는 라벨을 통해 다른 컴포넌트가 해당 파드를 지정할 수 있도록 알릴 수 있고, 서비스에서는 셀렉터를 통해 트래픽을 전달할 파드를 선택할 수 있습니다.

단 동일한 라벨을 갖는 모든 레플리카들에 트래픽을 전달하는 것이 아닌, kube-proxy 에 의해 트래픽을 균등하게 파드에 배분합니다.

이제 파드까지 트래픽이 도달했는데요, spec.ports.targetPort 속성을 통해 트래픽을 전달할 (컨테이너의) 포트를 지정할 수 있습니다.

  • 라벨을 지정한 파드를 셀렉터로 지정하는 서비스 템플릿
# deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: microservice-one
spec:
  replicas: 2
  ...
  template:
    metadata:
      # 생성되는 파드들에 app: microservice-1 라는 라벨을 부여합니다.
      labels:
        app: microservice-1
# service.yaml

apiVersion: v1
kind: Service
metadata:
  name: microservice-service-1
spec:
  selector:
    # 트래픽을 app: microservice-1 라벨을 갖는 파드로 전달합니다.
    # 서비스의 3001번 포트로 들어오는 트래픽은 파드의 3000번 포트로 전달됩니다.
    app: microservice-1
  ports:
    - protocol: TCP
      port: 3001
      targetPort: 3000 

3단계 : 둘 이상의 컨테이너를 갖는 파드

지금까지의 과정을 통해 인그레스 - 서비스 - 파드를 거쳐 하나의 컨테이너에 트래픽을 전달할 수 있게 되었습니다.

이제 만약 둘 이상의 컨테이너를 갖는 파드에 각각 트래픽을 보내고 싶다면, 서비스의 spec.ports 속성에 서비스 포트와 targetPort 를 추가해주기만 하면 됩니다.

  • 둘 이상의 컨테이너를 갖는 파드에 포워딩을 수행하는 서비스 템플릿
# service.yaml

apiVersion: v1
kind: Service
metadata:
  name: microservice-service-1
spec:
  selector:
    # 트래픽을 app: microservice-1 라벨을 갖는 파드로 전달합니다.
    app: microservice-1
  ports:
      # 서비스의 3301번 포트로 들어온 트래픽은 파드의 3000번 포트로 전달됩니다.
    - protocol: TCP
      port: 3001
      targetPort: 3000 
      # 서비스의 5501번 포트로 들어온 트래픽은 파드의 5500번 포트로 전달됩니다.
    - protocol: TCP
      port: 5501
      targetPort: 5500       

NodePort 서비스 타입의 트래픽 전달 과정

NodePort 서비스 타입은 외부에서 각 워커 노드에 직접 접근할 수 있도록 포트를 공개하는 방식으로, 보안이 취약하다는 단점이 있어 주로 임시 개발용이나 데모용으로 사용됩니다.

nodePort30000 ~ 32767 사이의 값만을 가질 수 있으며, 노드로 보내진 트래픽은 spec.ports.targetPort 에 명시된 포트로 전달됩니다.

apiVersion: v1
kind: Service
metadata:
  name: my-nodeport-service
spec:
  type: NodePort
  selector:
    app: microservice-1
  ports:
    - name: container-1
      port: 3001
      nodePort: 30000
      targetPort: 3000
    - name: container-2
      port: 5501
      nodePort: 30001
      targetPort: 5501

이 때 spec.ports.portspec.ports.targetPort 는 여전히 ClusterIP 기반으로 생성됩니다.

LoadBalancer 타입 서비스의 트래픽 전달 과정

LoadBalancer 타입 서비스는 NodePort와 유사한 구조를 갖지만, 외부에서 퍼블릭으로 노드에 접근할 수 있는 것이 아닌 클라우드 기반의 로드밸런서만이 클러스터 내 노드에 접근할 수 있도록 합니다.

apiVersion: v1
kind: service
metadata:
  name: my-nodeport-service
spec:
  type: LoadBalancer
  selector:
    app: microservice-1
  ports:
    - name: container-1
      port: 3001
      nodePort: 30000
      targetPort: 3000
    - name: container-2
      port: 5501
      nodePort: 30001
      targetPort: 5501
profile
Public Cloud 및 Cloud Native 기술에 관심이 많습니다.

0개의 댓글