본문 바로가기
Docker-k8s

Nginx Ingress Controller를 이용하여 kube-prometheus-stack으로 배포한 prometheus, grafana 접속하기

by 간식주인 2024. 7. 11.

요건

 - 관리형 쿠버네티스에서 kube-prometheus-stack 으로 배포한 프로메테우스와 그라파나를 ingress로 접속

 - value.yaml를 통해 프로메테우스, 그라파나의 ingress를 생성할 수 있지만, 관리 포인트를 줄이기 위해 1개의 사용자 정의 ingress.yaml을 생성하여 path를 통해 관리(/grafana, /prometheus)

 

환경

  • Naver Cloud Platform Kubernetes Service 1  Cluster(Node 1 - 2Core/4GB Ram)

목차

  1. NCP 관리형 쿠버네티스 생성
  2. NCP 관리형 쿠버네티스 클러스터에 Nginx Ingress Controller 설치
  3. helm 설치 및 kube-prometheus-stack을 이용하여 prometheus, grafana 설치
  4. ingress.yaml 배포 및 접속 테스트 

주의 사항

- nginx ingress controller 설치 후 Cloud Controller Manager에 의해 로드밸런서가 생성되어야하기 때문에 CSP에서 제공하는 관리형 쿠버네티스를 사용해야 합니다.

- kube-prometheus-stack의 경우 내용이 많으므로, 수정 시 유의하여 진행합니다.

 

==================================================================================

1. NCP 관리형 쿠버네티스 생성

2023.08.30 - [NCloud(NCP)] - [Naver Cloud Platform] (공공기관용) 관리형 Kubernetes Service에서 Velero를 이용한 PV 백업 및 복구

 

[Naver Cloud Platform] (공공기관용) 관리형 Kubernetes Service에서 Velero를 이용한 PV 백업 및 복구

요건  - Naver Cloud Platform 공공 플랫폼의 Kubernetes Service에서 Velero를 이용한 PV 백업 및 복구 환경 Kubernetes Service Cluster(최소 1개 노드 이상) Kubernetes에 접속하기 위한 NCloud Server 1대(운영체제 무관) 목

enginnersnack.tistory.com

위의 글에서 목차 2번까지 진행하여 관리형 쿠버네티스 클러스터 생성 및 클러스터 접속 설정까지 진행합니다.

 

 

2. NCP 관리형 쿠버네티스 클러스터에 Nginx Ingress Controller 설치

생성한 클러스터에 nginx ingress controller를 설치합니다.

kubectl --kubeconfig $KUBE_CONFIG apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

*$KUBE_CONFIG는 ncp-iam-athunticater를 통해 생성한 kubeconfig.yaml 파일입니다.

 

설치가 완료되면 아래와 같이 ingress-nginx 네임스페이스에 2개의 service가 생긴 것을 확인할 수 있습니다.

이후 과정에서 사용하기 위해 ingress-nginx-controller의 EXTERNAL-IP를 메모장에 기록합니다.

"ingress-ngi-ingress-ngin-4ab45-2217451-d7e7f88d5b8a.kr-gov.lb.naverncp.com"

 

*snack point

nginx ingress controller는 alb ingress controller와 달리 컨트롤러를 설치할때부터 기본적으로 1대의 NPLB를 제공합니다.

이후 ingress를 배포할때 별도의 NPLB와 target group이 생성되지 않으며, nginx ingress controller의 내부 라우팅 룰에 의해 서비스로 트래픽이 라우팅됩니다.(NPLB 1대를 통해 ingress를 처리하게 됩니다.)

 

 

 

3. helm 설치 및 kube-prometheus-stack을 이용하여 prometheus, grafana 설치

kube-prometheus-stack 차트를 통해 prometheus, grafana를 설치하기 위해 먼저 helm을 설치합니다.

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh ## 권한 변경
./get_helm.sh

 

 

패키지 설치를 위해 헬름 레포지토리를 업데이트 합니다.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

 

 

kube-prometheus-stack에서는 prometheus, grafana등 배포되는 애플리케이션의 설정을 커스터마이징할 수 있는 value.yaml 파일을 제공하고 있습니다.

ingress.yaml 배포 시 subpath를 통해 prometheus와 grafana로 접속할 수 있게하기 위해 해당 파일을 수정합니다.

 

먼저, helm pull을 통해 value.yaml을 가져옵니다.

helm pull prometheus-community/kube-prometheus-stack

 

value.yaml에서 grafana와 prometheus 파트의 수정을 진행합니다.

grafana 파트의 enabled를 "true"로 설정하고, grafana.ini부터 새로이 추가합니다.

이 때, domain을 아까 적어둔 nginx ingress controller의 External-IP(NPLB 도메인)으로 입력합니다.

....
grafana:
  enabled: true
  grafana.ini:
    server:
      domain: "ingress-ngi-ingress-ngin-4ab45-2217451-d7e7f88d5b8a.kr-gov.lb.naverncp.com"
      root_url: "%(protocol)s://%(domain)s/grafana"
      serve_from_sub_path: true
....

 

prometheus 파트에서도 enabled를 "true"로 설정하고 prometheusSpec 아래에 externalUrl과 routePrefix를 입력합니다.

externalUrl에서도 nginx ingress controller의 External-IP(NPLB 도메인)으로 입력합니다.

....
prometheus:
  enabled: true
  ....
  prometheusSpec:
    externalUrl: "http://ingress-ngi-ingress-ngin-4ab45-2217451-d7e7f88d5b8a.kr-gov.lb.naverncp.com/prometheus"
    ....
    routePrefix: /prometheus
....

 

value.yaml 수정이 완료되었다면, helm 명령어를 통해 prometheus와 grafana를 설치합니다.

kubectl --kubeconfig=$KUBE_CONFIG create ns monitoring
helm install --kubeconfig=$KUBE_CONFIG prom prometheus-community/kube-prometheus-stack -f values.yaml -n monitoring

*helm 역시 kubectl과 마찬가지로 remote cluster를 제어해야하기 때문에 --kubeconfig 옵션을 통해 kubeconfig.yaml 파일을 사용합니다.

 

kube-prometheus-stack에 정의되어있는 애플리케이션들이 설치된 것을 확인할 수 있습니다.

kubectl --kubeconfig=$KUBE_CONFIG get po -n monitoring

 

4. ingress.yaml 배포 및 접속 테스트

prometheus와 grafana를 ingress를 통해 접속하기 위해 먼저 각 애플리케이션의 서비스 이름을 파악합니다.

각 서비스의 이름은 "prom-kube-prometheus-stack-prometheus", "prom-grafana" 입니다.

kubectl --kubeconfig=$KUBE_CONFIG get svc -n monitoring

 

위의 정보를 바탕으로 ingress.yaml을 작성합니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: monitoring-ingress
  namespace: monitoring
  annotations:
    #nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  ingressClassName: nginx
  defaultBackend:
    service:
      name: prom-kube-prometheus-stack-prometheus
      port:
        number: 9090
  rules:
  - http:
      paths:
      - backend:
          service:
            name: prom-grafana
            port:
              number: 80
        path: /grafana
        pathType: Prefix
      - backend:
          service:
            name: prom-kube-prometheus-stack-prometheus
            port:
              number: 9090
        path: /prometheus
        pathType: Prefix

 

작성한 ingress.yaml 파일을 배포하여 ingress가 생성되는지 확인합니다.

kubectl --kubeconfig=$KUBE_CONFIG apply -f ingress.yaml

 

기록해두었던 도메인에 path를 붙여 접속을 진행합니다.

{NPLB 도메인}/grafana

 

{NPLB 도메인}/prometheus 

 

*snack point

ingress.yaml 내용중 "    #nginx.ingress.kubernetes.io/rewrite-target: / " 해당 부분이 주석이 되어있습니다. ingress의 subpath를 이용해서 grafana를 접속하는 대부분의 글에서는 저 설정을 켜놓아야 된다고 설명하고 있는데요, 현재 버전에서는 해당 설정을 킬 경우 redirection loop 가 발생합니다.

리다이렉션 루프가 발생하는 주요 원인은 Grafana의 설정과 Ingress의 설정 사이의 불일치 때문입니다.

  1. Grafana 설정:
    grafana.ini: server: root_url: "%(protocol)s://%(domain)s/grafana" serve_from_sub_path: true
    • 이 설정은 Grafana에게 '/grafana' 하위 경로에서 서비스되고 있다고 알려줍니다.
    • serve_from_sub_path: true는 Grafana가 하위 경로에서 작동하도록 합니다.
  2. Ingress 설정:
    nginx.ingress.kubernetes.io/rewrite-target: / ... path: /grafana
    • 이 설정은 '/grafana' 경로로 들어오는 모든 요청을 루트('/')로 리다이렉트합니다.
  3. 리다이렉션 루프 발생 과정:
    • a. 사용자가 '/grafana'로 접근합니다.
    • b. Ingress는 이 요청을 Grafana 서비스로 전달하지만, 경로를 '/'로 리다이렉트합니다.
    • c. Grafana는 자신이 '/grafana' 하위 경로에서 작동한다고 설정되어 있으므로, 루트('/')로 오는 요청을 다시 '/grafana'로 리다이렉트합니다.
    • d. 이 과정이 계속 반복되어 리다이렉션 루프가 발생합니다.
  4. 근거:
    • Ingress의 rewrite-target: /는 모든 요청을 루트로 보냅니다.
    • Grafana의 root_url과 serve_from_sub_path 설정은 Grafana가 '/grafana' 경로에서 작동한다고 예상합니다.
    • 이 두 설정의 불일치로 인해 서로 다른 경로로 계속 리다이렉트하게 됩니다.

그러므로 rewrite-target 어노테이션을 주석처리하고, 사용자가 ingress로 접속시 들어온 경로 그대로 grafana에 알려주는 방식으로 redirection loop를 방지할 수 있습니다.