IT/AWS

AWS kops 쿠버네티스 클러스터에 Ingress 적용하기

twofootdog 2020. 3. 8. 23:53

이번 글에서는 AWS에 kops로 구축한 쿠버네티스 클러스터에 Ingress를 적용하는 방법에 대해 알아볼 것이다.

글의 순서는 다음과 같다.

  1. Ingress란 무엇인가?
  2. 실습 전 준비사항
  3. 쿠버네티스 클러스터에 Ingress 적용하기
  4. Ingress 테스트

 

 

 

 


1. Ingress란 무엇인가?

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

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

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

 

 

 

 


2. 실습 전 준비사항

이번 실습을 진행하기 위해선 다음과 같은 준비가 되어 있어야 한다.

  • AWS에 kops로 구축한 쿠버네티스 클러스터
  • 쿠버네티스 클러스터에 구동중인 스프링부트 서비스(context-root : /)

 

 

 

 


3. 쿠버네티스 클러스터에 ingress 적용하기

3-1. Ingress controller 적용

우선 Ingress controller yaml파일을 다운받는다.

# curl -Lo ingress-nginx-v1.6.0.yaml https://raw.githubusercontent.com/kubernetes/kops/master/addons/ingress-nginx/v1.6.0.yaml

 

 

그 다음 ingress-nginx-v1.6.0.yaml을 kubectl apply 로 클러스터에 등록시키면 되는데, 해당 파일의 Deployment 선언 부분에 apiVersion이 extensions/v1beta1로 되어 있어서 Deployment 가 적용되지 않는다(extensions/v1beta1은 쿠버네티스 버전 1.16부터 지원이 중단되었다). 그렇기 때문에 apiVersion을 extensions/v1beta1을 apps/v1으로 변경해줘야 하고 selector 필드를 추가해줘야한다(밑에 소스코드에서 주석으로 "삭제" 혹은 "추가"라고 명시한 부분만 수정하면 된다).

ingress-nginx-v1.6.0.yaml : 

....

kind: Deployment
#apiVersion: extensions/v1beta1 삭제
apiVersion: apps/v1 #추가
metadata:
  name: nginx-default-backend
  namespace: kube-ingress
  labels:
    k8s-app: default-http-backend
    k8s-addon: ingress-nginx.addons.k8s.io
spec:
  replicas: 1
  selector: #추가
    matchLabels: #추가
      k8s-app: default-http-backend #추가
      k8s-addon: ingress-nginx.addons.k8s.io #추가
      app: nginx-default-backend #추가
  revisionHistoryLimit: 10
  template:
    metadata:
      labels:
        k8s-app: default-http-backend
        k8s-addon: ingress-nginx.addons.k8s.io
        app: nginx-default-backend


....


kind: Deployment
#apiVersion: extensions/v1beta1 삭제
apiVersion: apps/v1 #추가
metadata:
  name: ingress-nginx
  namespace: kube-ingress
  labels:
    k8s-app: nginx-ingress-controller
    k8s-addon: ingress-nginx.addons.k8s.io
spec:
  replicas: 3
  selector: #추가
    matchLabels: #추가
      app: ingress-nginx #추가
      k8s-app: nginx-ingress-controller #추가
      k8s-addon: ingress-nginx.addons.k8s.io #추가
  template:
    metadata:
      labels:
        app: ingress-nginx
        k8s-app: nginx-ingress-controller
        k8s-addon: ingress-nginx.addons.k8s.io
      annotations:
        prometheus.io/port: '10254'
        prometheus.io/scrape: 'true'


....


 

 

yaml파일 수정이 완료되었으면 쿠버네티스 클러스터에 적용시키자.

# kubectl apply -f ingress-nginx-v1.6.0.yaml

 

 

적용이 완료되면 정상적으로 구동되고 있는지 확인해보자.

# kubectl get pod --all-namespaces
# kubectl get svc --all-namespaces

 

 

 

3-2. Ingress 적용

Ingress controller를 적용했으니 이제 Ingress를 적용해보자.

Ingress는 https://raw.githubusercontent.com/kubernetes/contrib/master/ingress/controllers/nginx/examples/ingress.yaml 에서 Sample 파일을 다운받아서 수정하였다.

 

ingress.yaml : 

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: toy-project-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host:
    http:
      paths:
      - path: /app1
        backend:
          serviceName: toy-project-service
          servicePort: 8082

코드에 대해 간략히 설명하자면 [ingress호스트주소]/[path]으로 접속하게 되면 [스프링부트서비스 호스트주소]:[servicePort]/[path]과 동일한 서비스를 호출하게 된다. 이 코드에선 [ingress호스트주소]/app1으로 접속하게 되면 [스프링부트서비스 호스트주소]:8082/app1 서비스를 호출하게 된다.

 

 

 

 

Ingress파일 수정이 끝났으면 적용시키고 확인해보자. 

# kubectl apply -f ingress.yaml
# kubectl get ingress --all-namespaces

 

 

 

 


4. Ingress 테스트

이제 Ingress 테스트를 해보자.

Ingress를 통해서 서비스에 접속하기 위해서는 Ingress 호스트주소를 알아야 한다. 

Ingress의 호스트주소는 Ingress의 ADDRESS나 ingress-nginx의 EXTERNAL-IP를 확인하면 된다. 

# kubectl get ingress --all-namespaces
# kubectl get svc --all-namespaces

 

 

 

웹페이지를 열고 스프링부트 서비스를 호출해보자. 접속할 주소는 [ingress ADDRESS]/[ingress yaml에 명시된 path]다. 이 글에서는 [ingress ADDRESS]/app1이다.

접속을 해보면 정상적으로 접속이 되지 않는다. 왜일까? 바로 스프링부트 서비스의 context-root가 수정되지 않았기 때문이다. ingress는 /app1으로 가지만 스프링부트 서비스의 context-root는 현재 / 로 되어있기 때문이다.

스프링부트 서비스를 수정해주자. src/main/resources/application.yml 파일의 소스 코드 상단에 다음 코드를 삽입해주고 재배포를 해보자.

src/main/resources/application.yml

server:
  port: 8080
  servlet:
    context-path: /app1

 

 

 

그리고 서비스를 배포해보면 정상적으로 스프링부트 서비스를 호출하는 것을 확인할 수 있다.

 

 

 

 


참고

https://github.com/kubernetes/kops/tree/master/addons/ingress-nginx

 

kubernetes/kops

Kubernetes Operations (kops) - Production Grade K8s Installation, Upgrades, and Management - kubernetes/kops

github.com

https://github.com/awskrug/handson-labs-2018/tree/master/Container/3_Kubernetes

 

awskrug/handson-labs-2018

AWSKRUG Hands-on Lab 2018. Contribute to awskrug/handson-labs-2018 development by creating an account on GitHub.

github.com

https://twofootdog.tistory.com/23

 

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

이번 글에서는 Ingress의 정의 및 On-Premise환경(클라우드가 아닌 자체 서버를 사용한 경우)에서 Ingress를 어떻게 사용하는지에 대해 알아볼 것이다. 1. Ingress란 무엇인가? 1-1. Ingress 정의 쿠버네티스 Ingr..

twofootdog.tistory.com