귀염둥이의 메모

[K8s] 서비스(Service)와 인그레스(Ingress) 본문

Infra & Devops/Kubernetes

[K8s] 서비스(Service)와 인그레스(Ingress)

겸둥이xz 2021. 10. 8. 21:43
반응형

서비스(Service)

서비스는 여러 개의 파드에 접근할 수 있는 IP 하나를 제공한다. 파드가 클러스터 안 어디에 있든 고정 주소를 이용해 접근이 가능하다. 
  • L4 영역에서 통신할 때 사용
  • 파드에 접근할 수 있는 경로 제공
  • 고정된 포인트 / 외부 접근 가능한 포인트를 제공
  • 서비스에는 크게 4가지 종류가 있다

ClusterIP : 기본 서비스 타입이며 클러스터 내부에서만 사용할 수 있다. 클러스터 내부 노드나 파드에서는 클러스터 IP를 이용해서 서비스에 연결된 파드에 접근한다. 클러스터 외부에서는 이용 불가

 

NodePort :  서비스 하나에 모든 노드의 지정된 포트를 할당한다. node1:8080, node2:8080처럼 노드에 상관없이 서비스에 지정된 포트 번호만 사용하여 파드에 접근할 수 있다. 노드의 포트를 사용하므로 클러스터 내부뿐만 아니라 외부에서도 접근할 수 있다.

파드가 node1에서만 실행중이더라도 node2:8080으로 접근했을 때, node1에 실행된 파드로 연결한다. 클러스터 외부에서 클러스터 내부 파드로 접근할 때 사용할 수 있는 가장 간단한 방법이다.

 

LoadBalancer : 클라우드 서비스를 사용할 때 사용가능한 옵션이다. 클라우드에서 제공하는 로드밸런서와 파드를 연결한 후 해당 로드밸런서의 IP를 이용하여 클러스터 외부에서 파드에 접근할 수 있도록 한다. 서비스 상태를 확인하면 EXTERNAL-IP 항목에 로드밸런서 IP를 표시한다.

 

ExternalName : 서비스를 .sepc.externalName 필드에 설정한 값과 연결한다. 클러스터 내부에서 외부로 접근할 때 주로 이용한다.

클러스터 외부에 접근하면 설정해둔 CNAME 값을 이용해 클러스터 외부에 접근할 수 있다. 설정할 때 selector가 필요 없다.

헤드리스 서비스(Headless Service)

. spec.clusterIP 필드 값을 None으로 설정하면 클러스터 IP가 없는 서비스를 만들 수 있다. 로드밸런싱이 필요 없거나 단일 서비스 IP가 필요 없을 때 사용한다. selector 필드를 설정하면 쿠버네티스 API로 확인할 수 있는 엔드포인트가 만들어진다. 서비스와 연결된 파드를 직접 가리키는 DNS A 레코드도 만들어진다. selector가 없으면 엔드포인트는 만들어지지 않으며, DNS 시스템은 ExternalName 타입의 서비스에서 사용할 CNAME 레코드가 만들어진다.

 

인그레스(Ingress)

클러스터 외부에서 안에 있는 파드에 접근할 때 사용하는 방법이다. 서비스와의 차이점은 주로 L7 영역의 통신을 담당해서 처리한다.
  • 클러스터 외부에서 안으로 접근하는 요청들을 어떻게 처리할지 정의해둔 규칙 모음
  • L7 기반 로드밸런싱 제공
  • SSL 인증서 처리 제공
  • 도메인 기반 가상 호스팅 제공
  • 실제로 동작시키는 것은 인그레스 컨트롤러(Ingress controller)이다.

인그레스는 임의의 포트 또는 프로토콜을 노출시키지 않고, HTTP와 HTTPS 이외의 서비스를 인터넷에 노출하려면 Service.Type=NodePort 또는 Service.Type=LoadBalancer 유형의 서비스를 사용한다.

 

클라우드 서비스를 이용한다면 별 다른 설정 없이 자체 로드밸런서 서비스와 연동해서 인그레스를 사용할 수 있다. 만약 쿠버네티스 클러스터를 직접 구축해서 사용한다면 인그레스 컨트롤러를 직접 인그레스와 연동해야 한다. 이때 가장 많이 사용하는 도구는 쿠버네티스에서 제공하는 ingress-nginx이다. 그 외에도 HAProxy, Envoy, Kong 등 소프트웨어 프록시를 이용하기도 한다.

 

인그레스 설정 예시 (v1.18)

# kubernetes v1.18

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: / # '/'' 경로로 리다이렉트
spec:
  rules: # 규칙
    - host: foo.bar.com # 첫 번째 필드 값
      http:
        paths: # HTTP 요청이 어떤 경로에서 들어오는지
          - path: /foos1
            pathType: Prefix # 경로의 접두사를 '/' 기준으로 분리한 값과 일치시킴
            backend: # foo.bar.com/foos1 으로 들어오는 요청을 s1 서비스의 80포트로 보냄
              serviceName: s1
              servicePort: 80
          - path: /bars2
            pathType: Prefix
            backend: # foo.bar.com/bars2 으로 들어오는 요청을 s2 서비스의 80포트로 보냄
              serviceName: s2
              servicePort: 80
    - host: bar.foo.com
      http:
        paths:
          - backend: # bar.foo.com/ 으로 들어오는 요청을 s2 서비스의 80포트로 보냄
              serviceName: s2
              servicePort: 80
  • foo.bar.com 으로 요청이 오면
    • /foos1 이면 서비스 s1으로 연결
    • /bars 이면 s2로 연결
  • bar.fooo.com 으로 요청이 오면 s2로 연결
  • 이와 같이 인그레스는 클러스터 외부에서 오는 요청을 다양한 방식으로 처리할 수 있다

 

Service vs Ingress

  • Service와 Ingress는 포트를 노출하는 기능과 로드밸런싱을 수행한다
  • Service = L4
  • Ingress = L7

  • 서비스는 여러 개로 복제된 한 종류의 파드를 로드밸런싱 한다
  • 인그레스는 여러 서비스에 대해서 라우팅의 역할을 담당한다
  • 일반적인 경우 온프레미스 환경에서는 ServiceNodePort 타입을 사용하고, 퍼블릭 클라우드 환경에서는 ServiceLoadBalancer 타입을 사용하면 대부분 서비스 운영이 가능하다
  • MSA(Microservice Architecture)로 개발되어 서비스 간의 라우팅이 필요한 구조에서는 Ingress를 사용한다

References

https://arisu1000.tistory.com/27840?category=787056 

https://danawalab.github.io/kubernetes/2020/01/23/kubernetes-service-ingress.html

반응형
Comments