[Week4] AWS EKS Observability(2/3)

오태경·2024년 3월 30일

본 게시물은 CloudNet@팀 Gasida(서종호) 님이 진행하시는
AWS EKS Workshop Study 내용을 기반으로 작성되었습니다.

Prometheus

소개 & 기능

  • Prometheus is an open-source systems monitoring and alerting toolkit originally built at SoundCloud
  • a multi-dimensional data model with time series data(=TSDB, 시계열 데이터베이스) identified by metric name and key/value pairs
  • PromQL, a flexible query language to leverage this dimensionality
  • no reliance on distributed storage; single server nodes are autonomous
  • time series collection happens via a pull model over HTTPPushPull 수집 방식 장단점? - 링크
  • pushing time series is supported via an intermediary gateway
  • targets are discovered via service discovery or static configuration
  • multiple modes of graphing and dashboarding support

구성 요소

Prometheus Stack 설치

# 모니터링
kubectl create ns monitoring
watch kubectl get pod,pvc,svc,ingress -n monitoring

# 사용 리전의 인증서 ARN 확인 : 정상 상태 확인(만료 상태면 에러 발생!)
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
echo $CERT_ARN

# repo 추가
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

# 파라미터 파일 생성
cat <<EOT > monitor-values.yaml
prometheus:
  prometheusSpec:
    podMonitorSelectorNilUsesHelmValues: false
    serviceMonitorSelectorNilUsesHelmValues: false
    retention: 5d
    retentionSize: "10GiB"
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: gp3
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 30Gi

  ingress:
    enabled: true
    ingressClassName: alb
    hosts: 
      - prometheus.$MyDomain
    paths: 
      - /*
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
      alb.ingress.kubernetes.io/group.name: study
      alb.ingress.kubernetes.io/ssl-redirect: '443'

grafana:
  defaultDashboardsTimezone: Asia/Seoul
  adminPassword: prom-operator

  ingress:
    enabled: true
    ingressClassName: alb
    hosts: 
      - grafana.$MyDomain
    paths: 
      - /*
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
      alb.ingress.kubernetes.io/group.name: study
      alb.ingress.kubernetes.io/ssl-redirect: '443'

  persistence:
    enabled: true
    type: sts
    storageClassName: "gp3"
    accessModes:
      - ReadWriteOnce
    size: 20Gi

defaultRules:
  create: false
kubeControllerManager:
  enabled: false
kubeEtcd:
  enabled: false
kubeScheduler:
  enabled: false
alertmanager:
  enabled: false
EOT

cat monitor-values.yaml | yh
prometheus:
  prometheusSpec:
    podMonitorSelectorNilUsesHelmValues: false
    serviceMonitorSelectorNilUsesHelmValues: false
    retention: 5d
    retentionSize: "10GiB"
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: gp3
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 30Gi
  ingress:
    enabled: true
    ingressClassName: alb
    hosts:
      - prometheus.tkops.click
    paths:
      - /*
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:891377200830:certificate/a712c613-0255-47f4-b0f8-1d1610866e14
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
      alb.ingress.kubernetes.io/group.name: study
      alb.ingress.kubernetes.io/ssl-redirect: '443'
grafana:
  defaultDashboardsTimezone: Asia/Seoul
  adminPassword: prom-operator
  ingress:
    enabled: true
    ingressClassName: alb
    hosts:
      - grafana.tkops.click
    paths:
      - /*
    annotations:
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:891377200830:certificate/a712c613-0255-47f4-b0f8-1d1610866e14
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
      alb.ingress.kubernetes.io/group.name: study
      alb.ingress.kubernetes.io/ssl-redirect: '443'
  persistence:
    enabled: true
    type: sts
    storageClassName: "gp3"
    accessModes:
      - ReadWriteOnce
    size: 20Gi
defaultRules:
  create: false
kubeControllerManager:
  enabled: false
kubeEtcd:
  enabled: false
kubeScheduler:
  enabled: false
alertmanager:
  enabled: false

# 배포
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 57.1.0 \
--set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' \
-f monitor-values.yaml --namespace monitoring

# 확인
## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송
## grafana : 프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리
## prometheus-0 : 모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장
## node-exporter : 노드익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출
## operator : 시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원
## kube-state-metrics : 쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드
helm list -n monitoring
kubectl get pod,svc,ingress,pvc -n monitoring
kubectl get-all -n monitoring
kubectl get prometheus,servicemonitors -n monitoring
kubectl get crd | grep monitoring
kubectl df-pv



AWS CNI Metrics 수집 설정

# PodMonitor 배포
cat <<EOF | kubectl create -f -
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: aws-cni-metrics
  namespace: kube-system
spec:
  jobLabel: k8s-app
  namespaceSelector:
    matchNames:
    - kube-system
  podMetricsEndpoints:
  - interval: 30s
    path: /metrics
    port: metrics
  selector:
    matchLabels:
      k8s-app: aws-node
EOF

# PodMonitor 확인
kubectl get podmonitor -n kube-system
kubectl get podmonitor -n kube-system aws-cni-metrics -o yaml | kubectl neat | yh
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata: 
  name: aws-cni-metrics
  namespace: kube-system
spec: 
  jobLabel: k8s-app
  namespaceSelector: 
    matchNames: 
    - kube-system
  podMetricsEndpoints: 
  - interval: 30s
    path: /metrics
    port: metrics
  selector: 
    matchLabels: 
      k8s-app: aws-node
          
# metrics url 접속 확인
curl -s $N1:61678/metrics | grep '^awscni'
awscni_add_ip_req_count 10
awscni_assigned_ip_addresses 7
awscni_assigned_ip_per_cidr{cidr="192.168.1.104/32"} 1
awscni_assigned_ip_per_cidr{cidr="192.168.1.138/32"} 1
awscni_assigned_ip_per_cidr{cidr="192.168.1.155/32"} 1
awscni_assigned_ip_per_cidr{cidr="192.168.1.177/32"} 0
awscni_assigned_ip_per_cidr{cidr="192.168.1.200/32"} 1
awscni_assigned_ip_per_cidr{cidr="192.168.1.213/32"} 1
awscni_assigned_ip_per_cidr{cidr="192.168.1.226/32"} 0
awscni_assigned_ip_per_cidr{cidr="192.168.1.249/32"} 1
awscni_assigned_ip_per_cidr{cidr="192.168.1.251/32"} 1
...



Prometheus 기본 사용

  • 모니터링 대상 서비스는 /metric 엔드포인트로 다양한 메트릭 정보를 노출

  • Prometheus는 해당 경로를 GET 방식으로 호출해 메트릭 정보를 조회하고 TSDB(Time Series DataBase)에 저장

  • Prometheus 접속

    # ingress 확인
    kubectl get ingress -n monitoring kube-prometheus-stack-prometheus
    kubectl describe ingress -n monitoring kube-prometheus-stack-prometheus
    
    # 프로메테우스 ingress 도메인으로 웹 접속
    echo -e "Prometheus Web URL = https://prometheus.$MyDomain"
    
    # 웹 상단 주요 메뉴 설명
     1. 경고(Alert) : 사전에 정의한 시스템 경고 정책(Prometheus Rules)에 대한 상황
     2. 그래프(Graph) : 프로메테우스 자체 검색 언어 PromQL을 이용하여 메트릭 정보를 조회 -> 단순한 그래프 형태 조회
     3. 상태(Status) : 경고 메시지 정책(Rules), 모니터링 대상(Targets) 등 다양한 프로메테우스 설정 내역을 확인 > 버전(2.42.0)
     4. 도움말(Help)

  • 쿼리 입력 옵션

    • Use local time : 출력 시간을 로컬 타임으로 변경
    • Enable query history : PromQL 쿼리 히스토리 활성화
    • Enable autocomplete : 자동 완성 기능
    • Enable highlighting : 하이라이팅 기능
    • Enable linter : 메트릭 포맷 유효성 검사 기능
  • Prometheus Configuration 확인

    • Status → Runtime & Build Information

    • Status → Command-Line Flags

  • 메트릭 수집 대상(Targets) 확인

    • Status → Targets
  • Service Discovery

    • Status → Service Discovery
    • Configuration에 정의된 도달 규칙 기준, endpoint를 자동으로 발견함 => pull 방식 수집이 가능
  • Graph 조회

    • Graph -> PromQL 쿼리 조회



애플리케이션 - NGINX 웹서버 모니터링 설정

  • 서비스 모니터 동작

  • nginx 를 helm 설치 시 프로메테우스 익스포터 Exporter 옵션 설정 시 자동으로 nginx 를 프로메테우스 모니터링에 등록 가능

  • 프로메테우스 설정에서 nginx 모니터링 관련 내용을 서비스 모니터 CRD로 추가 가능

  • 기존 애플리케이션 파드에 프로메테우스 모니터링을 추가하려면 사이드카 방식을 사용하며 exporter 컨테이너를 추가

  • nginx 웹 서버(with helm)에 metrics 수집 설정 추가

    # 모니터링
    watch -d "kubectl get pod; echo; kubectl get servicemonitors -n monitoring"
    
    # 파라미터 파일 생성 : 서비스 모니터 방식으로 nginx 모니터링 대상을 등록하고, export 는 9113 포트 사용
    cat <<EOT > ~/nginx_metric-values.yaml
    metrics:
     enabled: true
    
     service:
       port: 9113
    
     serviceMonitor:
       enabled: true
       namespace: monitoring
       interval: 10s
    EOT
    
    # 배포
    helm upgrade nginx bitnami/nginx --reuse-values -f nginx_metric-values.yaml
    
    # 확인
    kubectl get pod,svc,ep
    kubectl get servicemonitor -n monitoring nginx
    kubectl get servicemonitor -n monitoring nginx -o json | jq
    
    # 메트릭 확인 >> 프로메테우스에서 Target 확인
    NGINXIP=$(kubectl get pod -l app.kubernetes.io/instance=nginx -o jsonpath={.items[0].status.podIP})
    curl -s http://$NGINXIP:9113/metrics # nginx_connections_active Y 값 확인해보기
    curl -s http://$NGINXIP:9113/metrics | grep ^nginx_connections_active
    
    # nginx 파드내에 컨테이너 갯수 확인
    kubectl get pod -l app.kubernetes.io/instance=nginx
    kubectl describe pod -l app.kubernetes.io/instance=nginx
    
    # 접속 주소 확인 및 접속
    echo -e "Nginx WebServer URL = https://nginx.$MyDomain"
    curl -s https://nginx.$MyDomain
    kubectl logs deploy/nginx -f
    
    # 반복 접속
    while true; do curl -s https://nginx.$MyDomain -I | head -n 1; date; sleep 1; done
  • 서비스 모니터 Target 확인

  • 설정이 자동으로 반영되는 원리 => config-reloader 동작

    kubectl describe pod -n monitoring prometheus-kube-prometheus-stack-prometheus-0
    ...
    config-reloader:
       Container ID:  containerd://8373b07b3868bd1d842f19f259daac36471aa45981dcb6173fe79b3b22bb09c6
       Image:         quay.io/prometheus-operator/prometheus-config-reloader:v0.72.0
       Image ID:      quay.io/prometheus-operator/prometheus-config-reloader@sha256:89a6c7d3fd614ee1ed556f515f5ecf2dba50eec9af418ac8cd129d5fcd2f5c18
       Port:          8080/TCP
       Host Port:     0/TCP
       Command:
         /bin/prometheus-config-reloader
       Args:
         --listen-address=:8080
         --reload-url=http://127.0.0.1:9090/-/reload
         --config-file=/etc/prometheus/config/prometheus.yaml.gz
         --config-envsubst-file=/etc/prometheus/config_out/prometheus.env.yaml
         --watched-dir=/etc/prometheus/rules/prometheus-kube-prometheus-stack-prometheus-rulefiles-0
       State:          Running
         Started:      Sat, 30 Mar 2024 23:38:26 +0900
       Ready:          True
       Restart Count:  0
       Environment:
         POD_NAME:  prometheus-kube-prometheus-stack-prometheus-0 (v1:metadata.name)
         SHARD:     0
       Mounts:
         /etc/prometheus/config from config (rw)
         /etc/prometheus/config_out from config-out (rw)
         /etc/prometheus/rules/prometheus-kube-prometheus-stack-prometheus-rulefiles-0 from prometheus-kube-prometheus-stack-prometheus-rulefiles-0 (rw)
         /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7s8w9 (ro)
    ...
  • 메트릭 확인

0개의 댓글