NGINX Plus Ingress Controller + Prometheus+ Grafana 통합 가이드

현대적인 애플리케이션 환경에서는 가용성과 성능을 보장하기 위해 다양한 모니터링 솔루션이 필요합니다. 특히, Kubernetes 환경에서 Ingress Controller의 상태를 효과적으로 모니터링하는 것은 서비스 운영의 핵심 요소 중 하나입니다. 본 가이드에서는 NGINX Plus Ingress ControllerPrometheus, Grafana를 통합하여 실시간으로 트래픽을 모니터링하고 분석하는 방법을 다룹니다. 이를 통해 운영자는 서비스의 상태를 한눈에 파악하고, 문제 발생 시 빠르게 대응할 수 있습니다.

목차

1. 환경 구성
2. NGINX Plus Ingress Controller 배포
3. Prometheus 배포 및 NGINX Plus Ingress Controller와 연동
4. Grafana 배포 및 Prometheus 연동
5. 결론

1. 환경 구성

  • kubernetes : v1.32.2

2. NGINX Plus Ingress Controller 배포

해당 Prometheus Metrics은 NGINX Ingress Controller의 상업적 제품인 NGINX Plus Ingress Controller에서 지원하고 있습니다.

NGINX Ingress Controller를 배포하기 위해서 먼저 nginx github에서 NGINX Ingress Controller Repository를 Clone합니다.

$ git clone https://github.com/nginx/kubernetes-ingress.git --branch <version_number>

위와 같이 kubernetes-ingress 디렉토리가 생성 된 것을 확인할 수 있습니다.

디렉토리로 이동하여 NGINX Plus Ingress를 배포하기 전 필수 리소스를 배포합니다.

$ cd kubernetes-ingress
$ kubectl apply -f deployments/common/ns-and-sa.yaml
$ kubectl apply -f deployments/rbac/rbac.yaml
$ kubectl apply -f deployments/common/ingress-class.yaml
$ kubectl apply -f config/crd/bases/k8s.nginx.org_virtualservers.yaml
$ kubectl apply -f config/crd/bases/k8s.nginx.org_virtualserverroutes.yaml
$ kubectl apply -f config/crd/bases/k8s.nginx.org_transportservers.yaml
$ kubectl apply -f config/crd/bases/k8s.nginx.org_policies.yaml
$ kubectl apply -f config/crd/bases/k8s.nginx.org_globalconfigurations.yaml

위와 같이 배포 이후 Deployment, Service를 배포합니다.

배포하기 전 NGINX Plus Ingress Controller에서 prometheus의 메트릭을 내보내기 위한 구성을 진행합니다. ( Pod의 갯수는 3개로 지정하였습니다. WorkerNode 3개 사용)

(이미지는 NGINX Plus Ingress Controller 의 이미지를 사용하였습니다. NGINX Plus Ingress Controller의 이미지는 NGINX Plus Ingress Controller 이미지 빌드 에서 확인할 수 있습니다.)

# kubernetes-ingress/deployments/deployment/deployment.yaml
...
  template:
    metadata:
      labels:
        app: nginx-ingress
        app.kubernetes.io/name: nginx-ingress
      annotations:
        prometheus.io/scrape: "true" # Prometheus Annotations 주석 해제 
        prometheus.io/port: "9113"   # Prometheus Annotations 주석 해제 
        prometheus.io/scheme: http   # Prometheus Annotations 주석 해제 
    spec:
      serviceAccountName: nginx-ingress
      automountServiceAccountToken: true
      securityContext:
        seccompProfile:
          type: RuntimeDefault
...
        args:
          - -nginx-plus
          - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
          - -mgmt-configmap=$(POD_NAMESPACE)/nginx-config-mgmt
          - -report-ingress-status
          - -external-service=nginx-ingress
          - -enable-prometheus-metrics # Prometheus Metric 주석 해제 
         #- -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
         #- -enable-cert-manager
         #- -enable-external-dns
...

NGINX Plus Ingress Controller가 배포된 것을 확인할 수 있습니다.

Service를 구성하여 NGINX Plus Ingress Controller에 접속할 수 있도록 수정하여 배포합니다.

# kubernetes-ingress/deployments/service/nodeport.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP 
    name: http
  - port: 443 
    targetPort: 443 
    protocol: TCP 
    name: https
  - port: 9113
    targetPort: 9113    # Prometheus Metrics 전용 포트 추가 
    protocol: TCP
    name: prometheus      
  selector:
    app: nginx-ingress

모두 배포된 것을 확인할 수 있습니다.

Prometheus Metrics 전용 Port로 접속하여 NGINX Plus Ingress Controller의 메트릭을 확인합니다.

<Kubernetes Controle Plane IP>:<NGINX Plus Ingress Controller Prometheus NodePort>/metrics

위의 메트릭을 Prometheus와 연동합니다.

3. Prometheus 배포 및 NGINX Plus Ingress Controller와 연동

Prometheus를 k8s 환경에 배포합니다.

먼저 ConfigMap을 구성하여 NGINX Plus Ingress Controller의 메트릭을 수집할 수 있도록 구성합니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-server-conf
data:
  prometheus.yml: |
    global: 
      scrape_interval: 10s 
    scrape_configs: 
      - job_name: 'nginx-plus-ingress-controller-target' 
        kubernetes_sd_configs: 
          - role: pod  
        relabel_configs: 
          - source_labels: [__meta_kubernetes_namespace]
            action: keep
            regex: nginx-ingress 
          - source_labels: [__meta_kubernetes_pod_label_app] 
            action: keep 
            regex: nginx-ingress    
          - source_labels: [__meta_kubernetes_pod_container_name] 
            action: keep 
            regex: nginx-plus-ingress 
          - source_labels: [__meta_kubernetes_namespace] 
            target_label: namespace 
          - source_labels: [__meta_kubernetes_pod_name] 
            target_label: pod 
          - source_labels: [__meta_kubernetes_pod_container_port_number]
            action: keep
            regex: 9113
        metrics_path: /metrics

Deployment와 Service를 배포하기 전 Prometheus와 NGINX Plus Ingress Controller가 배포된 Namespace가 다르기 때문에 ServiceAccount를 생성하여 다른 Namespace에 있는 Pod에 접근할 수 있도록 권한을 설정합니다.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: npic-prometheus-cluster-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: npic-prometheus-pod-metrics-role
subjects:
- kind: ServiceAccount
  name: npic-prometheus-sa
---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: npic-prometheus-pod-metrics-role
rules:
- apiGroups: [""]
  resources:  Kubernetes Resource중 모든 NS에 있는 Pods에 접근할 수 있도록 구성합니다.
  - pods
  verbs:
  - get
  - list
  - watch

---

apiVersion: v1
kind: ServiceAccount
metadata:
  name: npic-prometheus-sa

Deployment와 Service를 배포합니다.

apiVersion: v1
kind: Service
metadata:
  name: prometheus-service
spec:
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9090
  selector:
    app: prometheus-server

---

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus-server
  template:
    metadata:
      labels:
        app: prometheus-server
    spec:
      serviceAccountName: npic-prometheus-sa # 위에서 구성했던 Service Account를 Deployment에 지정하여 권한을 넣습니다.
      containers:
        - name: prometheus
          image: prom/prometheus
          ports:
            - containerPort: 9090
          volumeMounts: # 위에서 구성했었던 ConfigMap을 사용할 수 있도록 구성합니다.
            - name: config-volume
              mountPath: /etc/prometheus
      volumes:
        - name: config-volume
          configMap: # 위에서 구성했었던 ConfigMap을 사용할 수 있도록 구성합니다.
            name: prometheus-server-conf
            defaultMode: 420

배포가 완료되게 되면 아래와 같이 Prometheus에 접속할 수 있게 됩니다.

위에서 구성했었던 NGINX Plus Ingress Controller의 Pod가 Target이 된 것을 확인할 수 있습니다.

NGINX Plus Ingress Controller 의 Metric도 확인할 수 있습니다.

4. Grafana 배포 및 Prometheus 연동

grafana를 k8s 환경에 배포하여 사용합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
  labels:
    app: grafana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
        - name: grafana
          image: grafana/grafana:latest
          ports:
            - containerPort: 3000
          env:
            - name: GF_SECURITY_ADMIN_PASSWORD # password를 admin으로 지정합니다(예시)
              value: "admin"
---
apiVersion: v1
kind: Service
metadata:
  name: grafana-service
  namespace: monitoring
spec:
  selector:
    app: grafana
  ports:
    - protocol: TCP 
      port: 80
      targetPort: 3000
  type: NodePort 

NodePort로 배포하였기 때문에 NodePort를 통해 접속합니다.

위에서 지정했었던 Grafana의 password로 admin 계정에 접근합니다.

Data Source를 추가하여 구성했었던 Prometheus의 메트릭을 받습니다.

Prometheus를 선택합니다.

Prometheus의 URL을 prometheus 서비스의 kubedns url을 적습니다.

[service name].[name space].[kind].cluster.local

Prometheus Data Source를 추가합니다.

Dashboard로 이동하여 NGINX Plus Ingress Controller의 Grafana Dashboard를 가져옵니다.

NGINX Plus Ingress Controller의 Dashboard는 github 파일에 kubernetes-ingress/grafana/NGINXPlusICDashboard.json에 있습니다.

Data Source를 아까 추가했었던 Prometheus를 추가합니다.

NGINX Plus Ingress Controller의 Grafana Dashboard를 확인할 수 있습니다.

5. 결론

NGINX Plus Ingress ControllerPrometheus, Grafana를 활용하여 Kubernetes 환경에서 효과적인 모니터링 시스템을 구축하는 방법을 살펴보았습니다. Prometheus를 이용해 Ingress Controller의 다양한 메트릭을 수집하고, Grafana를 통해 이를 시각화하여 보다 직관적인 대시보드를 제공할 수 있음을 확인했습니다. 이러한 통합 모니터링 환경은 시스템 성능을 최적화하고 장애 대응 시간을 단축하는 데 큰 도움이 됩니다.

NGINX Ingress Controller와 관련된 더 많은 정보를 알고싶으시다면 NGINX STORE Kubernetes 카테고리를 방문해주세요.

NGINX STORE를 통한 솔루션 도입 및 기술지원 무료 상담 신청

* indicates required