Ingress 를 통한 진입점 통일 - Path-based routing

Ingress 를 통한 진입점 통일 - Path-based routing

Ingress

Ingress 의 설정

주문, 상품, 배송 서비스를 분기하는 라우팅 룰을 가진 Ingress 를 생성한다:

apiVersion: networking.k8s.io/v1
kind: "Ingress"
metadata: 
  name: "shopping-ingress"
  annotations: 
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    ingressclass.kubernetes.io/is-default-class: "true"
spec: 
  ingressClassName: nginx
  rules: 
    - host: ""
      http: 
        paths: 
          - path: /orders
            pathType: Prefix
            backend: 
              service:
                name: order
                port:
                  number: 8080
          - path: /deliveries
            pathType: Prefix
            backend: 
              service:
                name: delivery
                port:
                  number: 8080
          - path: /products
            pathType: Prefix
            backend: 
              service:
                name: product
                port:
                  number: 8080

을 ingress.yaml 파일로 만들어 저장한후 생성한다

$ kubectl create -f ingress.yaml

이때 yaml 문법 validation 오류가 생긴다면, 설치된 쿠버네티스의 버전에 따라 발생할 수 있으며, validate 옵션을 해제하여 설정한다:

생성된 ingress 의 상태를 확인한다:

$ kubectl get ingress shopping-ingress -w

NAME               HOSTS   ADDRESS                                                                        PORTS   AGE
shopping-ingress   *       ???   80      7m36s

아무리 기다려도 ADDRESS 부분에 값이 채워지지 않음을 알 수 있다. 원인은 내게 gateway provider 가 없기 때문이다. Ingress 는 Kubernetes 의 스펙일 뿐, 이를 실질적으로 지원하는 ingress controller 가 필요하기 때문이다. 다행히, 우리에겐 무료로 사용할 수 있는 nginx 인그레스 프로바이더를 사용할 수 있다.

Ingress Provider 설치하기

오픈소스 ingress provider 인 nginx ingress controller 를 설치하기 위해서는 하나 이상의 kubernetes 구성요소들을 설치해야 하기 때문에 이를 쉽게 Helm Chart 를 통해서 설치할 수 있다.

Helm으로 Ingress Controller 설치

  • Helm repo 설정
helm repo add stable https://charts.helm.sh/stable
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
kubectl create namespace ingress-basic
  • Helm이 로컬에 설치되어 있지 않은 경우, Helm을 먼저 설치한다.
  • Helm 3.x 설치(권장)
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 > get_helm.sh
chmod 700 get_helm.sh
./get_helm.sh
  • nginx controller 설치
helm install nginx-ingress ingress-nginx/ingress-nginx --namespace=ingress-basic
  • 설치확인
  • Ingress Controller의 EXTERNAL-IP가 API Gateway 엔드포인트
kubectl get all --namespace=ingress-basic
  • 이제, 자동으로 ingress 의 ADDRESS 부분의 설정이 채워지는 것을 확인한다:
$ kubectl get ingress
NAME               HOSTS   ADDRESS                                                                        PORTS   AGE
shopping-ingress   *       acbdde7c8e29f451daee5605b8c7840c-1087513605.ap-northeast-2.elb.amazonaws.com   80      7m36s

발급된 주소에 path 까지 포함하여 접속을 시도해본다:

# http a52f3e05efdb2439e845aed8379437b4-1576614801.ap-northeast-2.elb.amazonaws.com/orders
HTTP/1.1 503 Service Temporarily Unavailable
Connection: keep-alive
Content-Length: 190
Content-Type: text/html
Date: Tue, 11 May 2021 06:25:37 GMT

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx</center>
</body>
</html>

HTML 이 출력되는 것으로보아 nginx 까지는 무사히 연결된 것으로 보이나, 해당 주소 (orders)에 접속이 안되는 것을 확인할 수 있다. 이것은 backend 인 order service 를 디플로이 하지 않았기 때문이다.

order 서비스와 delivery 서비스를 잘 디플로이 해주면, 해당 path 들로 path-based routing 이 잘 이루어짐을 알 수 있다.

order 서비스 디플로이 하기

kubectl create deploy order --image=jinyoung/monolith-order:v20210504
kubectl expose deploy/order --port=8080

Virtual Host based Ingress Example

apiVersion: networking.k8s.io/v1
kind: "Ingress"
metadata: 
  name: "shopping-ingress"
  namespace: "istio-system"  
  annotations: 
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    ingressclass.kubernetes.io/is-default-class: "true"
spec: 
  ingressClassName: nginx
  rules: 
    - host: "prom.service.com"
      http: 
        paths: 
          - 
            path: /
            pathType: Prefix
            backend: 
              service:
                name: prometheus
                port:
                  number: 9090

    - host: "gra.service.com"
      http: 
        paths: 
          - 
            path: /
            pathType: Prefix
            backend: 
              service:
                name: grafana
                port:
                  number: 3000

가상호스트를 테스트하기 위해서 C:\Windows\System32\drivers\etc 내의 hosts 파일에 아래를 추가한다:

<획득한 ingress의 External IP>  prom.service.com, gra.service.com