DevOps/Kubernetes

[Kubernetes] Service / Ingress: L4 L7 Load Balancer

ooeunz 2020. 7. 16. 14:06
반응형

Service란?

이전 포스팅에서 파드는 컨트롤러에 의해서 관리되고 만약 노드 중 하나에 장애가 발생하면 해당 노드에 있는 파드들을 다른 노드에 옮김으로써 동적으로 파드들을 관리한다고 이야기했습니다. 때문에 파드는 클러스터 안에서 옮겨 다니게 되는데, 이 과정에서 노드를 옮기면서 파드 안의 IP가 변경되게 됩니다. 이와 같이 동적으로 변하는 파드의 IP를 특정하기 위해서 사용하는 방법이 쿠버네티스 서비스(Service)입니다. 서비스는 위치를 바꿔가는 노드의 정보를 유연하게 쫓기위해 라벨(label)과 라벨 셀렉터(labal selector)를 사용하며, yaml 템플릿을 정의할 때 어떤 파드를 같은 서비스로 묶을지 정하게 됩니다. (metadata영역에 label을 정의할 수 있고, 라벨 셀렉터에 매핑시켜주면 같은 서비스로 분류됩니다.)

 

서비스를 사용하면 파드가 클러스터 안 어디에 있던지 고정 주소를 이용해서 접근할 수 있게됩니다. 또한 클러스터 외부에서 클러스터 안 파드에도 접근할 수 있습니다. 특별히 Service와 Ingress(아래에서 좀 더 자세히 다룸)는 외부 접근을 할 수 있을 뿐만 아니라 로드 밸런싱을 지원하는데, 둘의 차이는 통신 영역의 차이가 있습니다. Service는 OSI 7계층 중 L4 영역에서의 통신을 사용하고, Ingress는 L7 영역에서 통신할 때 사용하게 됩니다. 

 

 

[Teah] Load Balancer(로드 밸런서)

로드 밸런서 4차 산업혁명 시대가 되고 인터넷을 통해 거의 모든 작업들이 처리되고 있습니다. 웹툰부터 시작해서 페이스북 좋아요나 유튜브 스트리밍까지 모든 전자기기가 인터넷을 이용해 통

ooeunz.tistory.com

 

서비스는 크게 네 가지 타입이 있습니다. 이번 포스팅에서는 각 서비스에 대한 설명과 외부에서 접근할 수 있는 방법에 대해서 다뤄보겠습니다.

 

ClusterIP

먼저 ClusterIP입니다. ClusterIP는 이름 그대로 쿠버네티스 클러스터 안에서만 사용할 수 있습니다. 클러스터 안 노드나 파드에서는 ClusterIP를 이용해서 서비스에 연결된 각 파드들에 접근할 수 있습니다. 하지만 클러스터 내부 가상의 IP이기 때문에 클러스터 외부에서는 접근할 수 없습니다.

apiVersion: v1
kind: Service
metadata:
  name: sisko-service
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: sisko

 

NodePort

서비스에 각 노드의 지정된 포트를 할당하는 방식으로 클러스터 외부와 내부 모두 접근이 가능합니다. 이름에서 암시하듯 NodePort는 모든 노드에 특정 포트를 열어두고, 이 포트로 보내지는 모든 트래픽을 서비스로 포트 포워딩하게 됩니다. 그래서 파드가 일부 노드에만 실행되어 있을 때 파드가 떠 있지 않은 노드로 접근하더라도 파드가 떠 있는 노드로 연결되게 됩니다.

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

.spec.ports[]를 살펴보도록 하겠습니다. ports 안에는 port, tartgetPort, nodePort가 있습니다.

  • Port : 서비스가 클러스터 내부로 오픈하는 포트입니다.
  • TargetPort : 타겟 파드에 요청을 보내는 포트입니다.
  • NodePort : 서비스가 클러스터 외부로 노출하는 포트입니다.

 

LoadBalancer

AWS, GCP,과 같은 Public Cloud 서비스에서 지원하는 쿠버네티스 로드밸런서 장비를 사용합니다. 클라우드에서 제공하는 로드밸런서와 파드를 연결한 후 해당 로드밸런서 IP를 이용해 클러스터 외부에서 파드에 접근할 수 있도록 해줍니다.

 

ExternalName

클러스터 내부에서 외부로 접근할 때 주로 사용하는 서비스로, 서비스를 .spec.externalName 필드에 설정한 값과 연결합니다.

kind: Service
apiVersion: v1
metadata:
  name: test-service
  namespace: default
spec:
  type: ExternalName
  externalName: test.database.example.com #외부 IP

 


Ingress란?

Ingress는 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지에 관한 규칙 모음입니다. Ingress 자체는 클러스터 외부에서 접근해야 할 URL을 사용할 수 있도록 하고, 로드 밸런싱, SSL 인증서 처리, 도메인 기반 가상 호스팅 등의 규칙을 정의해둔 자원이고, 실제로 동작시키는 것은 Ingress-Controller입니다.

 

만약 Cloud 서비스에서 로드밸런서 서비스를 사용한다면 인그레스를 연동해서 쉽게 사용할 수 있습니다. 하지만 클라우드 서비스를 사용하는 것이 아니라 직접 쿠버네티스 클러스터를 구축해야 한다면 Ingress-Controller를 직접 Ingress와 연동해야 합니다. 이때 가장 많이 사용하는 도구는 쿠버네티스에서 공식적으로 제공하는 ingress-nginx입니다.

 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: sisko-ingress2
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  tls:
  - hosts:
    - search-cruise-sisko.dev.daumkakao.io
    secretName: devdakao
  rules:
  - host: search-cruise-sisko.dev.daumkakao.io
    http:
      paths:
      - path: /(.*)
        backend:
          serviceName: sisko-service1
          servicePort: 8080
      - path: /test/(.*)
        backend:
          serviceName: sisko-service2
          servicePort: 8080

 

쿠버네티스의 전체 구조를 정리해보자면, 먼저 유저로부터 Ingress Host로 부터 요청을 받고, 서비스를 거쳐 파드에 요청을 전달해서 비즈니스 로직을 수행한 다음 응답을 다시 유저로 return해 주게 됩니다.

 

이 과정에서 각 Ingress와 Service가 로드밸런싱을 하게되고, 컨트롤러가 각 파드들의 셀프힐링과 배포에 대한 사항들을 관리해주게 됩니다.

 

반응형