NGINX Ingress Controller Annotation rewrite, response header 설정
이 포스트는 NGINX Ingress Controller Annotation 설정을 통해 보다 심화된 기능인 request rewrite 기능과 추가 response header를 삽입하는 방법에 대해 설명합니다.
목차
1. NGINX Ingress Controller Annotation이란?
2. Deployment, service 사전 구성
3. NGINX Ingress Controller Annotation rewrite 설정
4. NGINX Ingress Controller Annotation 추가 response header 설정
1. NGINX Ingress Controller Annotation이란?

NGINX Ingress Controller의 annotation 설정은 Ingress 리소스의 고급 설정을 사용할 수 있게 합니다.
Ingress 리소스는 NGINX의 기본적인 기능인 host/path 기반 라우팅, TLS termination만을 지원하고, request rewrite나 추가 response header 삽입과 같은 고급 설정은 지원하지 않습니다.
하지만 NGINX Ingress Controller의 Ingress 리소스에 annotation을 추가하면 connection timeout 값을 추가하는 등의 고급 설정을 사용할 수 있습니다.
이러한 설정들은 ConfigMap을 통해서도 지원하지만, annotation 설정이 우선됩니다.
Annotation 설정에 대해 보다 자세한 내용을 여기를 참조하세요.
2. Deployment, service 사전 구성
NGINX Ingress Controller Annotation 설정에 앞서 NGINX Ingress Controller를 통해서 라우팅 될 backend1, backend2의 deployment, 서비스를 다음과 같이 구성하였습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend1
spec:
replicas: 2
selector:
matchLabels:
app: backend1
template:
metadata:
labels:
app: backend1
spec:
containers:
- name: backend1
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: backend1-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: backend1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend2
spec:
replicas: 1
selector:
matchLabels:
app: backend2
template:
metadata:
labels:
app: backend2
spec:
containers:
- name: backend2
image: nginxdemos/nginx-hello:plain-text
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: backend2-svc
labels:
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
name: http
selector:
app: backend2
컨테이너의 서버는 200 코드와 함께 서버 주소, 서버 이름, 요청 시간, 요청 URI, 요청 ID를 반환합니다.
server {
listen 8080;
listen [::]:8080;
location / {
default_type text/plain;
expires -1;
return 200 'Server address: $server_addr:$server_port\nServer name: $hostname\nDate: $time_local\nURI: $request_uri\nRequest ID: $request_id\n';
}
}
생성된 pod와 서비스는 다음과 같습니다.
# kubectl get pod,service
NAME READY STATUS RESTARTS AGE
pod/backend1-584b5f78fb-bcc4f 1/1 Running 0 29s
pod/backend1-584b5f78fb-zrdtl 1/1 Running 0 29s
pod/backend2-7464c479f8-rpg62 1/1 Running 0 29s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/backend1-svc ClusterIP 10.102.194.233 <none> 80/TCP 29s
service/backend2-svc ClusterIP 10.107.124.18 <none> 80/TCP 29s
Kubernetes 클러스터 외부에서 Ingress Controller를 통해 클러스터 내부의 서비스에 접근하기 위해 NodePort 서비스를 배포합니다.
# kubectl apply -f nodeport.yaml
배포 중인 Ingress controller의 NodePort 서비스를 확인합니다.
# kubectl get svc -n nginx-ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress NodePort 10.102.97.200 <none> 80:30348/TCP,443:32253/TCP 15m
30348 포트로 http 요청을 수신함을 확인할 수 있습니다.
2. NGINX Ingress Controller Annotation rewrite 설정
Ingress 파일의 annotations를 통해 rewrite 설정을 구성합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/rewrites: "serviceName=backend1-svc rewrite=/;serviceName=backend2-svc rewrite=/test/"
name: ingress-rewrite
spec:
rules:
- host: example.com
http:
paths:
- path: /backend1/
pathType: Prefix
backend:
service:
name: backend1-svc
port:
number: 80
- path: /backend2/
pathType: Prefix
backend:
service:
name: backend2-svc
port:
number: 80
- annotations 항목에 nginx.org/rewrites 설정을 추가합니다
- “serviceName=<서비스명> rewrite=<rewrite 내용>” 형식으로 rewrite 설정을 작성합니다.
위와 같이 설정 시 다음과 같이 적용됩니다.
- /backend1/ 요청의 URI를 /로 rewrite합니다
- /bakcend2/ 요청의 URI를 /test/로 rewrite합니다
- /backend1 요청은 /backend1/ 요청으로 redirect됩니다
- /backend2 요청은 /backend2/ 요청으로 redirect됩니다
작성한 Ingress 파일을 배포하고 확인합니다.
# kubectl apply -f rewrite.yaml
# kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-rewrite <none> example.com 80 3m14s
example.com/backend1과 example.com/backend2로 요청을 보내 rewrite 설정을 확인합니다.
# curl example.com:30348/backend1/hello
Server address: 10.244.1.34:8080
Server name: backend1-584b5f78fb-zrdtl
Date: 09/Apr/2024:07:36:39 +0000
URI: /hello
Request ID: 4e358f781161955642bda8e17705e8ec
# curl example.com:30348/backend2/hello
Server address: 10.244.1.33:8080
Server name: backend2-7464c479f8-rpg62
Date: 09/Apr/2024:07:37:01 +0000
URI: /test/hello
Request ID: ada22f6e0d67c59e8ab64e4a4f74ef52
example.com/backend1/hello 요청에 대해 URI가 /hello로 rewrite되고,
example.com/backend2/hello 요청에 대해 URI가 /test/hello로 rewrite됨을 확인할 수 있습니다.
3. NGINX Ingress Controller Annotation response header 설정
response header를 추가하기 위해서는 annotations에 snippets 설정이 필요합니다.
기본적으로 NGINX Ingress Controller 설정에서 snippets는 비활성화되어 있기 때문에, deployment 파일의 설정을 통해 활성화해야 합니다.
# vi ingress-snippets.yaml
apiVersion: apps/v1
kind: Deployment
......
spec:
template:
spec:
args:
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -enable-snippets # snippets 활성화 구문 추가
수정된 deployment 파일을 통해 snippets 설정이 활성화된 NGINX Ingress Controller를 재배포합니다.
# kubectl apply -f ingress-snippets.yaml
Ingress 파일의 annotation항목에 location-snippets를 설정하여 response header을 추가합니다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/location-snippets: |
add_header Custom-Header my-header;
name: ingress-header
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend1-svc
port:
number: 80
- annotations 항목에 nginx.org/location-snippets 설정을 추가합니다.
- add_header <헤더 이름> <헤더 내용> 형식으로 작성합니다.
example.com으로 요청을 전송할 때, 헤더에 Custom-Header 헤더 이름의 my-header 헤더 내용으로 헤더가 추가되도록 설정했습니다.
배포한 Ingress 파일을 확인합니다.
# kubectl get ingress ingress-header
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-header <none> example.com 80 24m
설정한 서비스에 요청 시, 설정한 request header을 반환하는 것을 확인할 수 있습니다.
# curl -I example.com:30348
HTTP/1.1 200 OK
Server: nginx/1.25.3
Date: Tue, 09 Apr 2024 06:56:50 GMT
Content-Type: text/plain
Content-Length: 157
Connection: keep-alive
Expires: Tue, 09 Apr 2024 06:56:49 GMT
Cache-Control: no-cache
Custom-Header: my-header # 설정한 header가 반환됨
아래 폼을 통해 NGINX Plus Ingress Controller Trial 라이선스를 신청해보세요!
댓글을 달려면 로그인해야 합니다.