Overview
가시다님이 진행하시는 쿠버네티스 스터디 6주차가 되었다.
오늘은 얼럿매니저와 로깅시스템에 대하여 공부하는 시간이 되었다.
그림 실습 시라니오는 '24단계 실습으로 정복하는 쿠버네티스' 책을 기준으로 정리하였습니다.
6주차 과제 내용
[과제1]
책 367~372페이지(24단계 실습으로 정복하는 쿠버네티스)
사용자 정의 prometheusrules 정책 설정 : 파일 시스템 사용률 80% 초과 시 시스템 경고 발생시키기 ⇒ 직접 실습 후 관련 스샷을 올려주세요
# git cone
(somaz:monitoring) [root@kops-ec2 ~]# git clone https://github.com/wikibook/kubepractice.git
(somaz:monitoring) [root@kops-ec2 ~]# cd kubepractice/ch19/
(somaz:monitoring) [root@kops-ec2 ch19]# ls
node-exporter-prometheusrules.yaml
(somaz:monitoring) [root@kops-ec2 ch19]# kubectl krew install neat
# 확인하기
(somaz:monitoring) [root@kops-ec2 ch19]# k get prometheusrules.monitoring.coreos.com |grep node-exporter
kube-prometheus-stack-node-exporter 3h28m
kube-prometheus-stack-node-exporter.rules 3h28m
# 주의해서 작성(책이랑 다름)
(somaz:monitoring) [root@kops-ec2 ch19]# k get prometheusrules.monitoring.coreos.com kube-prometheus-stack-node-exporter -o yaml|k neat > node-exporter-prometheusrules.yaml
# 수정
$ vi node-exporter-prometheusrules.yaml
# 해당 정책 복사
- alert: NodeFilesystemAlmostOutOfSpace
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 5% space left.
expr: |-
(
node_filesystem_avail_bytes{job="node-exporter",fstype!="",mountpoint!=""} / node_filesystem_size_bytes{job="node-exporter",fstype!="",mountpoint!=""} * 100 < 5
and
node_filesystem_readonly{job="node-exporter",fstype!="",mountpoint!=""} == 0
)
for: 30m
labels:
severity: warning
# 아래와 같이 변경
## 이름 변경
- 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 변경
summary: Filesystem has less than 20% space left.
expr: |-
(
## 해당 100 < 5 -> 100 /20 으로 변경
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
# 기존 kube-prometheus-stack-node-exporter 삭제 후 재생성
(somaz:monitoring) [root@kops-ec2 ch19]# k get prometheusrules.monitoring.coreos.com |grep node-exporter
kube-prometheus-stack-node-exporter 3h46m
kube-prometheus-stack-node-exporter.rules 3h46m
(somaz:monitoring) [root@kops-ec2 ch19]# k delete prometheusrules.monitoring.coreos.com kube-prometheus-stack-node-exporter
prometheusrule.monitoring.coreos.com "kube-prometheus-stack-node-exporter" deleted
(somaz:monitoring) [root@kops-ec2 ch19]# ls
node-exporter-prometheusrules.yaml
(somaz:monitoring) [root@kops-ec2 ch19]# k apply -f node-exporter-prometheusrules.yaml
prometheusrule.monitoring.coreos.com/kube-prometheus-stack-node-exporter created
이제 아무 노드나 접속해 임의의 큰 파일을 생성해 여유공간이 20% 미만이 되게 한다.
# 워커 노드 퍼블릭 IP 확인
(somaz:monitoring) [root@kops-ec2 ch19]# aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value}" --filters Name=instance-state-name,Values=running --output table
-----------------------------------------------------------------
| DescribeInstances |
+--------------------------------------------+------------------+
| InstanceName | PublicIPAdd |
+--------------------------------------------+------------------+
| nodes-ap-northeast-2c.somaz.link | 15.164.221.204 |
| nodes-ap-northeast-2a.somaz.link | 13.125.199.131 |
| nodes-ap-northeast-2a.somaz.link | 3.39.229.111 |
| master-ap-northeast-2a.masters.somaz.link | 3.36.78.41 |
| kops-ec2 | 3.36.127.208 |
+--------------------------------------------+------------------+
# 워거 노드 접속
(somaz:monitoring) [root@kops-ec2 ch19]# W1PIP=13.125.199.131
# 용량 80% 넘기기
ubuntu@i-0da9df20f40730970:~$ sudo fallocate /var/100g -l 100g
ubuntu@i-0da9df20f40730970:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 124G 105G 19G 85% /
[과제2]
책 386~389페이지(24단계 실습으로 정복하는 쿠버네티스)
LogQL 사용법 익히기 ⇒ 직접 실습 후 관련 스샷을 올려주세요
아래의 사이트 참고하기
Introduction to Loki: Like Prometheus, but for Logs | Grafana Labs
먼저 grafana - explore - LOKI 선택
error log만 검색
DEBUG log만 검색
[과제3]
아래 1,2 과제 중 하나를 해주시면 됩니다
- Awesome Prometheus alerts 를 참고해서 스터디에서 배우지 않은 Alert Rule 생성 및 적용 후 관련 스샷을 올려주세요
- 그라파나에서 그래프 이미지를 포함한 알람을 슬랙에 전달하게 설정 후 관련 스샷을 올려주세요
Awesome Prometheus alerts 를 참고해서 스터디에서 배우지 않은 Alert Rule 생성 및 적용 후 관련 스샷 올리기
링크 주소
https://awesome-prometheus-alerts.grep.to/
과제 1에서 사용했던 node-exporter-prometheusrules.yaml 사용하여 작성
(somaz:monitoring) [root@kops-ec2 ch19]# vi node-exporter-prometheusrules.yaml
...
spec:
groups:
- name: node-exporter
rules:
- alert: HostUnusualDiskReadRate
expr: sum by (instance) (rate(node_disk_read_bytes_total[2m])) / 1024 / 1024 > 50
for: 5m
labels:
severity: warning
annotations:
summary: Host unusual disk read rate (instance {{ $labels.instance }})
description: Disk is probably reading too much data (> 50 MB/s)\n VALUE = {{ $value }}\n LABELS = {{ $labels }}
(somaz:monitoring) [root@kops-ec2 ch19]# k delete prometheusrules.monitoring.coreos.com kube-prometheus-stack-node-exporter
(somaz:monitoring) [root@kops-ec2 ch19]# k apply -f node-exporter-prometheusrules.yaml
prometheusrule.monitoring.coreos.com/kube-prometheus-stack-node-exporter created
스터디 주요내용
실습 환경 배포
실습 환경
kops 인스턴스 t3.small & 노드 c5.2xlarge (vCPU 8, Memory 16GiB) 배포
이번주 실습에서 성능을 요구하는 파드를 사용한다.
- Tip. 실행하는 PC에 aws cli 설치되어 있고, aws configure 자격증명 설정 상태.
# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/kops-oneclick.yaml
# CloudFormation 스택 배포 : 노드 인스턴스 타입 변경 - MasterNodeInstanceType=c5.2xlarge WorkerNodeInstanceType=c5.2xlarge
aws cloudformation deploy --template-file kops-oneclick.yaml --stack-name mykops --parameter-overrides KeyName=somazkey SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=AKIA5... MyIamUserSecretAccessKey='CVNa2...' ClusterBaseName='somaz.link' S3StateStore='somaz-k8s-s3' MasterNodeInstanceType=c5.2xlarge WorkerNodeInstanceType=c5.2xlarge --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 kOps EC2 IP 출력
aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text
# 마스터노드 SSH 접속
ssh -i ~/.ssh/somazkey.pem ec2-user@$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)
EC2 instance profiles 설정 및 AWS LoadBalancer 배포 & ExternalDNS & Metrics-server 설치 및 배포
- 13분 정도 추가 시간 필요
# EC2 instance profiles 에 IAM Policy 추가(attach)
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
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name nodes.$KOPS_CLUSTER_NAME
# kOps 클러스터 편집 : 아래 내용 추가
# kubeproxy.metricsBindAddress 설정은 프로메테우스 kube-proxy 메트릭 수집을 위해서 설정 : 기본값 127.0.0.1 -> 수정 0.0.0.0 - 링크
kops edit cluster
-----
spec:
certManager:
enabled: true
awsLoadBalancerController:
enabled: true
externalDns:
provider: external-dns
metricsServer:
enabled: true
kubeProxy:
metricsBindAddress: 0.0.0.0
-----
# 업데이트 적용 : 모든 노드 롤링업데이트 필요 >> 마스터 EC2인스턴스 삭제 후 재생성 후 정상 확인 후, 워커노드 EC2인스턴스 생성 후 Join 후 삭제 과정 진행됨
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster --yes
# 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
Auto scaling 그룹 error 발생
I0219 21:28:39.447535 7072 instancegroups.go:533] Cluster did not pass validation, will retry in "30s": InstanceGroup "nodes-ap-northeast-2a" did not have enough nodes 0 vs 2.
I0219 21:29:10.139571 7072 instancegroups.go:533] Cluster did not pass validation, will retry in "30s": InstanceGroup "nodes-ap-northeast-2a" did not have enough nodes 0 vs 2.
I0219 21:29:40.775766 7072 instancegroups.go:533] Cluster did not pass validation, will retry in "30s": InstanceGroup "nodes-ap-northeast-2a" did not have enough nodes 0 vs 2.
I0219 21:30:11.515068 7072 instancegroups.go:533] Cluster did not pass validation, will retry in "30s": InstanceGroup "nodes-ap-northeast-2a" did not have enough nodes 0 vs 2.
I0219 21:30:42.282717 7072 instancegroups.go:533] Cluster did not pass validation, will retry in "30s": InstanceGroup "nodes-ap-northeast-2a" did not have enough nodes 0 vs 2.
해결이 되지 않아 동막골 - 김예준님께서 도움을 주셧다.
아래의 사이트에서 quota 증설을 요청했다.
요청을 하면 바로 답변메일이 온다.
I0222 18:07:14.394387 3754 instancegroups.go:443] waiting for 15s after terminating instance
I0222 18:07:29.403317 3754 instancegroups.go:477] Validating the cluster.
I0222 18:07:30.142086 3754 instancegroups.go:513] Cluster validated; revalidating in 10s to make sure it does not flap.
I0222 18:07:40.806417 3754 instancegroups.go:510] Cluster validated.
I0222 18:07:40.806452 3754 rollingupdate.go:214] Rolling update completed for cluster "somaz.link"!
(somaz:N/A) [root@kops-ec2 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
i-015147519888a394a NotReady,SchedulingDisabled node 19m v1.24.10
i-0691c03e2cd60796b Ready node 9m31s v1.24.10
i-0b531baf902cefeee Ready node 3m11s v1.24.10
i-0df291c5a3d9ad47f Ready control-plane 14m v1.24.10
- 메트릭 서버 확인
# 메트릭 서버 확인 : 메트릭은 15초 간격으로 cAdvisor를 통하여 가져옴
kubectl get pod -n kube-system -l k8s-app=metrics-server
kubectl top node
kubectl top pod -A
(somaz:N/A) [root@kops-ec2 ~]# kubectl get pod -n kube-system -l k8s-app=metrics-server
NAME READY STATUS RESTARTS AGE
metrics-server-6d48674cf8-dlxrm 1/1 Running 2 (50s ago) 3m6s
metrics-server-6d48674cf8-n8jgw 1/1 Running 2 (63s ago) 3m6s
(somaz:N/A) [root@kops-ec2 ~]# kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
i-000aab9321c2967a2 29m 0% 1044Mi 6%
i-03b033157083165e0 103m 1% 2219Mi 14%
i-07c20a6b6de51f97e 22m 0% 1000Mi 6%
(somaz:N/A) [root@kops-ec2 ~]# kubectl top pod -A
NAMESPACE NAME CPU(cores) MEMORY(bytes)
kube-system aws-cloud-controller-manager-qp6c4 2m 20Mi
kube-system aws-load-balancer-controller-68c78954d9-7lfbw 1m 31Mi
kube-system aws-node-4jf8z 3m 33Mi
kube-system aws-node-cq6rz 3m 34Mi
kube-system aws-node-mzt58 3m 34Mi
kube-system cert-manager-6b55fb8f96-cllvm 1m 24Mi
kube-system cert-manager-cainjector-5cf5bd97fc-kfjkd 1m 18Mi
kube-system cert-manager-webhook-66ccfc975d-rrxkp 1m 13Mi
kube-system coredns-6897c49dc4-tptcj 1m 13Mi
kube-system coredns-6897c49dc4-zk2cg 1m 14Mi
kube-system coredns-autoscaler-5685d4f67b-9tw97 1m 3Mi
kube-system dns-controller-6f8cbcbb69-8zmbd 1m 15Mi
kube-system ebs-csi-controller-657d666f54-mmtlh 2m 50Mi
kube-system ebs-csi-node-c7zcd 1m 22Mi
kube-system ebs-csi-node-hjzmx 1m 20Mi
kube-system ebs-csi-node-qq5dt 1m 22Mi
kube-system etcd-manager-events-i-03b033157083165e0 5m 30Mi
kube-system etcd-manager-main-i-03b033157083165e0 14m 62Mi
kube-system external-dns-844d94fdd8-8bjwf 1m 18Mi
kube-system kops-controller-qthz4 1m 18Mi
kube-system kube-apiserver-i-03b033157083165e0 31m 387Mi
kube-system kube-controller-manager-i-03b033157083165e0 6m 60Mi
kube-system kube-proxy-i-000aab9321c2967a2 1m 12Mi
kube-system kube-proxy-i-03b033157083165e0 1m 12Mi
kube-system kube-proxy-i-07c20a6b6de51f97e 1m 12Mi
kube-system kube-scheduler-i-03b033157083165e0 2m 19Mi
kube-system metrics-server-6d48674cf8-dlxrm 2m 16Mi
kube-system metrics-server-6d48674cf8-n8jgw 2m 14Mi
프로메테우스-스택 설치 및 웹 접속 : 모니터링에 필요한 여러 요소를 단일 차트(스택)으로 제공 ← 시각화(그라파나), 이벤트 메시지 정책(경고 임계값, 경고 수준) 등
# 사용 리전의 인증서 ARN 확인
CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
# 설치
kubectl create ns monitoring
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:
serviceMonitorSelectorNilUsesHelmValues: false
retention: 5d
retentionSize: "10GiB"
EOT
# 배포
#helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.0.0 -f monitor-values.yaml --namespace monitoringhelm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.0.0 --set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' -f monitor-values.yaml --namespace monitoring
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.0.0 -f monitor-values.yaml --namespace monitoring
# 확인
## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송
helm list -n monitoring
kubectl get-all -n monitoring
kubectl get prometheus,alertmanager -n monitoring
kubectl get prometheusrule -n monitoring
kubectl get servicemonitors -n monitoring
(somaz:N/A) [root@kops-ec2 ~]# helm list -n monitoring
NAME NAMESPACE REVISION UPDATED
STATUS CHART APP VERSION
kube-prometheus-stack monitoring 1 2023-02-19 21:25:39.389880109 +0900 KST deployed kube-prometheus-stack-45.0.0 v0.63.0
프로메테우스 기본 사용 : 모니터링 그래프 → 경고 Alert 클릭 확인
# 프로메테우스 ingress 도메인으로 웹 접속
echo -e "Prometheus Web URL = https://prometheus.$KOPS_CLUSTER_NAME"
# 웹 상단 주요 메뉴 설명
1. 경고(Alert) : 사전에 정의한 시스템 경고 정책(Prometheus Rules)에 대한 상황
2. 그래프(Graph) : 프로메테우스 자체 검색 언어 PromQL을 이용하여 메트릭 정보를 조회 -> 단순한 그래프 형태 조회
3. 상태(Status) : 경고 메시지 정책(Rules), 모니터링 대상(Targets) 등 다양한 프로메테우스 설정 내역을 확인
4. 도움말(Help)
(somaz:N/A) [root@kops-ec2 ~]# echo -e "Prometheus Web URL = https://prometheus.$KOPS_CLUSTER_NAME"
Prometheus Web URL = https://prometheus.somaz.link
워커 노드 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
# 인스턴스그룹 정보 확인
(somaz:N/A) [root@kops-ec2 ~]# kops get ig
NAME ROLE MACHINETYPE MIN MAX ZONES
master-ap-northeast-2a Master c5.2xlarge 1 1 ap-northeast-2a
nodes-ap-northeast-2a Node c5.2xlarge 1 1 ap-northeast-2a
nodes-ap-northeast-2c Node c5.2xlarge 1 1 ap-northeast-2c
# 노드 추가
kops edit ig nodes-ap-northeast-2a --set spec.minSize=2 --set spec.maxSize=2
# 확인
(somaz:N/A) [root@kops-ec2 ~]# kops get ig
NAME ROLE MACHINETYPE MIN MAX ZONES
master-ap-northeast-2a Master c5.2xlarge 1 1 ap-northeast-2a
nodes-ap-northeast-2a Node c5.2xlarge 2 2 ap-northeast-2a
nodes-ap-northeast-2c Node c5.2xlarge 1 1 ap-northeast-2c
# 수동으로 수정 가능
kops edit ig nodes-ap-northeast-2a
# 적용
kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster
# 워커노드 증가 확인
while true; do kubectl get node; echo "------------------------------" ;date; sleep 1; done
(somaz:N/A) [root@kops-ec2 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
i-0691c03e2cd60796b Ready node 16m v1.24.10
i-0b531baf902cefeee Ready node 9m50s v1.24.10
i-0da9df20f40730970 Ready node 2m1s v1.24.10
i-0df291c5a3d9ad47f Ready control-plane 21m v1.24.10
그라파나 웹 접속 및 대시보드 추가 : TSDB 데이터를 시각화, 다양한 데이터 형식 지원(메트릭, 로그, 트레이스 등)
- 링크
- 접속 정보 확인 및 로그인 : 기본 계정 - admin / prom-operator
# ingress 도메인으로 웹 접속
echo -e "Grafana Web URL = https://grafana.$KOPS_CLUSTER_NAME"
(somaz:N/A) [root@kops-ec2 ~]# echo -e "Grafana Web URL = https://grafana.$KOPS_CLUSTER_NAME"
Grafana Web URL = https://grafana.somaz.link
- 대시보드 사용 : 기본 대시보드 사용
- 스택을 통해서 설치된 기본 대시보드 확인 : Dashboards → Browse
- (대략) 분류 : 자원 사용량 - Cluster/POD Resources, 노드 자원 사용량 - Node Exporter, 주요 애플리케이션 - CoreDNS 등
- 확인해보자 - K8S / CR / Cluster, Node Exporter / Use Method / Cluster
- 공식 대시보드 가져오기 - 링크
- [1 Kubernetes All-in-one Cluster Monitoring KR] Dashboard → Import → 13770 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
- [Node Exporter Full] Dashboard → Import → 1860 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
얼럿매니저 웹 접속 & 얼럿매니저 대시보드 karma 사용
- 링크
- 얼럿매니저 웹 접속
# ingress 도메인으로 웹 접속
echo -e "Alertmanager Web URL = https://alertmanager.$KOPS_CLUSTER_NAME"
(somaz:N/A) [root@kops-ec2 ~]# echo -e "Alertmanager Web URL = https://alertmanager.$KOPS_CLUSTER_NAME"
Alertmanager Web URL = https://alertmanager.somaz.link
- Alerts 경고: 시스템 문제 시 프로메테우스가 전달한 경고 메시지 목록을 확인
- Silences 일시 중지 : 계획 된 장애 작업 시 일정 기간 동안 경고 메시지를 받지 않을 때, 메시지별로 경고 메시지를 일시 중단 설정
- Statue 상태 : 얼럿매니저 상세 설정 확인
그리고 프로메테우스에 Watchdog이 얼럿매니저에 표현이 되어 있는 걸 볼 수 있다.
[kops-ec2] 얼럿매니저 대시보드 karma 컨테이너로 실행
# 실행
docker run -d -p 80:8080 -e ALERTMANAGER_URI=https://alertmanager.$KOPS_CLUSTER_NAME ghcr.io/prymitive/karma:latest
(somaz:N/A) [root@kops-ec2 ~]# docker run -d -p 80:8080 -e ALERTMANAGER_URI=https://alertmanager.$KOPS_CLUSTER_NAME ghcr.io/prymitive/karma:latest
Unable to find image 'ghcr.io/prymitive/karma:latest' locally
latest: Pulling from prymitive/karma
fc251a6e7981: Pull complete
7be4d3667295: Pull complete
dcbf1cb4e3a6: Pull complete
Digest: sha256:94b432c69901ae7916acea2c6c4a2e9942176b0e57451a290639a9d6c3517ab1
Status: Downloaded newer image for ghcr.io/prymitive/karma:latest
26e5d83badb07dee7501b74a8ea018fa87790db2d2ac132aaab2b29c2c97657f
# 확인
docker ps
(somaz:N/A) [root@kops-ec2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
26e5d83badb0 ghcr.io/prymitive/karma:latest "/karma" 10 seconds ago Up 9 seconds 0.0.0.0:80->8080/tcp, :::80->8080/tcp friendly_jackson
[자신의 PC] 얼럿매니저 대시보드 karma 웹 접속 주소 확인
#
echo -e "karma Web URL = http://$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)"
(somaz:N/A) [root@kops-ec2 ~]# echo -e "karma Web URL = http://$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)"
karma Web URL = http://3.36.127.208
Alerting 얼럿매니저
소개 : 프로메테우스의 임곗값 도달 시 경고 메시지를 얼럿매니저에 푸시 이벤트로 전달하고, 얼럿매지저는 이를 가공후 이메일/슬랙 등에 전달
프로메테우스 웹 Alert & 얼럿매니저 웹 karma
슬랙 채널 및 웹훅 URL 생성 및 얼럿매니저 설정 적용 : 책 350~360페이지, 참고
# 웹훅 URL 정보
WEBHOOK='https://xxxxxx'(비공개)
# 샘플 메시지 보내기
curl -X POST --data-urlencode "payload={\"channel\": \"#webhook\", \"username\": \"pkosbot\", \"text\": \"$KOPS_CLUSTER_NAME 다음주 종강! - 봇 제공\"}" $WEBHOOK
curl -X POST --data-urlencode "payload={\"channel\": \"#webhook\", \"username\": \"pkosbot\", \"text\": \"$KOPS_CLUSTER_NAME 다음주 종강! - 봇 제공\", \"icon_emoji\": \":ghost:\"}" $WEBHOOK
(somaz:N/A) [root@kops-ec2 ~]# curl -X POST --data-urlencode "payload={\"channel\": \"#webhook\", \"username\": \"pkosbot\", \"text\": \"$KOPS_CLUSTER_NAME 다음주 종강! - 봇 제공\"}" $WEBHOOK
(somaz:N/A) [root@kops-ec2 ~]# curl -X POST --data-urlencode "payload={\"channel\": \"#webok\", \"username\": \"pkosbot\", \"text\": \"$KOPS_CLUSTER_NAME 다음주 종강! - 봇 제공\"}" $WEBHOOK
얼럿매니저에 웹훅 URL 정보 반영
cat <<EOT > ~/alertmanager-slack.yaml
alertmanager:
config:
global:
resolve_timeout: 5m
slack_api_url: 'https://hooks.slack.com/services/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'
route:
group_by: ['job'] # namespace
group_wait: 10s
group_interval: 1m
repeat_interval: 5m
receiver: 'slack-notifications'
routes:
- receiver: 'slack-notifications'
matchers:
- alertname =~ "InfoInhibitor|Watchdog"
receivers:
- name: 'slack-notifications'
slack_configs:
- channel: '#webhook'
send_resolved: true
title: '[{{.Status | toUpper}}] {{ .CommonLabels.alertname }}'
text: |
*Description:* {{ .CommonAnnotations.description }}
EOT
# helm 업그레이드로 얼럿매니저에 웹훅 URL 정보 반영
helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.0.0 --reuse-values -f alertmanager-slack.yaml --namespace monitoring
# 반영 확인 : 얼럿매니저 설정 파일에 반영(config reload)
kubectl describe pod -n monitoring alertmanager-kube-prometheus-stack-alertmanager-0
kubectl exec -it -n monitoring alertmanager-kube-prometheus-stack-alertmanager-0 -- ls /etc/alertmanager/config
alertmanager.yaml.gz
(somaz:N/A) [root@kops-ec2 ~]# kubectl describe pod -n monitoring alertmanager-kube-prometheus-stack-alertmanager-0
Name: alertmanager-kube-prometheus-stack-alertmanager-0
Namespace: monitoring
Priority: 0
Service Account: kube-prometheus-stack-alertmanager
Node: i-0691c03e2cd60796b/172.30.41.180
Start Time: Wed, 22 Feb 2023 18:10:30 +0900
Labels: alertmanager=kube-prometheus-stack-alertmanager
app.kubernetes.io/instance=kube-prometheus-stack-alertmanager
app.kubernetes.io/managed-by=prometheus-operator
app.kubernetes.io/name=alertmanager
app.kubernetes.io/version=0.25.0
controller-revision-hash=alertmanager-kube-prometheus-stack-alertmanager-659cbdf54d
statefulset.kubernetes.io/pod-name=alertmanager-kube-prometheus-stack-alertmanager-0
Annotations: kubectl.kubernetes.io/default-container: alertmanager
Status: Running
IP: 172.30.51.3
IPs:
IP: 172.30.51.3
Controlled By: StatefulSet/alertmanager-kube-prometheus-stack-alertmanager
Containers:
alertmanager:
Container ID: containerd://6857066521745df9dda0a676698fa8ab99c8abcff299382431c9ccdbd1d88105
Image: quay.io/prometheus/alertmanager:v0.25.0
Image ID: quay.io/prometheus/alertmanager@sha256:fd4d9a3dd1fd0125108417be21be917f19cc76262347086509a0d43f29b80e98
Ports: 9093/TCP, 9094/TCP, 9094/UDP
Host Ports: 0/TCP, 0/TCP, 0/UDP
Args:
--config.file=/etc/alertmanager/config_out/alertmanager.env.yaml
--storage.path=/alertmanager
--data.retention=120h
--cluster.listen-address=
--web.listen-address=:9093
--web.external-url=http://alertmanager.somaz.link/
--web.route-prefix=/
--cluster.peer=alertmanager-kube-prometheus-stack-alertmanager-0.alertmanager-operated:9094
--cluster.reconnect-timeout=5m
--web.config.file=/etc/alertmanager/web_config/web-config.yaml
State: Running
Started: Wed, 22 Feb 2023 18:10:40 +0900
Last State: Terminated
Reason: Error
Message: ts=2023-02-22T09:10:35.499Z caller=main.go:240 level=info msg="Starting Alertmanager" version="(version=0.25.0, branch=HEAD, revision=258fab7cdd551f2cf251ed0348f0ad7289aee789)"
ts=2023-02-22T09:10:35.499Z caller=main.go:241 level=info build_context="(go=go1.19.4, user=root@abe866dd5717, date=20221222-14:51:36)"
ts=2023-02-22T09:10:35.525Z caller=coordinator.go:113 level=info component=configuration msg="Loading configuration file" file=/etc/alertmanager/config_out/alertmanager.env.yaml
ts=2023-02-22T09:10:35.525Z caller=coordinator.go:118 level=error component=configuration msg="Loading configuration file failed" file=/etc/alertmanager/config_out/alertmanager.env.yaml err="open /etc/alertmanager/config_out/alertmanager.env.yaml: no such file or directory"
Exit Code: 1
Started: Wed, 22 Feb 2023 18:10:35 +0900
Finished: Wed, 22 Feb 2023 18:10:35 +0900
Ready: True
Restart Count: 1
Requests:
memory: 200Mi
Liveness: http-get http://:http-web/-/healthy delay=0s timeout=3s period=10s #success=1 #failure=10
Readiness: http-get http://:http-web/-/ready delay=3s timeout=3s period=5s #success=1 #failure=10
Environment:
POD_IP: (v1:status.podIP)
Mounts:
/alertmanager from alertmanager-kube-prometheus-stack-alertmanager-db (rw)
/etc/alertmanager/certs from tls-assets (ro)
/etc/alertmanager/config from config-volume (rw)
/etc/alertmanager/config_out from config-out (ro)
/etc/alertmanager/web_config/web-config.yaml from web-config (ro,path="web-config.yaml")
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-6kmtd (ro)
config-reloader:
Container ID: containerd://80c4ec6754524db2e61fc0eb2fe5145c081811f8d9bafa4716e22a84c7d7a10e
Image: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0
Image ID: quay.io/prometheus-operator/prometheus-config-reloader@sha256:3f976422884ec7744f69084da7736927eb634914a0c035d5a865cf6a6b8eb1b0
Port: 8080/TCP
Host Port: 0/TCP
Command:
/bin/prometheus-config-reloader
Args:
--listen-address=:8080
--reload-url=http://127.0.0.1:9093/-/reload
--config-file=/etc/alertmanager/config/alertmanager.yaml.gz
--config-envsubst-file=/etc/alertmanager/config_out/alertmanager.env.yaml
State: Running
Started: Wed, 22 Feb 2023 18:10:39 +0900
Ready: True
Restart Count: 0
Limits:
cpu: 200m
memory: 50Mi
Requests:
cpu: 200m
memory: 50Mi
Environment:
POD_NAME: alertmanager-kube-prometheus-stack-alertmanager-0 (v1:metadata.name)
SHARD: -1
Mounts:
/etc/alertmanager/config from config-volume (ro)
/etc/alertmanager/config_out from config-out (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-6kmtd (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
config-volume:
Type: Secret (a volume populated by a Secret)
SecretName: alertmanager-kube-prometheus-stack-alertmanager-generated
Optional: false
tls-assets:
Type: Projected (a volume that contains injected data from multiple sources)
SecretName: alertmanager-kube-prometheus-stack-alertmanager-tls-assets-0
SecretOptionalName: <nil>
config-out:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium: Memory
SizeLimit: <unset>
web-config:
Type: Secret (a volume populated by a Secret)
SecretName: alertmanager-kube-prometheus-stack-alertmanager-web-config
Optional: false
alertmanager-kube-prometheus-stack-alertmanager-db:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
kube-api-access-6kmtd:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 46m default-scheduler Successfully assigned monitoring/alertmanager-kube-prometheus-stack-alertmanager-0 to i-0691c03e2cd60796b
Normal Pulling 46m kubelet Pulling image "quay.io/prometheus/alertmanager:v0.25.0"
Normal Pulled 46m kubelet Successfully pulled image "quay.io/prometheus/alertmanager:v0.25.0" in 3.308438903s
Normal Pulling 46m kubelet Pulling image "quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0"
Normal Pulled 46m kubelet Successfully pulled image "quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0" in 3.6196947s
Normal Created 46m kubelet Created container config-reloader
Normal Started 46m kubelet Started container config-reloader
Normal Created 46m (x2 over 46m) kubelet Created container alertmanager
Normal Started 46m (x2 over 46m) kubelet Started container alertmanager
Normal Pulled 46m kubelet Container image "quay.io/prometheus/alertmanager:v0.25.0" already present on machine
(somaz:N/A) [root@kops-ec2 ~]# kubectl exec -it -n monitoring alertmanager-kube-prometheus-stack-alertmanager-0 -- ls /etc/alertmanager/config
alertmanager.yaml.gz
- 얼럿매니저 웹 → Status : 아래 config 부분에 위 슬랙 정보, 타이머 정보 확인
얼럿매니저 웹에서 일시 중지 Silence 기능 사용 : repeat_interval 5분 설정으로 경고 알람 미조치 시 5분 마다 반복 발생
- 웹 확인 : 프로메테우스 Alert, 얼럿매니지 웹, karma 웹
- KubeClientCertificateExpiration(버그로 보임) → Silence 클릭 후 설정 기간(Duration), 작성자(admin) 입력 후 아래 Create 선택 ⇒ 해당 기간 동안 알람 발생하지 않음
- Watchdog(탐지견, 얼럿매니저 정상 동작 여부 확인 용도) → Silence 클릭 후 설정 기간(Duration), 작성자(admin) 입력 후 아래 Create 선택
얼럿매니저 웹에서 일시 중지 Silence 기능 설정
- 10분 후 TargetDown 경보 알람 → Silence 클릭 후 설정 기간(Duration), 작성자(admin) 입력 후 아래 Create 선택 ⇒ 해당 기간 동안 알람 발생하지 않음
현재 2개의 장애(경보) 이슈 해결 : kube-controller-manager, kube-scheduler
- 프로메테우스 웹 → Status → Targets 확인 : kube-controller-manager, kube-scheduler 없음 확인
# 상태확인
(somaz:N/A) [root@kops-ec2 ~]# k get po -n kube-system | grep kube-scheduler
kube-scheduler-i-0df291c5a3d9ad47f 1/1 Running 0 66m
(somaz:N/A) [root@kops-ec2 ~]# k get po -n kube-system | grep kube-controller
kube-controller-manager-i-0df291c5a3d9ad47f 1/1 Running 1 (68m ago) 68m
# 레이블 셀렉터 Selector 정보 확인!
kubectl get svc,ep -n kube-system kube-prometheus-stack-kube-controller-manager
kubectl describe svc -n kube-system kube-prometheus-stack-kube-controller-manager
# 해당 서비스에 endpoint가 없다!
(somaz:N/A) [root@kops-ec2 ~]# kubectl exec -it -n monitoring alertmanager-kube-prometheus-stack-alertmanager-0 -- ls /etc/alertmanager/config
alertmanager.yaml.gz
(somaz:N/A) [root@kops-ec2 ~]# kubectl get svc,ep -n kube-system kube-prometheus-stack-kube-controller-manager
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-prometheus-stack-kube-controller-manager ClusterIP None <none> 10257/TCP 51m
NAME ENDPOINTS AGE
endpoints/kube-prometheus-stack-kube-controller-manager <none> 51m
# kube-controller-manager 파드의 레이블 확인
kubectl get pod -n kube-system --show-labels | grep kube-controller-manager
# 레이블 셀렉터 Selector 정보 확인!
kubectl get svc,ep -n kube-system kube-prometheus-stack-kube-scheduler
kubectl describe svc -n kube-system kube-prometheus-stack-kube-scheduler
# 파드의 레이블 확인
kubectl get pod -n kube-system --show-labels | grep kube-scheduler
(somaz:N/A) [root@kops-ec2 ~]# kubectl get pod -n kube-system --show-labels | grep kube-scheduler
kube-scheduler-i-0df291c5a3d9ad47f 1/1 Running 0 68m k8s-app=kube-scheduler
- 해결 : 방안1(파드에 레이블 추가), 방안2(프로메테우스-스택 배포 때 파리미터에 기입)
방안1 : 파드에 레이블 추가
# 추가
kubectl label $(kubectl get pod -n kube-system -l k8s-app=kube-controller-manager -oname) -n kube-system component=kube-controller-manager
(somaz:N/A) [root@kops-ec2 ~]# kubectl label $(kubectl get pod -n kube-system -l k8s-app=kube-controller-manager -oname) -n kube-system component=kube-controller-manager
pod/kube-controller-manager-i-0df291c5a3d9ad47f labeled
# 확인
kubectl get svc,ep -n kube-system kube-prometheus-stack-kube-controller-manager
# 앤드포인트에 IP가 생겼다!
(somaz:N/A) [root@kops-ec2 ~]# kubectl get svc,ep -n kube-system kube-prometheus-stack-kube-controller-manager
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-prometheus-stack-kube-controller-manager ClusterIP None <none> 10257/TCP 53m
NAME ENDPOINTS AGE
endpoints/kube-prometheus-stack-kube-controller-manager 172.30.37.245:10257 53m
# 추가
kubectl label $(kubectl get pod -n kube-system -l k8s-app=kube-scheduler -oname) -n kube-system component=kube-scheduler
(somaz:N/A) [root@kops-ec2 ~]# kubectl label $(kubectl get pod -n kube-system -l k8s-app=kube-scheduler -oname) -n kube-system component=kube-scheduler
pod/kube-scheduler-i-0df291c5a3d9ad47f labeled
# 확인
kubectl get svc,ep -n kube-system kube-prometheus-stack-kube-scheduler
(somaz:N/A) [root@kops-ec2 ~]# kubectl get svc,ep -n kube-system kube-prometheus-stack-kube-scheduler
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-prometheus-stack-kube-scheduler ClusterIP None <none> 10259/TCP 54m
NAME ENDPOINTS AGE
endpoints/kube-prometheus-stack-kube-scheduler 172.30.37.245:10259 54m
- 프로메테우스 웹 Status → Targets 확인
방안2 : 프로메테우스-스택 helm 배포 때 파리미터에 기입 혹은 스택 helm 업그레이드로 적용
...
kubeControllerManager:
enabled: true
service:
enabled: true
selector:
k8s-app: kube-controller-manager
...
kubeScheduler:
enabled: true
service:
enabled: true
selector:
k8s-app: kube-controller-manager
...
[장애 재현] 워커 노드 3번 kubelet down → 얼럿매니저 기능 검증 : 워커 노드 3번 다운 감지(TargetDown → Kube…)
# 모니터링
while true; do kubectl get node; echo "------------------------------" ;date; sleep 1; done
(somaz:N/A) [root@kops-ec2 ~]# while true; do kubectl get node; echo "------------------------------" ;date; sleep 1; done
NAME STATUS ROLES AGE VERSION
i-0691c03e2cd60796b Ready node 71m v1.24.10
i-0b531baf902cefeee Ready node 65m v1.24.10
i-0da9df20f40730970 Ready node 57m v1.24.10
i-0df291c5a3d9ad47f Ready control-plane 76m v1.24.10
------------------------------
#
WNODE3=<자신의 워커노드 3번 퍼블릭 IP>
WNODE3=13.125.162.198
ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 hostname
(somaz:default) [root@kops-ec2 ~]# ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 hostname
The authenticity of host '13.125.199.131 (13.125.199.131)' can't be established.
ECDSA key fingerprint is SHA256:MGI4H3x/hHypxiI1/ihUvPUzwO18bnFX5BWmKAnsROk.
ECDSA key fingerprint is MD5:40:eb:63:5a:86:16:c2:10:7c:1b:9b:3a:9f:19:ee:d0.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '13.125.199.131' (ECDSA) to the list of known hosts.
i-0da9df20f40730970
(somaz:default) [root@kops-ec2 ~]#
# 워커노드 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
(somaz:default) [root@kops-ec2 ~]# ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 sudo systemctl status kubelet
● kubelet.service - Kubernetes Kubelet Server
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
Active: inactive (dead) since Wed 2023-02-22 10:13:29 UTC; 4s ago
Docs: https://github.com/kubernetes/kubernetes
Process: 3679 ExecStart=/usr/local/bin/kubelet $DAEMON_ARGS (code=exited, status=0/SUCCESS)
Main PID: 3679 (code=exited, status=0/SUCCESS)
CPU: 33.442s
- 프로메테우스 Alerts(Pending 도 체크) vs 얼럿매니저 웹 상태 변화를 잘 관찰해보자!
# 모니터링 확인
while true; do kubectl get node; echo "------------------------------" ;date; sleep 1; done
Wed Feb 22 19:14:22 KST 2023
NAME STATUS ROLES AGE VERSION
i-0691c03e2cd60796b Ready node 74m v1.24.10
i-0b531baf902cefeee Ready node 68m v1.24.10
i-0da9df20f40730970 NotReady node 60m v1.24.10
i-0df291c5a3d9ad47f Ready control-plane 80m v1.24.10
------------------------------
https://awesome-prometheus-alerts.grep.to/
(참고) 그라파나 얼럿 Docs - 링크
슬랙 채널 알람 확인 → 프로메테우스 Alerts , 얼럿매니저 웹, karma 에서 확인
# TargetDown 은 10분간 Pending 상태에 있다가 지속시 Firing 으로 변경 -> 이후 얼럿매니저를 통해서 슬랙 알람 발생
kubectl get prometheusrules -n monitoring -o json | grep TargetDown -B1 -A11
{
"alert": "TargetDown",
"annotations": {
"description": "{{ printf \"%.4g\" $value }}% of the {{ $labels.job }}/{{ $labels.service }} targets in {{ $labels.namespace }} namespace are down.",
"runbook_url": "https://runbooks.prometheus-operator.dev/runbooks/general/targetdown",
"summary": "One or more targets are unreachable."
},
"expr": "100 * (count(up == 0) BY (job, namespace, service) / count(up) BY (job, namespace, service)) \u003e 10",
"for": "10m",
"labels": {
"severity": "warning"
}
},
장애 정보 확인 후 워커 노드 3번 kubelet 다시 start ⇒ Silence Expire 로 제거
(somaz:default) [root@kops-ec2 ~]# ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 sudo systemctl start
kubelet
(somaz:default) [root@kops-ec2 ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
i-0691c03e2cd60796b Ready node 103m v1.24.10
i-0b531baf902cefeee Ready node 97m v1.24.10
i-0da9df20f40730970 Ready node 89m v1.24.10
i-0df291c5a3d9ad47f Ready control-plane 109m v1.24.10
(somaz:default) [root@kops-ec2 ~]# ssh -i ~/.ssh/id_rsa ubuntu@$WNODE3 sudo systemctl status kubelet
● kubelet.service - Kubernetes Kubelet Server
Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2023-02-22 10:42:57 UTC; 44s ago
Docs: https://github.com/kubernetes/kubernetes
Main PID: 22011 (kubelet)
Tasks: 20 (limit: 18627)
Memory: 38.7M
CPU: 777ms
PLG 스택
NGINX 웹서버 배포
#
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.27 -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
(somaz:default) [root@kops-ec2 ~]# kubectl get pod,svc,ep
NAME READY STATUS RESTARTS AGE
pod/nginx-5b589b7644-jcdwb 2/2 Running 0 3m1s
NAME TYPE CLUSTER-IP EXTERNAL-IP
PORT(S) AGE
service/kubernetes ClusterIP 100.64.0.1 <none>
443/TCP 3h6m
service/nginx LoadBalancer 100.66.227.175 a0a5d72568a214215b5930d3f9ea24a0-1681479890.ap-northeast-2.elb.amazonaws.com 80:32530/TCP,9113:31643/TCP 3m1s
NAME ENDPOINTS AGE
endpoints/kubernetes 172.30.37.245:443 3h6m
endpoints/nginx 172.30.52.132:9113,172.30.52.132:8080 3m1s
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"
(somaz:default) [root@kops-ec2 ~]# echo -e "Nginx WebServer URL = http://nginx.$KOPS_CLUSTER_NAME"
Nginx WebServer URL = http://nginx.somaz.link
curl -s http://nginx.$KOPS_CLUSTER_NAME
(somaz:default) [root@kops-ec2 ~]# curl -s http://nginx.$KOPS_CLUSTER_NAME
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
kubectl logs deploy/nginx -f
# 반복 접속
while true; do curl -s http://nginx.$KOPS_CLUSTER_NAME -I | head -n 1; date; sleep 1; done
# (참고) 삭제 시
helm uninstall nginx
컨테이너 로그 환경의 로그는 표준 출력 stdout과 표준 에러 stderr로 보내는 것을 권고 - 링크
- 해당 권고에 따라 작성된 컨테이너 애플리케이션의 로그는 해당 파드 안으로 접속하지 않아도 사용자는 외부에서 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
(참고) nginx docker log collector 예시 - 링크 링크
RUN ln -sf /dev/stdout /opt/bitnami/nginx/logs/access.log
RUN ln -sf /dev/stderr /opt/bitnami/nginx/logs/error.log
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
- 또한 종료된 파드의 로그는 kubectl logs로 조회 할 수 없다
- kubelet 기본 설정은 로그 파일의 최대 크기가 10Mi로 10Mi를 초과하는 로그는 전체 로그 조회가 불가능함
PLG Stack 소개
Promtail + Loki + Grafana 여러 파드의 로그들을 중앙 서버에 저장하고 이를 조회- 링크
Loki에 저장한 로그는 LogQL(PromQL과 유사)을 이용해 조회 할 수 있으며, 그라파나 웹이나 logcli를 이용해 조회 가능 - 링크
- 전체 로그 기반 인덱스를 생성하지 않고, 메타데이터를 기준으로 인덱스를 생성하여 자원 사용량이 현저히 적음
- Promtail은 데몬셋으로 실행되며 각 로그에 로그를 중앙 로키 서버에 전달, Promtail 외에도 도커, FluentD 등 다른 로그수집 에이전트 사용 할 수 있다
Loki & Promtail 헬름 차트로 설치 - Helm Single & Helm
현재 Loki 최신 버전으로 설치(파라미터)가 실패해서, 책 설치 버전으로 진행합니다
(24단계 실습으로 정복하는 쿠버네티스)
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
(somaz:default) [root@kops-ec2 ~]# kubectl get pod,pvc,svc,ds,sts -n loki
NAME READY STATUS RESTARTS AGE
pod/loki-0 1/1 Running 0 89s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/storage-loki-0 Bound pvc-2165c9ff-de6a-4960-834d-a6c1a679c389 20Gi RWO kops-csi-1-21 89s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/loki ClusterIP 100.71.72.42 <none> 3100/TCP 89s
service/loki-headless ClusterIP None <none> 3100/TCP 89s
service/loki-memberlist ClusterIP None <none> 7946/TCP 89s
NAME READY AGE
statefulset.apps/loki 1/1 89s
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
(somaz:default) [root@kops-ec2 ~]# 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
(somaz:default) [root@kops-ec2 ~]# kubectl get-all -n loki |grep promtail
endpoints/promtail-metrics loki 29s
pod/promtail-6tt6s loki 29s
pod/promtail-bl6tb loki 29s
pod/promtail-db97p loki 29s
pod/promtail-ldml5 loki 29s
secret/promtail loki 29s
secret/sh.helm.release.v1.promtail.v1 loki 29s
serviceaccount/promtail loki 29s
service/promtail-metrics loki 29s
controllerrevision.apps/promtail-7dd7844cc5 loki 29s
daemonset.apps/promtail loki 29s
endpointslice.discovery.k8s.io/promtail-metrics-nwgsb loki 29s
servicemonitor.monitoring.coreos.com/promtail loki 29s
# (참고) 삭제 시
helm uninstall promtail -n loki
그라파나에서 로그 확인
- 그라파나 → Configuration → Data Source : 데이터 소스 추가 ⇒ Loki 클릭
- HTTP URL : http://loki-headless.loki:3100 ⇒ Save & Test
- nginx 반복 접속
# 접속 주소 확인 및 접속
kubectl logs deploy/nginx -f
# 반복 접속
while true; do curl -s http://nginx.$KOPS_CLUSTER_NAME -I | head -n 1; date; sleep 1; done
- 그라파나 → Explore : 상단 데이터 소스 Loki 선택
- Logfilters : Job → default/nginx 값 선택 ⇒ 우측 상단 Run query 클릭
- Logfilters : node_name → 아무 노드 선택 ⇒ 우측 상단 Run query 클릭
스터디 6주차 후기
6주차에는 프로메테우스와 그라파나를 사용하여 Alertmanager, karma 등에 대하여 공부하였다.
Monitoring Tool 공부는 처음이라서 상당히 도움이 많이 된 것 같다.
사내에도 Zabbix를 사용하여 텔레그램으로 알람을 주고 있는데, 비슷한 원리일 것으로 보인다.
이제 마지막 주차가 다가오고 있다.
다들 마지막까지 힘냅시다~~
'교육, 커뮤니티 후기 > PKOS 쿠버네티스 스터디' 카테고리의 다른 글
PKOS 쿠버네티스 스터디 7주차 - K8S 보안 (0) | 2023.02.28 |
---|---|
PKOS 쿠버네티스 스터디 5주차 - 프로메테우스 그라파나 (0) | 2023.02.14 |
PKOS 쿠버네티스 스터디 4주차 - Harbor Gitlab Argocd (2) | 2023.02.06 |
PKOS 쿠버네티스 스터디 3주차 - Ingress & Storage (4) | 2023.02.03 |
PKOS 쿠버네티스 스터디 2주차 - 쿠버네티스 네트워크 (0) | 2023.01.16 |