Kubernetes: AWS ALB Ingress Controller — добавление редиректа на другой домен

Автор: | 10/07/2020
 

Имеется приложение двух версий — старое и новое, и два домена — старый, и новый.

Работает  в AWS Elastic Kubernetes Service, за AWS LoadBalancer, который создаётся из AWS ALB Ingress Controller.

Задача — добавить редирект на LoadBalancer со старого домена на новый:

  • старый: dev.api.old-example.com
  • новый: dev.api.new-example.com

В самом AWS LoadBalancer это делается через Listener Rules, в случае с Kubernetes AWS ALB Ingress Controller — используем Ingress annotations, которые потом применятся к листенеру.

Сейчас Ingress ресурс старого приложения выглядит так:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig":
      { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-2:534***385:certificate/2811e48b-***-971272859a74
    alb.ingress.kubernetes.io/healthcheck-path: /is-running
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/load-balancer-attributes: access_logs.s3.enabled=true,access_logs.s3.bucket=access-logs-eksdev1,access_logs.s3.prefix=apps
    alb.ingress.kubernetes.io/scheme: internet-facing
    kubernetes.io/ingress.class: alb
...
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: ssl-redirect
          servicePort: use-annotation
        path: /*
      - backend:
          serviceName: apps-backend-svc
          servicePort: 80
        path: /*

И Listener 443 порта отправляет трафик на AWS TargetGroup с Kubernetes WorkerNodes:

Добавляем новую аннотацию, в которой описываем 301 редирект на домен dev.api.new-example.com:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/actions.redirect-to-quiz: '{"Type":"redirect","RedirectConfig":{"Host":"dev.api.new-example.com","Path":"/#{path}","Port":"443","Protocol":"HTTPS","Query":"#{query}","StatusCode":"HTTP_301"}}'
...

Далее, обновляем spec.rules.

Вместо редиректа на Service бекенда, который в свою очередь отправляет трафик к подам со старым приложением:

...
      - backend:
          serviceName: apps-backend-svc
          servicePort: 80
        path: /*
...

Указываем использование аннотации, которую добавили выше:

...
      - backend:
          serviceName: redirect-to-quiz
          servicePort: use-annotation
        path: /*
...

Сохраняем, проверям Lisneter 443 порта ещё раз:

И проверяем работу редиректа:

curl -LvI https://dev.api.old-example.com
...
< HTTP/2 301
HTTP/2 301
< server: awselb/2.0
server: awselb/2.0
...
< location: https://dev.api.new-example.com:443/
location: https://dev.api.new-example.com:443/
<
* Connection #0 to host dev.api.old-example.com left intact
* Issue another request to this URL: 'https://dev.api.new-example.com:443/'
*   Trying 3.***.***.151:443...
* Connected to dev.api.new-example.com (3.***.***.151) port 443 (#1)
...

Редирект работает, готово.