aws eks(k8s) ingress path regex 동작 문제

# aws eks(elastic kubernetes service) 에 ingress controller 를 설치했다.
# nginx-ingress controller 는 아래 설명처럼 nginxinc 를 설치했다. 

# 참고로 nginx controller 는 크게 2종류가 있다.
# kubernetes 에서 개발한 kubernetes/ingress-nginx
# nginx 에서 개발한 nginxinc/kubernetes-ingress with NGINX
# 모두 nginx 기반으로 하고 약간의 차이가 있다.

# ingress 설정은 다음과 같이 (.*) regexp(정규식) 매칭을 사용했다.
# 정규식의 capture group-> 보통 () 로 구분되는 그룹,
# (.*) 하나만 있어 $1 (첫번째 캡쳐 그룹)을 rewrite 대상으로
# 백엔드 서비스에 넘겨주는 의도다. 
# 만약 ysoftman/(/|$)(.*) 라면
# (/|$) -> $1
# (.*) -> $2 
# 가 placeholder 가 된다.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: path-ingress
annotations:
  nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
  - host: "*.amazonaws.com"
      paths:
      - path: /ysoftman/(.*)
        backend:
          serviceName: ysoftman-service
          servicePort: 8080

# 그런데 다음과 같이 요청하면 nginx 404 응답을 준다.
# 참고로 path를 / 나 /ysoftman 처럼 고정된 경로를 주면 동작한다.
curl "https://aaa-bbb-ccc.amazonaws.com/ysoftman/abc"
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

# nginx controller pod 의 로그를 보면 다음과 같은 에러 후 404로 응답한다.
/etc/nginx/html/ysoftman/abc" failed (2: No such file or directory)

# nginxinc 문서를 보니 ingress path 에 정규식이 사용되지 않고 있고,
# path 에 정규식을 지원한다고 명시도 되어 있지 않다.
# 대신 nginxinc ingress controller는 virtualServer 라는 새로운 loadbalancer 리소스도 제공하고 여기서 정규식을 사용할 수 있다.

# 그래서 nginxinc nginx-ingress controller 은 모두 삭제
kubectl delete namespace nginx-ingress
kubectl delete clusterrole nginx-ingress
kubectl delete clusterrolebinding nginx-ingress


# kubernetes nginx-ingress controller for AWS 를 설치
# NETWORK LOAD BALANCER (NLB) 설치
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.46.0/deploy/static/provider/aws/deploy.yaml

# 참고로 nginx controller pod 에러가 다음과 같이 발생하면 ingressclass 리소스를 삭제해야 한다.
Invalid IngressClass (Spec.Controller) value "quivr.be/ingress-nginx-controller". Should be "k8s.io/ingress-nginx"
IngressClass with name nginx is not valid for ingress-nginx (invalid Spec.Controller)

# external-ip 확인
# xxxxx-xxxxx.elb.ap-northeast-2.amazonaws.com
kubectl get svc --namespace ingress-nginx

# kubernetes ingress-nginx 는 path 에서 (.*)등의 정규식은 지원하지만
# host 명은 지원하지 않는다.
# 다음과 같이 호스명은 full hostname 으로 명시해야 하고
# path 에는 정규식을 사용할 수 있다.
  rules:
  - host: "xxxxx-xxxxx.elb.ap-northeast-2.amazonaws.com"
      paths:
      - path: /ysoftman/(.*)
        backend:
          serviceName: ysoftman-service
          servicePort: 8080

# 이제 ingress path 정규식에 맞다면 200 OK 응답을 받는다.
curl "https://xxxxx-xxxxx.elb.ap-northeast-2.amazonaws.com/ysoftman/abc"

comments:

댓글 쓰기