[kubernetes] 애플리케이션 노출법 Ⅱ (NodePort, LoadBalancer)

vinca·2023년 11월 24일
0

☸️ kubernetes

목록 보기
15/35

노드 포트(NodePort)

노드 포트란 애플리케이션을 외부로 노출하기 위한 kind : Servicetype : NodePort를 통해서 지정하게 된다.

노드 포트는 VM의 노드 포트(nodePort)를 통과해 서비스(port)에서 선택되는 파드의 내부 애플리케이션(targetPort)까지 트래픽을 전달하는 유형의 서비스다.

노드 포트를 통해 클러스터 내부로 들어온 트래픽을 내부의 특정 파드로 연결하기 위한 ClusterIP 역시 자동으로 생성된다.

용어 정리

  • nodePort: 외부에서 노드포트로 노출된 애플리케이션에 접속하기 위해 가장 먼저 통과되는 포트
  • port : nodePort를 통해서 들어온 트래픽이 서비스로 들어오기 위한 포트 (서비스를 노출하는 포트)
  • targetPort : 파드에서 애플리케이션으로 들어가기 위한 포트

NodePort 접속 흐름

  1. 사용자가 보낸 트래픽은 <접속할 노드 IP>:<nodePort>를 통해 해당 노드(VM)를 통과한다.

    🎈[TIP]
    이 때 <접속할 노드 IP>를 사용자가 직접 지정해야 한다.
    이를 직접 지정하지 않고, 자동으로 지정하는 방법이 바로 로드밸런서이다.

  2. port를 통해서 클러스터 내부의 서비스에 도착한다.
  3. 서비스에서 라운드 로빈과 같은 트래픽 분산 방법에 의해 트래픽을 보낼 파드를 결정하고, 이를 <해당 파드의 IP>:<targetPort>로 전달한다.

NodePort 실습

노드 포트를 배포하기 위해서 다음과 같이 yaml파일을 설정해 주도록 하자.

노드포트에서 관리하게 될 파드의 레이블을 NodePort쪽의 selector에 app : deploy-nginx 로 동일하게 작성해주면 해당 Deployment로 배포된 파드들은 NodePort를 통해서 외부에서 접근할 수 있게 된다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  labels:
    app: deploy-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: deploy-nginx
  template:
    metadata:
      labels:
        app: deploy-nginx
    spec:
      containers:
      - name: nginx
        image: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: np-nginx
spec:
  selector:
    app: deploy-nginx
  ports:
    - name: http
      port: 80
      targetPort: 80
      nodePort: 30000 #option
  type: NodePort

이를 통해 모든 노드가 노드 포트 30000번으로 노출 되었으므로, 각 노드의 INTERNAL-IP : 30000을 통해서 접속해보자.

여기서 주의할 점은, 노드 포트 서비스로 노출했다고 해서 노드 포트의 내부 아이피CLUSTER-IP를 사용해서 접근하는 것이 아니다.

노드에 대해서 접속을 열어준 "노드 포트" 이므로 노드의 INTERNAL-IP로 접근해야 한다.

노드 포트는 클러스터 내의 모든 노드에 대해서 지정된 포트 30000번을 열어주게 되므로, 워커노드는 물론이고, 마스터 노드의 주소인 192.168.1.10:30000을 사용해서 접속해도 접속이 가능하다.


로드밸런서 (LoadBalancer)

로드 밸런서란 노드들의 앞에 하나의 스위치 역할을 하는 문을 추가하여 기존 사용자가 노드 포트에서 직접 어떤 노드IP로 접속할지를 지정했던 것을 대신 해준다.

기존 <접속할 노드 IP>:<nodePort> 에서 접속할 노드 IP를 로드밸런서를 통해서 자동으로 지정해주는 것이다.

로드 밸런서의 사용을 통해 서비스의 가용성을 높이고, 특정 노드에 과부하가 발생하는 것을 방지할 수 있다.

LoadBalancer 접속 흐름

  1. 사용자는 로드 밸런서의 IP 주소나 도메인 이름을 사용하여 서비스에 접근.
  2. 로드밸런서는 내부적으로 라운드 로빈과 같은 트래픽 분산 방법을 통해 접속할 노드를 정하고, 노드 포트로 접속
  3. 노드 포트를 통해 VM를 통과한 트래픽은 port를 통해서 Service로 전달.
  4. 서비스에서 <해당 파드의 IP>:<targetPort>를 통해서 Pod의 애플리케이션으로 접속

LoadBalancer 실습

코드 및 구성

이번에는 2개의 로드밸런서를 만들어보도록 하자.
하나는 IP를 체크하는 용도, 하나는 nginx에 접속하는 용도로 사용된다.

이를 그림으로 확인해보면 다음과 같다.
총 6개의 파드가 구성되고, 2개의 로드밸런서가 각각의 파드들에 대해서 동작하는 것을 확인할 수 있다.

metallb-system 확인

k get po -n metallb-system -o wide

다음과 같이 metallb-system의 네임스페이스에 metallb를 통해서 로드밸런싱을 하기 위한 필수적인 파드들이 배포되어 있는 것을 확인할 수 있다.

  • 컨트롤러(controller) : 외부에서 들어오는 트래픽을 처리하고, 노드들을 관리
  • 스피커(Speaker) : 로드 밸런서와 각 노드 간의 네트워크 라우팅을 담당. 로드 밸런서로 들어온 트래픽을 노드로 전달하는 것을 수행

배포 후 접속하여 확인

배포를 완료한 뒤 확인해보자.

## 배포 코드는 생략
k get service -o wide

이제 접속하여 확인해보자.

웹 서버 접속 체크

http://192.168.1.11 인 lb-nginx 로드밸런서의 EXTERNAL-IP로 접속했을 때 웹 페이지로 잘 접속되는 것을 확인할 수 있다.

IP 체크

lb-chk-ip 로드밸런서의 EXTERNAL-IP로 접속했을 때, 도착한 목적지 IP를 확인할 수 있고, 이는 접속할 때마다 지속적으로 변경된다.

변경되는 이유는 바로 노드포트 서비스에서 kube-proxy의 iptables 또는 ebpf 기술에 의해서 접속되는 Endpoint가 변경되어 접속되는 파드가 지속적으로 변경되는 것이다.

🧐 관련 질문


🔥 추가 학습

💡 쿠버네티스에서 로드 밸런서가 필요한 이유

1. 고가용성의 이점

가장 먼저 서비스의 가용성을 높일 수 있다.
로드 밸런서를 사용하면, 배포된 (파드-애플리케이션)서비스 간에 네트워크 트래픽을 고르게 분산시킬 수 있다.

2. 노드 포트의 외부 접근에 대한 제한성

만약 NodePort를 계속해서 사용한다면, NodePort는 외부 접근을 위한 서비스로 사용할 때 제한되는 사항이 있다.

  1. NodePort는 특정 포트 범위 내에서만 사용할 수 있음.
  2. 노드의 IP 주소가 변경되면 이를 알고, 직접 또 다시 변경된 IP 주소로 접속해야함.

3. 로드 밸런서의 고급 라우팅 기능

Ingress와 같은 로드 밸런서는 고급 라우팅 기능을 제공한다.
(ex.URL 기반 라우팅이나 SSL 종료와 같은 기능)

따라서, 클러스터 IP 서비스가 내부적으로 트래픽을 분산시키는 데 도움이 되지만, 로드 밸런서는 외부 접근, 고가용성, 확장성, 그리고 고급 라우팅 기능과 같은 추가적인 이점을 제공한다.


Reference

profile
붉은 배 오색 딱다구리 개발자 🦃Cloud & DevOps

0개의 댓글