[Kubernetes] Service


NodePort

  • NodePort는 Kubernetes의 서비스 유형중 하나로 k8s 클러스터 외부에서 내부 파드에 접근할 수 있도록 해주는 서비스 타입이다.
  • Node의 IP와 지정된 포트(Node port)를 통해 파드로 요청을 전달한다.
  • 노드 포트 서비스 작성방식으로 서비스의 관점에서 작성된다.
    • TargetPort: 파드에서 웹 서버가 실제 실행되는 포트(80)
    • port: 서비스 내부에서 사용하는 포트(80)
    • NodePort: 외부에서 접근가능한 노드의 포트 (30008, 3000 ~ 32767 범위에 있어야 함)
    • 파드와 서비스의 연결은 파드의 레이블(label)과 셀렉터(Selector)를 서비스에 정의해주어 사용한다.
apiVersion: v1
kind: Service
metadata:
  name: backend
  
spec:
  type: NodePort # LoadBalance, ClusterIP
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30008

  selector:
    app: my-app
    type: front-end

특징 및 동작 방식

  • 자동 로드 밸런싱: 동일한 레이블을 가진 여러 파드에 랜덤으로 요청을 분산
  • 멀티 노드 지원: 클러스터 내 모든 노드에 동일한 nodePort가 매핑됨
    • 어떤 노드 IP를 사용하든 동일한 포트로 접근 가능
  • 자동 업데이트: 파드가 추가/삭제되면 서비스가 자동으로 엔드포인트(파드) 목록을 갱신
  • 별도의 추가 설정 없이, 유연하고 유지보수 부담이 적은 외부 공개 방식

ClusterIP

  • Kubernetes 내부에서만 접근 가능한 기본 서비스 유형
    • ClusterIP는 파드끼리의 통신을 하기 위해서 주로사용
  • 여러 파드(Pod)를 하나의 그룹으로 묶고, 단일 가상 IP와 이름(DNS) 으로 접근 가능
  • 주로 파드 간 통신(예: 프론트엔드 → 백엔드, 백엔드 → Redis 등)에 사용됨
  • 서비스는 파드들의 IP가 바뀌더라도 고정된 접근 지점 역할을 함
  • 요청은 레이블로 연결된 여러 파드 중 하나로 랜덤하게 분산

Yaml 작성법

  • Port: 클러스터 서비스의 포트
  • targetPort: 클러스터 서비스의 엔드포인트(접근하고자하는 파드의) 포트
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  ports:
    - port: 80
      targetPort: 80
      
  selector:
    app: myapp
    type: backend

LoadBalancer

NodePort 방식의 한계

  • NodePort 서비스를 사용하면 외부 사용자가 노드 IP:포트번호로 접근 가능
  • 하지만 노드 IP와 포트를 알아야 하며, 사용자는 votingapp.com 같은 도메인 기반 단일 URL을 선호
  • 사용자에게 여러 IP+포트 조합을 제공하는 건 비직관적이고 불편함

LoadBalancer 서비스의 개념

  • type: LoadBalancer로 설정하면 클라우드 제공업체의 로드밸런서를 자동 생성
  • 외부 사용자는 하나의 고정 URL 또는 IP로 접근 가능 (ex: votingapp.com)
  • 트래픽은 클러스터 노드의 NodePort 포트로 라우팅됨 (내부적으로는 NodePort 사용)

조건 및 주의사항

  • GCP, AWS, Azure 같은 공식 지원 클라우드 환경에서만 동작
  • VirtualBox 등 로컬 환경에서는 동작하지 않으며, 실제로는 NodePort와 동일한 효과만 나타남
  • 클라우드 환경에서 외부 로드밸런서를 직접 설정할 필요 없이 자동화 가능
apiVersion: v1
kind: Service
metadata:
  name: backend
  
spec:
  type: LoadBalance
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30008

  selector:
    app: my-app
    type: front-end