ingress-nginx 는 L7 프록시이며 요청의 Host 헤더로 어느 서비스에 보낼지 정한다. IP 로 접속하면 Host 헤더가 IP 가 되고, 그 값에 해당하는 규칙이 없으면 기본 백엔드가 404 를 돌려준다.
curl -I http://<INGRESS_IP>/
# HTTP/1.1 404 Not Found
curl -I -H "Host: app.example.com" http://<INGRESS_IP>/
# HTTP/1.1 200 OK
이 두 결과가 갈리면 라우팅 설정은 정상이고 접속 방법만 틀린 것이다. 즉 ingress-nginx 는 도메인으로 접속하는 것이 전제다.
# 1) 컨트롤러가 떠 있는지
kubectl -n ingress-nginx get pod,svc
# 2) 규칙이 등록됐는지. ADDRESS 가 비어 있으면 컨트롤러가 인식하지 못한 것이다
kubectl get ingress -A
kubectl describe ingress <name> -n <ns>
# 3) 백엔드 서비스와 엔드포인트
kubectl get svc,endpoints -n <ns>
# 4) 컨트롤러 로그
kubectl -n ingress-nginx logs -l app.kubernetes.io/component=controller --tail=100
describe ingress 의 Backends 항목이 <none> 이거나 엔드포인트가 비어 있으면 404 가 아니라 503 이 나오는 경우가 많다. 그쪽은 ingress-nginx 503 진단 을 본다.
컨트롤러가 담당하는 클래스와 Ingress 리소스가 지정한 클래스가 다르면 규칙이 적용되지 않는다. 이 경우 Ingress 의 ADDRESS 가 비어 있다.
kubectl get ingressclass
kubectl get ingress <name> -n <ns> -o jsonpath='{.spec.ingressClassName}{"\n"}'
spec:
ingressClassName: nginx
예전 애너테이션(kubernetes.io/ingress.class)은 더 이상 쓰지 않는다. spec.ingressClassName 으로 지정한다.
spec:
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app
port:
number: 80
브라우저가 app.example.com 으로 접속해야 한다. DNS 가 없으면 hosts 파일에 컨트롤러 주소를 매핑한다.
20.30.40.50 app.example.com
*.example.com 같은 와일드카드는 hosts 파일로 처리되지 않는다. 서브도메인을 여러 개 쓰려면 사내 DNS 에 등록한다.
pathType: Exact 는 완전히 같은 경로만 받는다. 하위 경로까지 받으려면 Prefix 다.
백엔드가 루트가 아닌 경로에 있으면 재작성이 필요하다.
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: app.example.com
http:
paths:
- path: /app(/|$)(.*)
pathType: ImplementationSpecific
rewrite-target 을 쓸 때는 정규식 그룹과 pathType 을 함께 맞춰야 한다. 그렇지 않으면 정적 자원만 404 가 나는 형태로 나타난다.
시험 목적이라면 host 없는 규칙을 둔다. 이 규칙은 매칭되는 host 규칙이 없을 때 적용된다.
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app
port:
number: 80
운영에서는 권장하지 않는다. 이름 기반 분기가 없어 여러 서비스를 붙일 수 없고, TLS 인증서도 이름이 있어야 의미가 있다.
한 서비스만 노출하면 되는 상황이라면 Ingress 대신 Service 를 LoadBalancer · NodePort 로 여는 편이 단순하다.
어떤 규칙에도 걸리지 않은 요청은 기본 백엔드로 간다. 무엇이 응답했는지 구분하려면 응답 본문을 본다. ingress-nginx 의 기본 404 페이지가 나오면 컨트롤러까지는 도달한 것이고, 아무 응답이 없으면 그 앞(LB · 방화벽)에서 끊긴 것이다.
curl -sv http://<INGRESS_IP>/ 2>&1 | egrep 'HTTP/|server:'