[Sprint] 모니터링 시스템 구축

# 학습 목표

  • Prometheus Operator가 설치된 환경에서 nginx 인그레스 컨트롤러를 설치합니다.
  • cozserver (v2)의 디플로이먼트 및 서비스를 배포하고, 인그레스를 만들어서 nginx를 통해 서비스에 접근하게 합니다.
  • Prometheus에서 쿼리를 통해 주요 메트릭을 확인합니다.
  • Grafana에 이미 존재하는 대시보드들을 살펴보고, 어떤 쿼리를 사용하는지 확인합니다.

# 해결 과제

1. nginx 인그레스 컨트롤러 설치

Helm을 이용해서 설치합니다. (minikube addon을 사용하는 것이 아닙니다) 이때 nginx 인그레스 컨트롤러가 프로메테우스용 메트릭을 노출해야 하므로, helm install 과정에서 반드시 설정해야 하는 옵션이 있습니다.

레퍼런스, 레퍼런스2를 참고해서, 어떤 옵션을 설정해 주어야 프로메테우스에서 nginx의 메트릭을 볼 수 있는지 고민해 보세요. 다음과 같이 환경설정을 지정할 수 있습니다.

$ helm install ingress-nginx ingress-nginx/ingress-nginx 
--set 환경설정키=값 
--set 환경설정키=값

프로메테우스 웹 UI (http://localhost:9090)에서 다음과 같이 ingress-nginx-controller가 Target으로 설정되면 성공입니다.

2. 인그레스 생성

레퍼런스를 참고해서, 인그레스를 만들고 적용합니다. 다음과 같은 아키텍처로 구성되어야 합니다.

3. 인그레스 접속 로그가 찍히는지 프로메테우스를 통해 확인

위와 같은 아키텍처로 구성을 완료했다면 http://localhost로 접근 시 인그레스를 통해 cozserver에 접속됩니다. 프로메테우스 웹 UI Graph 메뉴를 클릭하고, nginx_ingress_controller_requests라고 입력 후 Execute 버튼을 눌러 쿼리를 보내면, 접속 현황을 조회할 수 있습니다. 오른쪽에 보이는 숫자가 접속 횟수입니다.

SRE의 네 가지의 황금 시그널을 보기 위해 필요한 메트릭의 종류는 다음과 같습니다.

  • 트래픽, 오류
  • 대기 시간
  • 포화 수준

프로메테우스가 지원하는 PromQL을 통해 다음과 같이 복잡한 지표를 표현할 수도 있습니다.

예) 1시간 동안 인그레스 컨트롤러를 통해 들어온 요청의 누적 비율

sum(rate(
  nginx_ingress_controller_requests[1h]
))
by (ingress)

예) 1시간 동안 모든 요청 중 400번대 에러의 비율

sum(rate(
  nginx_ingress_controller_requests{
    status=~"4.."
  }[1h]
))
by (ingress) /
sum(rate(
  nginx_ingress_controller_requests[1h]
))
by (ingress)

4. Grafana의 대시보드 살펴보기

그라파나에 접속하고 로그인을 완료하면, 다양한 대시보드가 미리 준비되어 있습니다. 각 Panel에서 사용하는 메트릭을 살펴보고, 어떤 PromQL을 통해 쿼리하는지 알아보세요.

Panel의 제목을 클릭하고 Edit 버튼을 누르면, 다음과 같이 쿼리문을 확인할 수 있습니다.

또한 Create – Import 메뉴를 이용하면, 기존에 커뮤니티에서 만들어놓은 대시보드를 손쉽게 Import 할 수 있습니다.

여기 몇 가지 대시보드를 소개합니다.


# 과제 항목별 진행 상황

1. nginx 인그레스 컨트롤러 설치

helm install ingress-nginx ingress-nginx/ingress-nginx --set controller.metrics.enabled=true --set controller.metrics.serviceMonitor.enabled=true --set controller.metrics.serviceMonitor.additionalLabels.release="prometheus"

Prometheus Tartgets 확인

2. 아키텍처 구성 요소 생성

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cozserver
  namespace: default
  labels:
    app: cozserver
spec:
  selector:
    matchLabels:
      app: cozserver
  replicas: 3
  minReadySeconds: 10
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: cozserver
    spec:
      containers:
        - name: nodejs
          image: sebcontents/cozserver:2.0
          ports:
            - containerPort: 8080

Service

apiVersion: v1
kind: Service
metadata:
  name: cozserver
  namespace: default
spec:
  selector:
    app: cozserver
  type: LoadBalancer
  ports:
    - name: cozserver
      protocol: TCP
      port: 8055
      targetPort: 8080

Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cozserver
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: localhost
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: cozserver
                port:
                  number: 8055

Ingress 접속 확인 http://localhost:80

3. 프로메테우스를 통한 인그레스 접속 로그 확인

4. Grafana 대시보드 생성

[panel json]

https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/grafana/dashboards/nginx.json


# TROUBLE SHOOTING LOG

💡 Ingress 접속시 404 에러 발생

원인

ingress 생성시 잘못된 ingressClassName 을 지정하였음.

해결 방안

ingress-controller 에 지정된 ingress-class 확인하여, 해당 값으로 변경

ingress-nginx-controller.yaml

apiVersion: apps/v1
kind: Deployment
……
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
        - --election-id=ingress-nginx-leader
        - --controller-class=k8s.io/ingress-nginx
        - --ingress-class=nginx
        - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
        - --validating-webhook=:8443
        - --validating-webhook-certificate=/usr/local/certificates/cert
        - --validating-webhook-key=/usr/local/certificates/key
……

cozserver-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cozserver
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: localhost
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: cozserver
                port:
                  number: 8055

💡 Prometheus에서 nginx_ingress_controller_requests metric 조회 안 됨.

원인

해당 메트릭은 host가 특정된 ingress에 접속시 수집됨. [레퍼런스] https://github.com/kubernetes/ingress-nginx/blob/f85c3866d8135d698fe6a2753b1ed17d89a9efa0/internal/ingress/metric/collectors/socket.go#L263-L264

해결 방안

ingress rule에 host 지정 spec.rules[*].host

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cozserver
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: localhost
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: cozserver
                port:
                  number: 8055

#References

내용

Leave a Comment