IT/PaaS

쿠버네티스 Ingress 개념 및 적용방법

twofootdog 2020. 1. 20. 20:27

이번 글에서는 Ingress의 정의 및 On-Premise환경(클라우드가 아닌 자체 서버를 사용한 경우)에서 Ingress를 어떻게 사용하는지에 대해 알아볼 것이다.

 

1. Ingress란 무엇인가?

1-1. Ingress 정의

쿠버네티스 Ingress란 HTTP(S) 기반의 L7 로드밸런싱 기능을 제공하는 컴포넌트이다. Ingress는 외부에서 쿠버네티스 내부로 들어오는 네트워크 요청을 어떻게 처리할지 결정하며, 쉽게 말해 외부에서 쿠버네티스에서 실행중인 Deployment와 Service에 접근하기 위한 관문과 같은 역할을 담당한다.

쿠버네티스 서비스는 기본적으로 L4 레이어로 TCP 단에서 Pod를 로드밸런싱한다. 그런데 MSA(마이크로 서비스 아키텍쳐)의 경우 쿠버네티스 서비스 하나가 MSA 서비스 하나로 표현되는 경우가 많고, 서비스가 하나의 URL로 대표되는 경우가 많다(/member, /product ...). 그래서 MSA 서비스 간 라우팅을 하기 위해서는 API게이트웨이를 넣는 경우가 많은데, URL기반의 라우팅 정도라면 API게이트웨이처럼 무거운 아키텍쳐 컴포넌트가 아닌 L7 로드밸런서 정도로도 라우팅이 가능하며, 이때 필요한게 바로 쿠버네티스 Ingress다.

쿠버네티스 Ingress 개념도

1-2. Ingress, Ingress-Controller, Ingress-nginx

엄밀히 말하면 Ingress는 외부로부터 들어오는 요청에 대한 로드밸런싱, TLS/SSL 인증서 처리, 도메인 기반 가상 호스팅 제공, 특정 HTTP 경로의 라우팅 등의 규칙들을 정의해 둔 자원이며, 이런 규칙들을 실제로 동작하게 해주는건 Ingress-Controller다. 

하지만 클라우드 서비스를 사용하게 되면 별다른 설정없이 각 클라우드 서비스에서 자사의 로드밸런서 서비스들과 연동해서 Ingress를 사용할 수 있게 해주지만, 클라우드를 사용하지 않고 클러스터를 구축해서 사용하는 경우는 Ingress Controller를 직접 Ingress와 연동시켜줘야 하며, 이때 가장 많이 사용되는 것이 바로 Ingress-nginx다. 

따라서 이번 장에서는 Ingress, Ingress-Controller, Ingress-nginx를 적용해서 쿠버네티스 클러스터 내에 Ingress를 적용해 볼 것이다.

 

2. Ingress 적용하기

Ingress를 적용하기 위해서는 Ingress, Ingress-Controller, Ingress-nginx 적용이 필요하다.

하지만 그 전에 사전 준비사항이 있다.

 

2-1. 사전 준비사항

쿠버네티스 클러스터 상에서 구동중인 한 개 이상의 스프링부트 어플리케이션

 

2-2. Ingress yaml 파일 작성 후 적용

우선 Ingress부터 적용해보자. yaml파일 작성 후 쿠버네티스 클러스터에 등록해보자.
ingress.yaml : 

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: batch-visualizer-ingress
  namespace: ns-project
  annotations:
    kubernetes.io/ingress.class: nginx
    #ingress.kubernetes.io/rewrite-target: /
    #ingress.bluemix.net/rewrite-path: "serviceName=app-service rewrite=/"
spec:
  rules:
  - http:
      paths:
      - path: /auth/
        backend:
          serviceName: batch-visualizer-auth-service
          servicePort: 8082
      - path: /
        backend:
          serviceName: batch-visualizer-backend-provider-service
          servicePort: 8084
      - path: /batch/
        backend:
          serviceName: batch-visualizer-backend-migrator-service
          servicePort: 8081

코드에 대해 하나씩 설명해보자면 우선 kind는 Ingress로 했고, namespace는 Ingress에 묶일 서비스와 동일한 namespace로 적용하였다. 또한 spec.rules.paths.path에 총 3개의 uri(/auth/, /, /batch/)를 지정하였으며, 각 서비스 별 서비스 포트번호를 지정하였다. 위와 같이 path를 지정하게 되면 서비스 호출 시 uri가 /auth/로 유입되면 8082 포트를 가진 서비스를, /로 유입되면 8084 포트를 가진 서비스를, /batch/로 유입되면 8081 포트를 가진 서비스를 각각 호출하게 된다.

 

Ingress를 적용시킨 후 정상적으로 적용되었는지 확인해보자.

 

2-3. Ingress-controller 및 Ingress-nginx 적용

다음으로 Ingress-controller와 Ingress-nginx를 적용해보도록 하겠다.

Ingress-controller 적용 : 

# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml

 

Ingress-nginx 적용 : 

# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml

 

Ingress-controller와 Ingres-nginx가 적용되고 ingress를 확인해 보면 다음과 같이 ADDRESS가 할당된 것을 확인할 수 있다.

 

쿠버네티스에 올라간 pod 정보를 확인해보면 nginx-ingress-controller가 구동중인 것을 확인할 수 있다.

 

3. 스프링부트 어플리케이션 설정 변경 & 서비스 호출

Ingress 설정을 완료하였으니, 이제 스프링부트 어플리케이션 서비스를 호출해보도록 하겠다. 하지만 이에 앞서 스프링부트 어플리케이션의 context-path를 변경해야 한다. context-path를 왜 변경해야 하냐면 Ingress.yaml에 path를 /auth, /, /batch 총 3개로 나누었으니 Ingress에 호출되는 스프링부트 어플리케이션의 context-path도 해당 uri에 맞게 변경이 필요하다. 필자는 이 글에서는 "/auth" uri로 시작하는 auth 서비스"/" uri로 시작하는 provider 서비스를 띄워 Ingress를 통해 서비스를 호출하도록 하겠다.

 

3-1. Ingress & 어플리케이션 구조도

 

3-2. 스프링부터 어플리케이션 context-path 변경

스프링부트로 만든 auth 서비스의 context-path를 변경해보자. context-path는 application.yaml에서 변경 가능하다.

provider 서비스는 Ingress 설정에 path가 "/" 이고, context-path도 기본 "/" 이기 때문에 변경하지 않는다.

auth 서비스의 application.yaml : 

# dev environment
server:
  port: 8080
  servlet:
    context-path: /auth

....

위와 같이 설정 변경 후 해당 어플리케이션을 재배포 하자. 

 

 

3-3. Ingress를 통한 스프링부트 어플리케이션 서비스 호출

다음으로 Ingress를 통해 스프링부트 어플리케이션 서비스를 호출해보자. Ingress가 적용되었다면 서비스 분기는 포트번호가 아닌 Ingress에 정의된 spec.rules.http.paths.path 의 uri 정보로 처리된다. 따라서 서비스 호출 URL은 http://[서버IP]:[Ingress 서비스 포트번호]/[spec.rules.http.paths.path]/... 이 된다. 

우선 서비스 호출 전 Ingress서비스의 포트번호를 알아보자. 포트번호 확인은 쿠버네티스 서비스 목록에서 확인하면 된다(해당 글에서는 30275포트)

 

auth 서비스를 호출 할 때는 http://[서버IP]:[Ingress 서비스 포트번호]/auth/... 로 호출하면 된다(이 포스트에서는 http://66.42.43.41:30275/auth/.. 로 호출). POSTMAN을 통해 API를 호출해보면 다음과 같이 정상 응답을 받을 수 있다. 

 

provider 서비스를 호출 할 때는 http://[서버IP]:[Ingress 서비스 포트번호]/... 로 호출하면 된다(이 포스트에서는 http://66.42.43.41:30275/.. 로 호출). POSTMAN을 통해 API를 호출해보면 다음과 같이 정상 응답을 받을 수 있다. 

 

 

 

참고

https://bcho.tistory.com/1263

 

쿠버네티스 #8 - Ingress

쿠버네티스 #8 Ingress 조대협 (http://bcho.tistory.com) 쿠버네티스의 서비스는, L4 레이어로 TCP 단에서 Pod들을 밸런싱한다. 서비스의 경우에는 TLS (SSL)이나, VirtualHost와 같이 여러 호스트명을 사용하거..

bcho.tistory.com

https://blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=221502890249

 

162. [Kubernetes] 1편 : 쿠버네티스 Ingress 개념 및 사용 방법, 온-프레미스 환경에서 Ingress 구축하기

이번 포스트에서는 쿠버네티스에서 인그레스 (Ingress) 를 사용하는 방법, 그리고 Public 클라우드를 쓰...

blog.naver.com

https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal

 

Installation Guide - NGINX Ingress Controller

 Installation Guide Contents Prerequisite Generic Deployment Command Attention The default configuration watches Ingress object from all the namespaces. To change this behavior use the flag --watch-namespace to limit the scope to a particular namespace. W

kubernetes.github.io