Ingress에서 URL Path를 통한 라우팅

문제 상황

아래 상황은 실제로 발생한 이슈가 아닌, 이해를 돕기 위해 만든 가상의 상황입니다.

parker-movie 앱에서 영화의 정보를 조회할 수 있는 GET /movies/{movieId} API가 존재한다. 그런데, movieId 100번은 너무 유명한 영화라 조회 빈도가 높았고 부하가 심해졌다. 이를 해결하는 다양한 방식이 있겠지만, 여기서는 쿠버네티스 환경에서 pod 중 movieId 100번을 위한 pod을 따로 사용하고 싶었다. 이를 위해서 Ingress에서 URL Path를 통한 라우팅을 사용할 수 있다.

적용

apiVersion: apps/v1
kind: Deployment
metadata:
  name: parker-movie-normal-app
  labels:
    app: parker-movie-normal-app
spec:
  selector:
    matchLabels:
      app: parker-movie-normal-app
  replicas: 2
  template:
    metadata:
      labels:
        app: parker-movie-normal-app
    spec:
      containers:
        - name: parker-movie
          image: parker-movie:latest
          imagePullPolicy: Always
          ports:
            - containerPort: 8081
          env:
            - name: SPRING_PROFILES_ACTIVE
              value: real
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: parker-movie-100-app
  labels:
    app: parker-movie-100-app
spec:
  selector:
    matchLabels:
      app: parker-movie-100-app
  replicas: 2
  template:
    metadata:
      labels:
        app: parker-movie-100-app
    spec:
      containers:
        - name: parker-movie
          image: parker-movie:latest
          imagePullPolicy: Always
          ports:
            - containerPort: 8081
          env:
            - name: SPRING_PROFILES_ACTIVE
              value: real
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: parker-movie-normal-svc
  name: parker-movie-normal-svc
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 8081
  selector:
    app: parker-movie-normal-app
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: parker-movie-100-svc
  name: parker-movie-100-svc
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 8081
  selector:
    app: parker-movie-100-app
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: parker-movie-ingress
  namespace: default
  annotations:
    ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
    - hosts:
        - parker.movie.com
      secretName: parker-movie-com
  rules:
    - host: parker.movie.com
      http:
        paths:
          - path: /movies/100
            pathType: Prefix
            backend:
              service:
                name: parker-movie-100-svc
                port:
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: parker-movie-normal-svc
                port:
                  number: 80
  • 전체 movie를 처리하는 deployment와 service를 생성한다.
    • Deployment: parker-movie-normal-app
    • Service: parker-movie-normal-svc
  • movieId 100번을 위한 deployment와 service를 생성한다.
    • Deployment: parker-movie-100-app
    • Service: parker-movie-100-svc
  • Ingress를 생성하여, URL Path를 통한 라우팅을 설정한다.
    • path: /movies/100으로 요청이 들어오면, parker-movie-100-svc로 라우팅한다.
    • path: /으로 요청이 들어오면, parker-movie-normal-svc로 라우팅한다.

주의할 점은 paths에 설정한 path들은 순서대로 처리가 된다. 예를 들어, /movies/100 이 path가 들어와서 첫 번째와 매칭되어 처리가 되면 뒤에 path는 살펴보지 않는다.

그리고 path 설정에는 정규식을 제한적으로 사용가능한 것으로 보인다. 정규식 re2 엔진을 사용할 수 있다고 문서에 나와있는데, 매칭은 테스트해보니 동작하지만 not 조건은 문법 에러로 ingress 자체가 생성이 안되었다. (참고 문서 링크)