본문 바로가기
Tech/Kubernetes

[PKOS_2기] 4주차 쿠버네티스 모니터링

by 구름_쟁이 2023. 4. 1.

본 시리즈는 가시다님의 PKOS(Production Kubernetes Online Study) 2기 진행 내용입니다.

스터디에 사용된 서적은 이정훈님의 24단계 실습으로 정복하는 쿠버네티스 입니다.

도서 링크 : http://www.yes24.com/Product/Goods/115187666

 

24단계 실습으로 정복하는 쿠버네티스 - YES24

실무 현장의 경험을 고스란히 담은 쿠버네티스 실습서!직접 해야만 알 수 있는 것들이 있다. 쿠버네티스도 마찬가지다. 쿠버네티스의 기반이 되는 컨테이너 기술은 기존의 가상 머신과 기본 전

www.yes24.com

 

Monitoring이란?
기본적인 인프라 환경(여기서는 쿠버네티스 클러스터 워커노드 혹은 파드 메트릭 등등)부터 애플리케이션의 로그 혹은 애플리케이션 성능 모니터링(APM)까지 넓은 범위에서 사용되고 있는 용어이다.
On-Premise에서 모놀리식 아키텍처에서의 모니터링은 서비스 주체를 애완동물처럼 관리했기에 한번 모니터링을 설정(Agent)해두면 그 뒤로는 특별히 건드릴 필요가 없었다.
반면, 쿠버네티스에서 애플리케이션을 배포/운영하는 방식은 서비스 주체를 가축처럼 관리하는 것이므로 언제든 내부의 IP값들이 변경될 수 있다.
그 외에도 파드의 개수가 늘어나는 경우에 대비할 수 있는 모니터링 시스템이 준비되어야 한다.

 

목차

1. 프로메테우스(Prometheus) 구축

2. 그라파나(Grafana) 구축

3. 프로메테우스 Alert Manager

4. PLG 스택 구축

5. 과제

 

 

4주차 강의를 토대로 쿠버네티스 클러스터 환경과 Application을 모니터링하는 방법을 잘 알려진 툴로 구현하고, Pod의 로그도 중앙 서버에 저장 및 조회가 가능하도록 PLG 스택을 실습해본다.

 

그리고 마지막으로 엄청난 양의 고봉밥 과제를 진행해보도록 한다.

(다는 못할지도...)

 

 

 


1. 프로메테우스(Prometheus) 구축

 

프로메테우스란?

1. SoundCloud에 구축된 오픈 소스 시스템 모니터링 및 경고 툴킷이다.

2. GO 언어로 작성되었다.

3. Apache 2.0 라이센스로 무료이다.

4. 자체 쿼리(PromQL)를 제공한다.

5. 이름과 키/값 쌍으로 식별되는 시계열 데이터(=TSDB, 시계열 데이터베이스)가 포함된 다차원 데이터 모델이다.

6. Pull 방식과 Push 방식 모두 제공한다.

 

출처 : https://prometheus.io/docs/introduction/overview/

구성 요소

  • 시계열 데이터를 스크랩하고 저장하는 기본 Prometheus 서버
  • 애플리케이션 코드 계측을 위한 클라이언트 라이브러리
  • 특정한 상황(서비스 레벨의 배치잡의 결과 캡쳐) 등에 사용되는 Pushgateway
  • HAProxy, StatsD, Graphite 등과 같은 서비스를 위한 특별한 exporter 제공
  • Alert 관리를 위한 Alertmanager
  • 그외 다양한 지원 도구

 

kops 클러스터 배포

배포 특이사항

- kops 인스턴스 t3.small & 노드 c5a.2xlarge

 

## 매번 진행하는 master/worker node 역할(Role)에 AWSLoadBalancerControllerIAMPolicy 정책 추가

aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name nodes.$KOPS_CLUSTER_NAME

 

프로메테우스-스택 설치

모니터링에 필요한 여러 요소를 단일 차트(스택)로 제공 ← 시각화(그라파나), 이벤트 메시지 정책(경고 임계값, 경고 수준) 등 - Helm

 

# 모니터링
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)를 메트릭으로 변환하는 파드
helm list -n monitoring
kubectl get pod,svc,ingress -n monitoring
kubectl get-all -n monitoring
kubectl get prometheus,alertmanager -n monitoring
kubectl get prometheusrule -n monitoring
kubectl get servicemonitors -n monitoring
kubectl get crd | grep monitoring

 

설정 후 helm install

 

helm list 확인
prometheus-stack 배포 확인

기본적으로 prometheus, alertmanager, grafana가 배포된다.

 

node exporter 확인

Node exporter Pod는 Node의 IP를 가지고 통신하며, 노드의 메트릭 데이터를 수집한다.

 

# 마스터노드에 lynx 설치
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME hostname
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME sudo apt install lynx -y

# 노드의 9100번의 /metrics 접속 시 다양한 메트릭 정보를 확인할수 있음 : 마스터 이외에 워커노드도 확인 가능
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME lynx -dump localhost:9100/metrics

수진되는 메트릭 확인

Tip : 명령어 뒤에 파이프(|) 후 tail -n <숫자> 를 추가 입력하면 출력값의 마지막 라인부터 <숫자>만큼의 라인만 출력된다.

 

 

프로메테우스 웹 페이지(도메인 연결)

 

앞선 실습과 마찬가지로 하나의 ALB에서 3개의 도메인이 관리됨

위 내용에서 규칙 보기/편집 을 누르면 Rule 이 서브도메인 AND 경로(/*) 로 되어있는 것을 확인할 수 있다.

(스샷 누락 하하...)

 

Route53에 등록된 도메인 레코드 정보

 

 

그럼 이제 프로메테우스에서 수집하는 메트릭 데이터들이 어떤 것들인지 살펴보고, CLI로 조회해보도록 하자

 

우선 kube-proxy부터 살펴보자.

 

그 다음은 coredns를 살펴보자

이쯤되면 이걸 왜 보고있는지 의문이 들 수도 있는데, 과제까지 하고 나서야 생각이 든 것은 아래와 같다.

더보기

1. 각 컴포넌트에서 확인할 수 있는 정보들이 어떤 것들인지 확인 가능하다.

2. 이 정보들을 가지고 추후 Alertmanager를 통해 Alert 설정을 할 수 있다.

3. 도전 과제 중에 깨달은 것... (도전과제5 내용 참고)

 

그럼 이제 프로메테우스 Graph에서 우리가 원하는 메트릭 데이터를 시각화하여 보자

 

1- avg(rate(node_cpu_seconds_total{mode="idle"}[1m]))

전체 클러스터 노드의 CPU 사용량 합계

 

node_boot_time_seconds

노드의 부팅 시간

 

 

결론

1장부터 고봉의 느낌이 든다.

프로메테우스 스택을 통해 편하게 모니터링 서비스를 배포했고, 프로메테우스가 어떤건지 조금이나마 파악할 수 있게 되었다. 


2. 그라파나(Grafana) 구축

 

Prometheus Stack 으로 배포하면서 같이 배포가 되었다.

# ingress 확인
kubectl get ingress -n monitoring kube-prometheus-stack-grafana
kubectl describe ingress -n monitoring kube-prometheus-stack-grafana

# ingress 도메인으로 웹 접속
echo -e "Grafana Web URL = https://grafana.$KOPS_CLUSTER_NAME"

기본 계정 - admin / prom-operator

 

 

  1. Search dashboards : 대시보드 검색
  2. Starred : 즐겨찾기 대시보드
  3. Dashboards : 대시보드 전체 목록 확인
  4. Explore : 쿼리 언어 PromQL를 이용해 메트릭 정보를 그래프 형태로 탐색
  5. Alerting : 경고, 에러 발생 시 사용자에게 경고를 전달
  6. Configuration : 설정, 예) 데이터 소스 설정 등
  7. Server admin : 사용자, 조직, 플러그인 등 설정
  8. admin : admin 사용자의 개인 설정

특이사항

Configuration → Data sources : 스택의 경우 자동으로 프로메테우스를 데이터 소스로 추가됨

 

 

내부적으로 network 관련 테스트를 위한 netshoot pod를 배포해두자

 

kube-prometheus-stack-prometheus.monitoring 을 nslookup 조회해보기

이건 netshoot Pod 가 다 배포되기 전에 명령을 수행하여 발생한 오류

 

조회가 잘 된다.
graph도 조회

 

기본 대시보드

  • 스택을 통해서 설치된 기본 대시보드 확인 : Dashboards → Browse
  • (대략) 분류 : 자원 사용량 - Cluster/POD Resources, 노드 자원 사용량 - Node Exporter, 주요 애플리케이션 - CoreDNS 등
    • K8S / CR / Cluster, Node Exporter / Use Method / Cluster

 

공식 대시보드

Dashboard -> Import -> 13770 입력 후 Load

=> 데이터 소스 : Prometheus

그외 공식 대시보드

 

NGINX 웹서버 배포 및 애플리케이션 모니터링 설정 및 접속

서비스 모니터 동작

https://containerjournal.com/topics/container-management/cluster-monitoring-with-prometheus-operator/

  • nginx 를 helm으로 설치 시 프로메테우스 익스포터(Exporter) 옵션 설정 시 자동으로 nginx가 프로메테우스 모니터링에 등록됨
    • 프로메테우스 설정에서 nginx 모니터링 관련 내용을 서비스 모니터 CRD로 추가 가능
  • 기존 애플리케이션 파드에 프로메테우스 모니터링을 추가하려면 사이드카 방식을 사용하며 exporter 컨테이너를 추가
# bitnami라는 이름을 가진 helm repo 추가 (내용은 https://charts.bitnami.com/bitnami)
helm repo add bitnami https://charts.bitnami.com/bitnami

# 파라미터 파일 생성 : 서비스 모니터 방식으로 nginx 모니터링 대상을 등록하고, export 는 9113 포트 사용, nginx 웹서버 노출은 AWS CLB 기본 사용
cat <<EOT > ~/nginx-values.yaml
metrics:
  enabled: true

  service:
    port: 9113

  serviceMonitor:
    enabled: true
    namespace: monitoring
    interval: 10s
EOT

# 배포
helm install nginx bitnami/nginx --version 13.2.23 -f nginx-values.yaml

# CLB에 ExternanDNS 로 도메인 연결
kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx.$KOPS_CLUSTER_NAME"

# 확인
kubectl get pod,svc,ep
kubectl get servicemonitor -n monitoring nginx
kubectl get servicemonitor -n monitoring nginx -o json | jq

# nginx 파드내에 컨테이너 갯수 확인
kubectl get pod -l app.kubernetes.io/instance=nginx
kubectl describe pod -l app.kubernetes.io/instance=nginx

# 접속 주소 확인 및 접속
echo -e "Nginx WebServer URL = http://nginx.$KOPS_CLUSTER_NAME"
curl -s http://nginx.$KOPS_CLUSTER_NAME
kubectl logs deploy/nginx -f

# 반복 접속
while true; do curl -s http://nginx.$KOPS_CLUSTER_NAME -I | head -n 1; date; sleep 1; done
  • 서비스 모니터링 생성 후 1분 정도 후에 프로메테우스 웹서버에서 State → Targets 에 nginx 서비스 모니터 추가 확인

pod READY에 2/2라... 이것은 필시 멀티 컨테이너다. 그 속을 들여다보자

배포할 때 눈여겨봤다면 알겠지만, 프로메테우스 익스포터를 위해 metrics를 enable 했기 때문에 사이드카 형태로 하나의 컨테이너가 더 배포되었다.

 

Status -> Targets에서 nginx가 잘 올라온 것을 확인

자 그럼 또 helm으로 배포한 nginx 는 어떤 메트릭 정보를 주는지 확인해보자.

 

그 중에 하나를 프로메테우스 Graph에서 조회해보자. (nginx까지만 입력해도 자동완성 리스트가 나온다)

 

Grafana에서도 NGINX exporter 메트릭 정보를 확인해보자

(공식 대시보드 활용 12708 번 Import)

 

KWatch 설치

(코드 미기입)

잘못된 이미지 배포하여 웹훅이 잘 되는지 확인

# 터미널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

 

웹훅에는 어떤 내용이 나타날까?

 

 

결론

단순히 그라파나로 보고 땡! 하는 느낌이 아니라 프로메테우스에서 메트릭을 수집하기 위한 테스트 애플리케이션(nginx) 배포와 그 과정, 추가로 kwatch를 통한 Slack 웹훅 연동 등이 있어 폭 넓게 실습해볼 수 있었다.

 


3. 프로메테우스 Alert Manager

 

프로메테우스 Alert Manager란?

프로메테우스의 임곗값 도달 시 경고 메시지를 얼럿매니저에 푸시 이벤트로 전달하고, 얼럿매지저는 이를 가공후 이메일/슬랙 등에 전달 - 링크

 

 

https://www.oreilly.com/library/view/prometheus-up/9781492034131/ch18.html

 

프로메테우스 설명 때 본 이미지 한번 더 참고

 

Alert Manager 역시 프로메테우스 스택에서 같이 배포되었으므로 URL 확인

# ingress 도메인으로 웹 접속
echo -e "Alertmanager Web URL = https://alertmanager.$KOPS_CLUSTER_NAME"

 

Karma Web 배포

프로메테우스 Alert Manager 용 알림 대시보드인 Karma란?

  • Alert Manager에서 제공하지 않는 다양한 기능들을 제공함
    • Alert 집계 및 중복 제거
    • Alert 그룹
    • Silences 중복 제거
    • Label 기반 멀티 그리드
    • etc

 

Alert Manager 주소를 Karma 웹이 Expose하도록 설정

다만, 본 과정에서는 karma보다는 Alert Manager에 어떤 설정을 추가하고 알림받을 수 있는지를 중점적으로 진행

 

 

웹훅에 테스트 메시지 전송

Alert Manager 설정 확인 및 테스트

워커노드 3번 추가

(미리 해두는 것을 추천)

# EC2 인스턴스 모니터링
while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --output text | sort; echo "------------------------------" ;date; sleep 1; done

# 인스턴스그룹 정보 확인
kops get ig

# 노드 추가
kops edit ig nodes-ap-northeast-2a --set spec.minSize=2 --set spec.maxSize=2

# 적용
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster

# 워커노드 증가 확인
while true; do kubectl get node; echo "------------------------------" ;date; sleep 1; done
  • 노드 추가 시 프로메테우스의 Target들이 자동으로 발견(Auto Discovery)되어서 등록이 되고, 메트릭 수집됨

 

첫 번째로는 워커노드 3의 kubelet Stop

# 모니터링
while true; do kubectl get node; echo "------------------------------" ;date; sleep 1; done

#
WNODE3=<자신의 워커노드 3번 퍼블릭 IP>
WNODE3=***.***.***.***
ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 hostname

# 워커노드 3번 kubelet 강제 stop
ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 sudo systemctl stop kubelet
ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 sudo systemctl status kubelet

우선 감지가 된 순간 Pending 상태로 관리된다.

이후 10분이 지나면 Firing 상태로 전환된다.

다시 워커노드 3의 kubelet 실행

 

# 워커노드 3번 kubelet start
ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 sudo systemctl start kubelet
ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 sudo systemctl status kubelet

 

 

 

결론

프로메테우스 Alert manager에 대해 알 수 있었고 도전과제를 하며 더욱 친해졌다.

(그래도 아직 덜 친한 게 함정)


4. PLG 스택 구축

 

들어가기에 앞서

컨테이너 로그 환경의 로그는 표준 출력 stdout과 표준 에러 stderr로 보내는 것을 권고 - 링크

  • 해당 권고에 따라 작성된 컨테이너 애플리케이션의 로그는 아래 2 항목에 대해 무관하게 해당 파드 안으로 접속하지 않아도 사용자는 외부에서 kubectl logs 명령어로 조회 가능
    • 애플리케이션 종류
    • 애플리케이션마다 다른 로그 파일 위치
# 로그 모니터링
kubectl logs deploy/nginx -c nginx -f

# nginx 웹 접속 시도

# 컨테이너 로그 파일 위치 확인
kubectl exec -it deploy/nginx -c nginx -- ls -l /opt/bitnami/nginx/logs/
total 0
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

  • 또한 종료된 파드의 로그는 kubectl logs로 조회 할 수 없다
  • kubelet 기본 설정은 로그 파일의 최대 크기가 10Mi로 10Mi를 초과하는 로그는 전체 로그 조회가 불가능함

 

PLG Stack 소개 : Promtail + Loki + Grafana 여러 파드의 로그들을 중앙 서버에 저장하고 이를 조회- 링크

https://www.infracloud.io/blogs/logging-in-kubernetes-efk-vs-plg-stack/

  • Loki에 저장한 로그는 LogQL(PromQL과 유사)을 이용해 조회 할 수 있으며, 그라파나 웹이나 logcli를 이용해 조회 가능 - 링크
    • 전체 로그 기반 인덱스를 생성하지 않고, 메타데이터를 기준으로 인덱스를 생성하여 자원 사용량이 현저히 적음

https://grafana.com/docs/loki/latest/fundamentals/architecture/components/

  • Promtail은 데몬셋으로 실행되며 각 로그에 로그를 중앙 로키 서버에 전달, Promtail 외에도 도커, FluentD 등 다른 로그수집 에이전트 사용 할 수 있다

Loki & Promtail 헬름 차트로 설치

  • 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 delete -f ~/pkos/2/netshoot-2pods.yaml
kubectl apply -f ~/pkos/2/netshoot-2pods.yaml

# 로키 gateway 접속 확인
kubectl exec -it pod-1 -- curl -s http://loki.loki.svc:3100/api/prom/label

# (참고) 삭제 시
helm uninstall loki -n loki
kubectl delete pvc -n loki --all

 

  • 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

# (참고) 삭제 시
helm uninstall promtail -n loki

 

https://grafana.com/docs/loki/latest/getting-started/

loki 서비스 확인

 

로키 역시 그라파나와 연동이 가능하다.

 

그라파나에서 로그 확인

그라파나 → Configuration → Data Source : 데이터 소스 추가 ⇒ Loki 클릭

  • nginx 반복 접속
# 접속 주소 확인 및 접속
kubectl logs deploy/nginx -f

# 반복 접속
while true; do curl -s http://nginx2.$KOPS_CLUSTER_NAME -I | head -n 1; date; sleep 1; done

 

  • Loki 로그 확인 대시보드 : 15141

자 이제 애플리케이션의 로그를 수집하는 Loki까지 배포했으니 고봉밥 과제를 하러 가보자!

 

 

결론

이제 애플리케이션의 로그까지 수집하고 조회할 수 있게 되었다. 도전과제 2번을 통해 loki LogQL 쿼리까지 추가로 학습할 수 있었다.

 

 


5. 과제

 

[도전과제1]

책 367~372페이지 - 사용자 정의 prometheusrules 정책 설정 : 파일 시스템 사용률 80% 초과 시 시스템 경고 발생시키기

 

스터디 상에서 진행했던 부분과 책에서 진행한 부분은 약간의 차이가 있으니 이점을 참고하여 진행

기존 프로메테우스 정책을 받을 때 현재 배포한 프로메테우스 node exporter가 어떤 이름인지 확인

## 기존 프로메테우스 정책을 받을 때 현재 배포한 프로메테우스 node exporter가 어떤 이름인지 확인
kubectl get prometheusrules.monitoring.coreos.com -n monitoring

## kube-prometheus-stack-node-exporter 인 것 확인

## krew 툴에서 neat 설치
kubectl krew install neat

## |k neat : yaml로 출력 시 불필요한 정보들을 없애주어 깔끔하게 yaml 추출할 수 있다.
k get prometheusrules.monitoring.coreos.com kube-prometheus-stack-node-exporter -o yaml |k neat > node-exporter-prometheusrules.yaml

vim node-exporter-prometheusrules.yaml
############### node-exporter-prometheusrules.yaml 에 이 내용 추가
    - alert: NodeFilesystemAlmostOutOfSpace-20
      annotations:
        description: Filesystem on {{ $labels.device }} at {{ $labels.instance }}
          has only {{ printf "%.2f" $value }}% available space left.
        runbook_url: https://runbooks.prometheus-operator.dev/runbooks/node/nodefilesystemalmostoutofspace
        summary: Filesystem has less than 20% space left.
      expr: |-
        (
          node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 20
        and
          node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0
        )
      for: 10m
      labels:
        severity: warning
 
###################

k apply -f node-exporter-prometheusrules.yaml

 

이제 볼륨을 점유하러 가보자 (약탈이다!)

(워커노드로 접속하는 과정 생략)

# Worker Node 확인 - kops VM에서 실행
aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value}" --filters Name=instance-state-name,Values=running --output table

W1PIP=<워커노드1 Public IP>
W1PIP=***.***.***.***

ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP

## 디스크 용량 확인
df -h

## 더미 파일 생성
sudo fallocate /var/100g -l 100g

결과 확인

10분 더 기다리면?

 

[도전과제2]

책 386~389페이지 - LogQL 사용법 익히기

그라파나->Explore (Loki 선택)

monitoring 네임스페이스에서 발생한 로그 중 err가 포함된 로그 조회
loki 네임스페이스에서 DEBUG를 제외한 로그 조회

 

 

[도전과제3]

Awesome Prometheus alerts 를 참고해서 스터디에서 배우지 않은 Alert Rule 생성 및 적용 후 관련 스샷을 올려주세요

진행할 대상 : Apache [링크]

마찬가지로 앞서 추출해둔 Prometheusrules yaml에 아래 내용 추가

vim node-exporter-prometheusrules.yaml

#################### 추가
    - alert: ApacheDown
      expr: apache_up == 0
      for: 0m
      labels:
        severity: critical
      annotations:
        summary: Apache down (instance {{ $labels.instance }})
        description: "Apache down\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
  
    - alert: ApacheWorkersLoad
      expr: (sum by (instance) (apache_workers{state="busy"}) / sum by (instance) (apache_scoreboard) ) * 100 > 80
      for: 2m
      labels:
        severity: warning
      annotations:
        summary: Apache workers load (instance {{ $labels.instance }})
        description: "Apache workers in busy state approach the max workers count 80% workers busy on {{ $labels.instance }}\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
  
    - alert: ApacheRestart
      expr: apache_uptime_seconds_total / 60 < 1
      for: 0m
      labels:
        severity: warning
      annotations:
        summary: Apache restart (instance {{ $labels.instance }})
        description: "Apache has just been restarted.\n  VALUE = {{ $value }}\n  LABELS = {{ $labels }}"
####################

프로메테우스에 잘 등록되었는지 확인

 

 

이제 apache를 프로메테우스에서 모니터링 가능하도록 exporter를 추가하여 배포해보자

helm repo add bitnami https://charts.bitnami.com/bitnami

cat <<EOT > ~/apache-values.yaml
metrics:
  enabled: true

  service:
    port: 9117

  serviceMonitor:
    enabled: true
    namespace: monitoring
    interval: 10s
EOT


# 배포
helm install apache bitnami/apache --version 9.2.20 -f apache-values.yaml

# CLB에 ExternanDNS 로 도메인 연결
kubectl annotate service apache "external-dns.alpha.kubernetes.io/hostname=apache.$KOPS_CLUSTER_NAME"

# 접속 주소 확인 및 접속
echo -e "apache WebServer URL = http://apache.$KOPS_CLUSTER_NAME"
curl -s http://apache.$KOPS_CLUSTER_NAME
kubectl logs deploy/apache -f

 

자 이제 우리가 해야할 것은?

더보기

배포한 apache를 무슨 수를 써서라도 망가트리는 것!

결과

 

[도전과제4]

그라파나에서 그래프 이미지를 포함한 알람을 슬랙에 전달하게 설정 후 관련 스샷을 올려주세요

 

[도전과제5]

Nginx 파드를 배포 후 관련 metric 를 프로메테우스 웹에서 확인하고, 그라파나에 nginx 웹서버 대시보드를 추가 후 확인해보세요

 

사실 해당 내용은 실습 때 했던 거라 단순하게 생각했지만 Awesome Prometheus alerts 에서 nginx를 찾아보고나서 눈에 번뜩이는 것이 있었다.

그것은 바로 우리가 헬름 차트로 배포했던 nginx 의 기본 metric은 nginx_http_requests_total을 단순히 count만 하기 때문에 어떤 코드(ex, 2xx, 4xx, 5xx)인지 분류가 되지 않았다.

Awesome Prometheus alerts 에 있는 nginx 예제
헬름 차트로 배포한 nginx에는 nginx_http_requests_total 내에 status가 없다.

 

이것은 추후 과제로 미래의 나에게... 전달하겠다..

 

 

 

 

결론

다음주가 스터디 마지막 주차(5주차)인데 4주차는 정말 극...고봉이라 실습 자료 따라하는 데에 1일, 도전과제 하는데에 1일, 블로그에 작성하면서 1일 총 3일을 클러스터를 만들었다 지웠다를 반복했다.

(IaC가 되어있지 않았다면 정말 끔찍한 일...)

이래저래 개인적인 일들로 바쁜 일정들이 있었지만, 그래도 100%는 아니더라도 실습과 도전과제를 수행했다는 사실이 뿌듯하고 부족한 부분은 추가적으로 보완해 나가자!

 

댓글