반응형

이번 포스팅은 구글 클라우드의 Kubernetes Service 비교 글을 참조 했으며 참조한 원본 글을 아래의 링크에서 확인 할 수 있다.

 

Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what?

Recently, someone asked me what the difference between NodePorts, LoadBalancers, and Ingress were. They are all different ways to get…

medium.com


Kubernetes 서비스

Kubernetes 서비스는 Pod(파드) 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 방법을 의미한다.

Kubernetes는 Pod에게 고유한 IP 주소와 Pod 집합에 대한 단일 DNS 명을 부여하고, 그것들 간에 로드-밸런스를 수행할 수 있다. 다만 Pod의 경우에 지정되는 Ip가 랜덤하게 할당되고 시작때마다 재할당되기 때문에 고정된 엔드포인트로 호출이 어렵다, 또한 동일 애플리케이션이 여러 Pod에서 운용될 경우(Replication, Scale Out되었을 경우) 이 Pod 간의 로드밸런싱이 필요하다. 이런 역할들을 서비스가 한다.

 

즉 서비스는 지정된 IP로 생성이 가능하고, 여러 Pod를 묶어서 로드 밸런싱이 가능하며, 고유한 DNS 이름을 가질 수 있다.

 

이러한 서비스는 다음의 5가지 방식이 있으며 이 포스팅에서는 Cluster IP, Load Balancer, NodePort 3가지와 서비스는 아니지만 k8s 클러스터 내외부 통신을 도와주는 Ingress Gateway에 대해 다루기로 하겠다.

 

  • ClusterIP
  • NodePort
  • LoadBalancer
  • External name
  • Headless

 

 

ClusterIP

Kubernetes(쿠버네티스)의 기본 설정으로, 서비스에 클러스터 IP (내부 IP)를 할당한다. 쿠버네티스 클러스터 내에서는 이 서비스에 접근이 가능하지만, 클러스터 외부에서는 외부 IP 를 할당  받지 못했기 때문에, 접근이 불가능하다. 그렇기 때문에 외부에서 접근을 하기 위해서는 별도의 Proxy 설정을 해야 하며 이렇게 설정된 Proxy를 통해 외부에서 접근 가능하다.

특징

  • ClusterIP 서비스는 Kubernetes 기본 서비스로, 클러스터 내의 다른 앱이 접근할 수 있게 해준다.
  • ClusterIP는 외부 접근이 되지 않는다.
  • K8S내에 Proxy 설정을 통해 외부에서 접근 가능하게 할 수 있다.

사용시기

  • 서비스를 디버깅하거나 특정 사유로 PC에서 직접 접근할때
  • 내부 대시보드 표시 등 내부 트래픽을 허용할 때

ClusterIP YAML 예제

apiVersion: v1
kind: Service
metadata:
  name: my-internal-service
spec:
  selector:
    app: my-app
    type: ClusterIP
    ports:
      - name: http
        port: 80
        targetPort: 80
        protocol: TCP

 

 

NodePort

ClusterIP가 Proxy를 이용해 외부에서 접근하게 하는 방식인거 달리, Kubernetes는 모든 노드의 IP와 포트를 통해서도 접근이 가능하게 된다. 예를 들어 아래와 같이 각각의 Node들은 서비스를 NodePort 타입으로 선언을 하고, 각 nodePort를 각각 설정하면, 외부에서 이렇게 설정된 NodePort로 접근이 가능하게 된다.

 

특징

  • NodePort서비스는 Pod가 탑재된 Node에 접근할 수 있는 포트를 외부로 노출(Expose)시켜주는 포트이다.
  • NodePort는 30000 ~ 32767 사이의 Port만 사용할 수 있다.
  • 사용하기 가장 쉽다.

사용시기

  • 포트당 한 서비스만 할당할 수 있다.
  • 30000-32767 사이의 포트만 사용할 수 있으므로 서비스 대상이 많은 경우 추천하지 않는다.
  • 비용에 민감하거나 항상 운용하는 서비스가 아닌 경우 사용 추천

NodePort YAML 예제

apiVersion: v1
kind: Service
metadata:
  name: my-nodeport-service
spec:
  selector:
    app: my-app
    type: NodePort
    ports:
      - name: http
       port: 80
       targetPort: 80
       nodePort: 30036
       protocol: TCP

 

프로그램 예제

다음의 링크를 통해 NodePort로 Hello Minikube를 구현한 예제를 테스트 해 볼수 있다.

 

Spring Boot로 만든 Hello Minikube 예제

이번 포스팅에서는 spring boot 기반의 hello 애플리케이션을 지난번 포스팅에서 설치했었던 minikube(미니큐브) 시스템에 배포하고 호출하는 예제를 실행해 보고자 한다. (*PC에 minikube가 이미 설치되

sharplee7.tistory.com

 

 

LoadBalancer

보통 클라우드 벤더에서 제공하는 설정 방식으로, 외부 IP 를 가지고 있는 로드밸런서를 할당한다. 외부 IP를 가지고 있기  때문에, 클러스터 외부에서 접근이 가능하다. 

 

특징

  • LoadBalancer 서비스는 서비스를 인터넷에 노출하는 일반적인 방식이다.
  • GKE의 경우 Network Load Balancer를 작동시켜 모든 트래픽을 서비스로 포워딩하는 단 하나의 IP주소를 제공한다.

사용시기

  • 서비스를 직접적으로 노출하기 원할 경우
  • 필터, 라우팅, 인증처리, 암호화등 부가 기능이 필요 없을때
  • DMZ의 API Gateway등과 통합할 때
  • 단, 노출하는 서비스마다 자체 IP를 가지게 된다는 것과, 노출 서비스 마다 LoadBalancer 비용을 지불해야 하는 것은 부담스러움

LoadBalancer YAML 예제

apiVersion: v1
kind: Service
metadata:
  name: internal-loadbalancer
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080
      selector:
        app: internal-loadbalancer
        ver: v1

 

Ingress

MSA(Micro Service Architecture)의 경우, 대부분 Kubernetes 서비스 하나가 MSA의 서비스로 구성되며 이러한 서비스는 하나의 URL로 표현된다. (/users, /products, …) 

그래서 MSA 서비스간의 라우팅을 하기 위해서는 API Gateway가 필요했으며, 이 경우 API Gateway에 대한 관리포인트가 생겨났다.

 

하지만 URL 기반의 간단한 라우팅 정도라면, API Gateway 처럼 무거운 제품이 아니라, Kubernetes에서 HTTP(S)기반의 L7 Load Balancer 기능을 제공해주는 Ingress를 이용해 API Gateway가 해주는 상당 수의 기능을 간단하게 구현 할 수 있다. 

 

즉, Ingress를 이용하면 Kubernetes 내부 서비스들과 L7 Load Balancer를 이용해 통신이 가능하며 각 서비스들에 대한 end point(/users, /products, ...) 기능까지 구현 가능하다.

 

 

특징

  • Ingress는 Cluster, NodePort, LoadBalancer와 달리 서비스가 아니다.
  • L7 수준의 로드밸런싱 역할을 수행한다.
  • End Port 역할 수행
  • 가장 강력한 외부로의 서비스 노출 방식이지만 가장 복잡한 방식임

사용시기

  • NginX, Contour, ELB, Google Cloud Load Balancer, Kong등이 유명
  • 다양한 부가 기능이 필요할때.(제품에 따라 트래픽제어, 필터링, 로드밸런싱, SSL, Auth 등 가능)

Ingress YAML 예제

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-ingress-ip
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "hello-ingress-ip"
spec:
  rules:
  - http:
      paths:
      - path: /users/*
        backend:
          serviceName: users-node-svc
          servicePort: 80
      - path: /products/*
        backend:
          serviceName: products-node-svc
          servicePort: 80

 

 

정리

Cluster IP, NodePort, LoadBalancer 및 Ingress 비교


이번 포스팅은 여기까지

끝~

반응형

+ Recent posts