NGINX Plus Sidecar Proxy, Kubernetes 클러스터에 구성 가이드
이 블로그 포스트에서는 NGINX Plus 컨테이너를 sidecar proxy 로 구성하고, Kubernetes 클러스터에 백엔드 컨테이너와 함께 배포하여 NGINX Plus API를 통해 모니터링하는 방법을 설명합니다.
Kubernetes 배포에 사용할 NGINX Plus 이미지를 준비하는 방법과, ConfigMap을 활용하여 NGINX Plus 컨테이너의 설정을 구성하는 방법, 실제로 NGINX Plus를 sidecar proxy로 구성해 deployment로 배포하는 방법을 예제와 함께 알아도록 하겠습니다. 마지막으로 해당 deployment를 통해 배포된 pod에 NodePort service를 통해 접근하고, 모니터링 대시보드를 확인해 보도록 하겠습니다.
이 포스트의 예제는 Kubernetes 1.30.3 버전에서 진행되었으며, default 네임스페이스에 리소스를 배포하여 진행했습니다.
목차
1. NGINX Plus Sidecar Proxy란?
2. NGINX Plus 이미지 준비
3. NGINX Plus Sidecar Proxy 구성
3-1. Kubernetes Secret 생성
3-2. ConfigMap 생성
3-3. NGINX Plus Sidecar Proxy 포함 Deployment 배포
3-4. NGINX Plus Sidecar Proxy API 모니터링
4.결론
1. NGINX Plus Sidecar Proxy 란?

NGINX Plus Sidecar Proxy는 Kubernetes의 pod에 백엔드 컨테이너와 함께 배포되는 NGINX Plus 컨테이너입니다. 해당 pod는 NGINX Plus 컨테이너를 통해 요청을 수신하고, 해당 요청을 백엔드 컨테이너로 프록시하도록 동작합니다. NGINX Plus 컨테이너를 통해 sidecar proxy를 구성함에 따라, NGINX Plus API를 통해서 모니터링 할 수 있고, NGINX Prometheus Exporter와 함께 구성 시 프로메테우스를 통해 모니터링하도록 구성할 수 있습니다.
2. NGINX Plus 이미지 준비
NGINX Plus Sidecar Proxy 구성을 위해선 NGINX Plus 이미지를 준비해야 합니다. 이 포스트에서는 공식 NGINX Plus Docker 레지스트리에서 이미지를 pull 한 후, 개인 Docker Hub 리포지토리로 push 하는 방식으로 진행합니다.
Dockerfile을 통해 이미지를 직접 빌드하는 방법은 Docker에 NGINX 및 NGINX Plus 배포 문서의 2-1. NGINX Plus Docker 이미지 만들기 항목을 참고하세요.
1. NGINX Plus 구독 라이센스의 jwt 파일을 통해 NGINX Plus 컨테이너 레지스트리와 통신하도록 설정합니다.
$ docker login private-registry.nginx.com --username=`cat nginx-repo.jwt` --password=none
Login Succeeded
해당 명령어를 nginx-repo.jwt 파일이 존재하는 디렉토리에서 사용하거나, username의 값(`cat nginx-repo.jwt`)을 nginx-repo.jwt 파일의 내용으로 대체하여 명령어를 사용합니다.
2. NGINX Plus 이미지를 pull 합니다.
$ docker pull private-registry.nginx.com/nginx-plus/base:<버전 태그>
예제에서는 r32 버전을 사용했습니다.
$ docker pull private-registry.nginx.com/nginx-plus/base:r32
r32: Pulling from nginx-plus/base
efc2b5ad9eec: Pull complete
fa87451535c6: Pull complete
Digest: sha256:02ff65688322151e7ded0f43c81321d8ed7a8808af685d0fddb3203b42b066e2
Status: Downloaded newer image for private-registry.nginx.com/nginx-plus/base:r32
private-registry.nginx.com/nginx-plus/base:r32
3. 개인 Docker Hub 계정에 로그인합니다.
$ docker login
Login Succeeded
4. 앞서 pull 한 이미지를 개인 Dokcer Hub 리포지토리로 push 하기 위해 tag를 변경합니다.
$ docker tag private-registry.nginx.com/nginx-plus/base:<버전 태그> <개인 Docker Hub 리포지토리>:<지정 태그>
예제의 경우 nginxstore 유저의 nginxplus 리포지토리(nginxstore/nginxplus)가 구성되어있다 가정하고 진행됩니다.
$ docker tag private-registry.nginx.com/nginx-plus/base:r32 nginxstore/nginxplus:nginx-plus
앞서 pull 한 r32 태그의 이미지를, nginx-plus 태그로 지정했습니다.
5. 이미지를 개인 Docker Hub 리포지토리로 push 합니다. 해당 이미지를 공개 리포지토리로 push 하지 않도록 주의합니다. (라이센스 계약 위반)
$ docker push nginxstore/nginxplus:nginx-plus

Docker Hub에 로그인하여 push 한 리포지토리에서 위와 같이 확인할 수 있습니다.
3. NGINX Plus Sidecar Proxy 구성
개인 Docker Hub 리포지토리에 준비한 NGINX Plus 이미지를 활용하여, NGINX Plus 컨테이너를 sidecar proxy로 구성하고 백엔드 컨테이너와 함께 deployment로 배포하겠습니다.
예제에 사용된 yaml 파일들은 NGINX STORE GitHub 리포지토리에서 확인하실 수 있습니다.
3-1. Kubernetes Secrert 생성
Kubernetes에서 pod를 배포할 때, 공개 리포지토리가 아닌, private 리포지토리에서 이미지를 pull 하기 위해선 Kubernetes의 secret 리소스가 필요합니다.
1. 개인 Docker Hub의 private 리포지토리에서 이미지를 pull 하기 위해, secret을 생성합니다.
$ kubectl create secret generic docker-secret --from-file=.dockerconfigjson=<docker config.json 파일 경로> --type=kubernetes.io/dockerconfigjson
secret/docker-secret created
docker config.json 파일의 경우 앞서 이미지를 push 하기 위해 docker login을 실행한 유저의 홈 디렉토리의 docker/config.json 에 위치합니다.
/root/.docker/config.json # root 유저의 경우
/home/nginxstore/.docker/config.json # nginxstore 유저의 경우
2. 정상적으로 생성 시 다음과 같이 확인할 수 있습니다.
$ kubectl get secrets
NAME TYPE DATA AGE
docker-secret kubernetes.io/dockerconfigjson 1 5s
3-2. ConfigMap 생성
NGINX Plus Sidecar Proxy 컨테이너의 NGINX 설정 파일 관리를 위해 ConfigMap을 생성합니다.
1. NGINX의 설정 파일 내용을 담은 yaml파일을 작성합니다.
# nginx-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-conf
data:
nginx.conf: |
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
default.conf: |
upstream tomcat { # 모니터링을 위한 upstream 설정
zone tomcat 32k;
server localhost:8080; # 프록시 설정
}
server {
listen 80;
#access_log /var/log/nginx/host.access.log main;
location / {
proxy_pass http://tomcat; # upstream(tomcat)으로 프록시
status_zone backend; # 모니터링을 위한 status_zone 설정
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
metric.conf: |
server {
listen 9113;
location /api { # NGINX Plus API 설정
api write=on;
}
location = /dashboard.html { # 대시보드 설정
root /usr/share/nginx/html;
}
}
위 ConfigMap 리소스는 NGINX 구성 파일인 nginx.conf, default.conf, metric.conf 파일의 데이터를 담고 있습니다.
위 설정에 따르면 NGINX Plus 컨테이너는 80번 포트를 통해 요청을 8080 포트로 프록시하고, 9113 포트를 통해 NGINX Plus API를 활성화하고, 모니터링 대시보드에 접근할 수 있도록 설정합니다.
실제 구성 시 백엔드 컨테이너의 포트 설정에 따라, 프록시 되는 8080 포트를 변경하여 사용합니다.
2. 명령어를 통해 ConfigMap 리소스를 생성하고, 확인합니다.
$ kubectl apply -f nginx-cm.yaml
configmap/nginx-conf created
# cm은 configmap 리소스의 약자
$ kubectl get cm nginx-conf
NAME DATA AGE
nginx-conf 3 31s
정상적으로 3개의 설정 파일 데이터를 포함하고 있는 것을 확인할 수 있습니다.
3. 백엔드 컨테이너로 사용할 Tomcat 컨테이너의 index.html 파일을 ConfigMap으로 생성합니다.
# tomcat-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: tomcat-index
data:
index.html: |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to Tomcat</title>
<style>
body { font-family: Arial, sans-serif; line-height: 1.6; padding: 20px; }
h1 { color: #333; }
.container { max-width: 800px; margin: 0 auto; }
</style>
</head>
<body>
<div class="container">
<h1>Welcome to Tomcat</h1>
<p>This is a custom welcome page for your Tomcat server.</p>
<p>Your application is running successfully!</p>
</div>
</body>
</html>
$ kubectl apply -f tomcat-cm.yaml
configmap/tomcat-index created
3-3. NGINX Plus Sidecar Proxy 포함 Deployment 구성
NGINX Plus Sidecar Proxy Kubernetes 컨테이너 구성을 위한 pod의 yaml 파일 예제는 다음과 같습니다.
실제 배포는 백엔드 컨테이너와 함께 deployment로 배포됩니다.
apiVersion: v1
kind: Pod
metadata:
labels:
app: nginx
name: nginx-plus
spec:
imagePullSecrets: # 생성한 secret 지정
- name: docker-secret
containers:
- image: nginxstore/nginxplus:nginx-plus # 개인 Docker Hub 리포지토리 이미지 지정
name: nginx-proxy
ports:
- containerPort: 80
- containerPort: 9113
volumeMounts:
- name: nginx-conf # 하단에 명시한 volume 이름 지정
mountPath: /etc/nginx/nginx.conf # 컨테이너 내부에 마운트할 디렉토리 지정
subPath: nginx.conf # ConfigMap 내부의 데이터 지정
- name: nginx-conf
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
- name: nginx-conf
mountPath: /etc/nginx/conf.d/metric.conf
subPath: metric.conf
volumes:
- name: nginx-conf
configMap:
name: nginx-conf # 생성한 ConfigMap을 지정
- imagePullSecrets : 3-1 항목에서 생성한 secret을 통해 개인 리포지토리에서 이미지를 pull 합니다.
- image : Docker Hub 개인 리포지토리에 push 한 NGINX Plus 이미지를 사용합니다.
- volumes : 3-2 항목에서 생성한 ConfigMap을 volume으로 설정합니다.
- volumeMounts : ConfigMap의 데이터를 컨테이너 내부에 마운트합니다.
위 내용은 NGINX Plus 컨테이너의 예제로, sidecar proxy로 구성되기 위해서는 NGINX Plus 컨테이너가 백엔드로 구성될 컨테이너와 하나의 pod에 함께 구성되어야 합니다.
1. NGINX Plus 컨테이너와 백엔드 컨테이너(Tomcat)가 구성된 deployment의 yaml 파일을 작성합니다.
# nginx-tomcat.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: tomcat
name: nginx-tomcat
spec:
replicas: 1
selector:
matchLabels:
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
imagePullSecrets:
- name: docker-secret
containers:
- image: tomcat # 백엔드 컨테이너(Tomcat) 추가
name: tomcat
ports:
- containerPort: 8080 # NGINX Plus가 프록시 할 Tomcat의 포트
volumeMounts:
- name: tomcat-index # index.html 파일 마운트 설정
mountPath: /usr/local/tomcat/webapps/ROOT/index.html
subPath: index.html
- image: nginxstore/nginxplus:nginx-plus # NGINX Plus Sidecar Proxy 컨테이너
name: nginx-proxy
ports:
- containerPort: 80
- containerPort: 9113
volumeMounts:
- name: nginx-conf
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: nginx-conf
mountPath: /etc/nginx/conf.d/default.conf
subPath: default.conf
- name: nginx-conf
mountPath: /etc/nginx/conf.d/metric.conf
subPath: metric.conf
volumes:
- name: nginx-conf
configMap:
name: nginx-conf
- name: tomcat-index
configMap:
name: tomcat-index
실제 구성 시 image의 값을 개인 리포지토리의 이미지로 지정합니다.
2. 작성한 파일을 통해 deployment를 배포하고 확인합니다.
$ kubectl apply -f nginx-tomcat.yaml
deployment.apps/nginx-tomcat created
$ kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-tomcat 1/1 1 1 2m54s
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-tomcat-7658c8b88-wrfg9 2/2 Running 0 3m
pod 내부에 2개의 컨테이너(NGINX Plus, Tomcat)가 정상적으로 실행되어 2/2 상태임을 확인할 수 있습니다.
3. 생성된 pod로 연결하기 위한 service의 yaml 파일을 작성하고, 배포합니다.
# tomcat-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nginx-proxy
- port: 9113
targetPort: 9113
protocol: TCP
name: metric
selector:
app: tomcat
$ kubectl apply -f tomcat-svc.yaml
service/tomcat-svc created
$ kubectl get svc tomcat-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tomcat-svc ClusterIP 10.111.57.196 <none> 80/TCP,9113/TCP 8s
서비스를 통해 NGINX Plus 컨테이너의 프록시를 위한 80번 포트와 NGINX Plus API를 위한 9113 포트가 노출되었습니다.
3-4 . NGINX Plus Sidecar Proxy API 모니터링
현재 NGINX Plus + Tomcat pod는 ClusterIP service를 통해 클러스터 내부에 노출되어 외부에서는 접근이 불가능합니다. 예제에서는 클러스터 외부에서 해당 pod에 접근하기 위해, 간단하게 NodePort service를 활용해서 확인하도록 하겠습니다.
예제의 방법은 간단한 확인을 위한 방법으로, 실제 환경에선 Ingress Controller를 활용해서 접근하도록 설정하세요.
NGINX Ingress Controller를 활용하여 외부의 접근을 설정하는 방법은 NGINX Ingress Controller 라우팅 Host 및 Path 기반으로 설정 포스트를 참고하세요.
1. 기존에 배포한 service 리소스를 NodePort service로 변경하여 배포합니다
# tomcat-svc-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: tomcat-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
protocol: TCP
name: nginx-proxy
- port: 9113
targetPort: 9113
protocol: TCP
name: metric
selector:
app: tomcat
$ kubectl apply -f tomcat-svc-nodeport.yaml
service/tomcat-svc configured
$ kubectl get svc tomcat-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tomcat-svc NodePort 10.111.57.196 <none> 80:30354/TCP,9113:30683/TCP 31m
80번 포트는 30354번, 9113번 포트는 30683번 포트를 통해 노출된 것을 확인할 수 있습니다.
2. 노드의 IP를 통해 브라우저로 접근하여 확인합니다.
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP
master Ready control-plane 125d v1.30.3 192.168.200.171 <none>
worker Ready <none> 40d v1.30.3 192.168.200.91 <none>

Tomcat 컨테이너로 연결되어 ConfigMap으로 생성한 index.html 페이지를 확인할 수 있습니다.



30683 포트를 통해 /dashboard.html 경로로 접속 시, NGINX Plus API를 통한 모니터링 대시보드에 접근할 수 있습니다. nginx-conf ConfigMap의 default.conf 설정에 따라 tomcat upstream과 backend location zone을 확인할 수 있습니다.
3. 30683번 포트를 통해 요청을 전송하여, NGINX Plus API 기능을 활용할 수 있습니다.
/api/<api 버전>/<API 엔드포인트> 경로로 요청을 전송합니다.
$ curl -X GET 192.168.200.91:30683/api/9/nginx | jq .
{
"version": "1.25.5",
"build": "nginx-plus-r32",
"address": "10.244.2.112",
"generation": 1,
"load_timestamp": "2024-08-13T02:20:25.920Z",
"timestamp": "2024-08-13T02:36:23.600Z",
"pid": 10,
"ppid": 8
}
NGINX Plus API의 각 엔드포인트 및 사용 가능한 HTTP 메서드는 여기를 참고하세요. 이 페이지에서 API의 전체적인 구조와 요청 형식, 응답 형식을 상세히 확인할 수 있습니다.
4. 결론
이번 포스트에서는 NGINX Plus를 사이드카 프록시로 구성하는 방법을 예제를 통해 자세히 알아보았습니다. NGINX Plus 이미지를 개인 Docker Hub 리포지토리에 업로드하고, Kubernetes에 배포하는 방법부터 ConfigMap 리소스를 활용해 NGINX Plus 컨테이너의 설정 파일을 구성하는 과정까지 살펴보았습니다. 또한, NGINX Plus를 sidecar proxy로 구성하여 백엔드 컨테이너인 Tomcat과 함께 Deployment로 배포하고, NGINX Plus API를 통해 대시보드를 사용하여 모니터링하는 방법도 알아봤습니다.
이와 같은 방법으로 NGINX Plus를 사이드카 프록시로 구성해 백엔드 컨테이너의 요청을 프록시하고, NGINX Plus API를 활용해 실시간 모니터링을 구현할 수 있습니다.
예제와 같이 NGINX Plus를 sidecar proxy 컨테이너로 구성하고, NGINX Plus API를 통해 모니터링하고 싶으시다면 NGINX STORE를 통해 문의해 무료로 NGINX Plus trial을 체험해 보세요.
댓글을 달려면 로그인해야 합니다.