프로메테우스
개요
key/value 값을 쌍으로 사용하는 시계열 데이터베이스
PromQL(prometheus 쿼리 언어)를 제공
프로메테우스는 pull 방식으로 수집
Push 와 Pull 수집 방식 장단점? 링크
- Push: 데이터를 가진 곳에서, 필요한 곳으로 보내준다. (Nasgios, zabbix)
- Pull: 데이터가 필요한 곳에서, 가진 곳에 접속하여 데이터를 긁어간다. (Prometheus, Datadog, collected)
프로메테우스-스택 설치
# 모니터링
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 "alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN"
# 설치
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# 파라미터 파일 생성
cat <<EOT > ~/monitor-values.yaml
alertmanager:
ingress:
enabled: true
ingressClassName: alb
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/group.name: "monitoring"
hosts:
- alertmanager.$KOPS_CLUSTER_NAME
paths:
- /*
grafana:
defaultDashboardsTimezone: Asia/Seoul
adminPassword: prom-operator
ingress:
enabled: true
ingressClassName: alb
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/group.name: "monitoring"
hosts:
- grafana.$KOPS_CLUSTER_NAME
paths:
- /*
prometheus:
ingress:
enabled: true
ingressClassName: alb
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/group.name: "monitoring"
hosts:
- prometheus.$KOPS_CLUSTER_NAME
paths:
- /*
prometheusSpec:
podMonitorSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
retention: 5d
retentionSize: "10GiB"
EOT
# 배포
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.7.1 \
--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)를 메트릭으로 변환하는 파드
프로메테우스 웹 접속
- 경고(Alert) : 사전에 정의한 시스템 경고 정책(Prometheus Rules)에 대한 상황
- 그래프(Graph) : 프로메테우스 자체 검색 언어 PromQL을 이용하여 메트릭 정보를 조회 -> 단순한 그래프 형태 조회
- 상태(Status) : 경고 메시지 정책(Rules), 모니터링 대상(Targets) 등 다양한 프로메테우스 설정 내역을 확인 > 버전(2.42.0)
- 도움말(Help)
그라파나 Grafana
개요
TSDB 데이터를 시각화, 다양한 데이터 형식 지원(메트릭, 로그, 트레이스 등)
그라파나는 시각화 솔루션으로 데이터 자체를 저장하지 않음 / 가시화만 해줌
현재 실습 환경에서는 데이터 소스는 프로메테우스를 사용
공식 대시보드 사용 - 링크
13770
15757
nginx 리소스 확인 (12708)
Kwatch
Kwatch 배포
# configmap 생성
cat <<EOT > ~/kwatch-config.yaml
apiVersion: v1
kind: Namespace
metadata:
name: kwatch
---
apiVersion: v1
kind: ConfigMap
metadata:
name: kwatch
namespace: kwatch
data:
config.yaml: |
alert:
slack:
webhook: 'https://hooks.slack.com/~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#title:
#text:
pvcMonitor:
enabled: true
interval: 5
threshold: 70
EOT
kubectl apply -f kwatch-config.yaml
# 배포
kubectl apply -f https://raw.githubusercontent.com/abahmed/kwatch/v0.8.3/deploy/deploy.yaml
잘못된 이미지 파드 배포 및 확인
# 터미널1
watch kubectl get pod
# 잘못된 이미지 정보의 파드 배포
kubectl apply -f https://raw.githubusercontent.com/junghoon2/kube-books/main/ch05/nginx-error-pod.yml
kubectl get events -w
# 이미지 업데이트 방안2 : set 사용 - iamge 등 일부 리소스 값을 변경 가능!
kubectl set
kubectl set image pod nginx-19 nginx-pod=nginx:1.19
# 삭제
kubectl delete pod nginx-19
프로메테우스 얼럿매니저
웹 접근
- Alerts 경고: 시스템 문제 시 프로메테우스가 전달한 경고 메시지 목록을 확인
- Silences 일시 중지 : 계획 된 장애 작업 시 일정 기간 동안 경고 메시지를 받지 않을 때, 메시지별로 경고 메시지를 일시 중단 설정
- Statue 상태 : 얼럿매니저 상세 설정 확인
장애 알람및 해소
로그 관리
PLG 스택
개요
- 파드와 인스턴스의 로그를 수집해서 볼 수 있다.
- Promtail + Loki + Grafana 여러 파드의 로그들을 중앙 서버에 저장하고 이를 조회
pod의 로그
lrwxrwxrwx 1 root root 11 Feb 18 13:35 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 Feb 18 13:35 error.log -> /dev/stderr
Dockerfile 설정
RUN ln -sf /dev/stdout /opt/bitnami/nginx/logs/access.log
RUN ln -sf /dev/stderr /opt/bitnami/nginx/logs/error.log
조회 불가
- kubelet 기본 설정은 로그 파일의 최대 크기가 10Mi로 10Mi를 초과하는 로그는 전체 로그 조회가 불가능함
- 또한 종료된 파드의 로그는 kubectl logs로 조회 할 수 없다
PLG 스택 설치
Loki 설치
# 모니터링
kubectl create ns loki
watch kubectl get pod,pvc,svc,ingress -n loki
# Repo 추가
helm repo add grafana https://grafana.github.io/helm-charts
# 파라미터 설정 파일 생성
cat <<EOT > ~/loki-values.yaml
persistence:
enabled: true
size: 20Gi
serviceMonitor:
enabled: true
EOT
# 배포
helm install loki grafana/loki --version 2.16.0 -f loki-values.yaml --namespace loki
# 설치 확인 : 데몬셋, 스테이트풀셋, PVC 확인
helm list -n loki
kubectl get pod,pvc,svc,ds,sts -n loki
kubectl get-all -n loki
kubectl get servicemonitor -n loki
kubectl krew install df-pv && kubectl df-pv
# curl 테스트 용 파드 생성
kubectl apply -f ~/pkos/2/netshoot-2pods.yaml
# 로키 gateway 접속 확인
kubectl exec -it pod-1 -- curl -s http://loki.loki.svc:3100/api/prom/label
Promtail 설치
# 파라미터 설정 파일 생성
cat <<EOT > ~/promtail-values.yaml
serviceMonitor:
enabled: true
config:
serverPort: 3101
clients:
- url: http://loki-headless:3100/loki/api/v1/push
#defaultVolumes:
# - name: pods
# hostPath:
# path: /var/log/pods
EOT
# 배포
helm install promtail grafana/promtail --version 6.0.0 -f promtail-values.yaml --namespace loki
# (참고) 파드 로그는 /var/log/pods에 저장
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ls /var/log/pods
# 설치 확인 : 데몬셋, 스테이트풀셋, PVC 확인
helm list -n loki
kubectl get pod,pvc,svc,ds,sts,servicemonitor -n loki
kubectl get-all -n loki
그라파나 설정
15141
도전과제1 책 367~372 페이지
기존 5 퍼센트 40 퍼센트 수정
# neat가 없기 때문에 neat 설치
$ k krew install neat
# node-exporter를 yaml 파일로 익스포트
$ k get prometheusrules.monitoring.coreos.com kube-prometheus-stack-node-exporter -o yaml | k neat > node-exporter.yaml
$ vim node-exporter.yaml
- alert: NodeFilesystemAlmostOutOfSpace-40
...
summary: Filesystem has less than 40% space left.
...
# 여유공간이 20% 미만이면 경고를 발생시킵니다.
node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 20
0
...
# 5분 동안 동일한 상태이면 경고를 발생시킵니다.
for: 5m
labels:
severity: warning
추가 정책 적용
$ k apply -f node-exporter.yaml
prometheusrule.monitoring.coreos.com/kube-prometheus-stack-node-exporter configured
controlplane 워커 노드 접근 및 여유공간 40% 미만 설정
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME
root@i-0ab7b5a71ededdbe2:~# df -h | grep "/dev/root"
/dev/root 124G 5.4G 119G 5% /
root@i-0ab7b5a71ededdbe2:~# fallocate /var/100g -l 100g
root@i-0ab7b5a71ededdbe2:~# df -h | grep "/dev/root"
/dev/root 124G 106G 19G 86% /
Pending 상태 확인
5분후 경고 메시지 확인 및 파일 삭제후 정상
```
root@i-0ab7b5a71ededdbe2:~# rm -rf /var/100g
```
도전과제2 책 386~389페이지 - LogQL 사용법 익히기
정규 표현식 사용
{job="monitoring/nginx"} |~"(?i)err"
특정문자열 제외한 로그 검색
{job="monitoring/nginx"} !="GET"
도전과제3 Awesome Prometheus alerts 를 참고해서 스터디에서 배우지 않은 Alert Rule 생성 및 적용 후 관련 스샷을 올려주세요
룰 추가
$ k get prometheusrules.monitoring.coreos.com kube-prometheus-stack-kubernetes-apps -o yaml | k neat > k8s-app-prom-rule.yaml
$ wget https://raw.githubusercontent.com/samber/awesome-prometheus-alerts/master/dist/rules/nginx/knyar-nginx-exporter.yml
# 룰 추가
$ vim k8s-app-prom-rule.yaml
- alert: NginxHighHttp4xxErrorRate
annotations:
summary: Nginx high HTTP 4xx error rate (instance {{ $labels.instance }})
description: "Too many HTTP requests with status 4xx (> 5%)\n VALUE = {{ $value }}\n LABELS = {{ $labels }}"
expr: 'sum(rate(nginx_http_requests_total{status=~"^4.."}[1m])) / sum(rate(nginx_http_requests_total[1m])) * 10 > 3'
for: 1m
labels:
severity: critical
로그 확인
(thumbup:monitoring) [root@kops-ec2 ~]# k get svc | grep nginx
nginx LoadBalancer 100.65.250.210 a12e6d60754f04c6eaafbf041a06f723-1394958853.ap-northeast-2.elb.amazonaws.com 80:31527/TCP,9113:31968/TCP 3h3m
(thumbup:monitoring) [root@kops-ec2 ~]# curl -s http://a12e6d60754f04c6eaafbf041a06f723-1394958853.ap-northeast-2.elb.amazonaws.com -I
HTTP/1.1 200 OK
Server: nginx
(thumbup:monitoring) [root@kops-ec2 ~]# k logs deployments/nginx | tail -n 3
Defaulted container "nginx" out of: nginx, metrics
172.30.90.113 - - [29/Mar/2023:13:12:37 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.88.1" "-"
172.30.62.199 - - [29/Mar/2023:13:12:39 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.88.1" "-"
172.30.90.113 - - [29/Mar/2023:13:12:42 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.88.1" "-"
알람 발생(실패)
- nginx_http_requests_total 는 데이터가 나오지만
- nginx_http_requests_total{status=~"^4.."} 정규 표현식 사용시 안나오는 것 확인
- 당연히 404 에러를 발생시킨 후 확인 했음
- 단순히 requests 토탈수를 카운터 해주는것 같음..
- 정확한 원인은 nginx-exporter를 분석해 봐야할 것 같아서 포기.. 했습니다.
- 그래도 프로메테우스 간단한 사용법 분석방법을 조금은 이해한 것 같습니다.
느낀점
리소스 모니터링, 로그 모니터링에 대해서 알아 본 기회였습니다.
로키는 처음 써본것 같은데 실무에 다들 많이 쓰시는지 궁금하네요.
3번 과제는 분석하다가 시간도 너무 늦고, 왠지 nginx-exporter를 봐야 될 것 같아서 포기했습니다.
많은 도움이 되는 것 같습니다.