카이도스의 Tech Blog

EKS 4주차 - EKS Observability 본문

EKS

EKS 4주차 - EKS Observability

카이도스 2023. 5. 16. 13:56
728x90
반응형
CloudNet@-가시다(Gasida)님의 EKS 스터디를 기준으로 작성됩니다.

지난글 : 2023.05.12 - [EKS] - EKS 3주차 - EKS Storage & Node 관리

 

EKS 3주차 - EKS Storage & Node 관리

CloudNet@-가시다(Gasida)님의 EKS 스터디를 기준으로 작성됩니다. 지난글 : 2023.04.26 - [EKS] - EKS 1주차 - Amzaon EKS 설치 및 기본 사용 EKS 1주차 - Amzaon EKS 설치 및 기본 사용 CloudNet@-가시다(Gasida)님의 EKS 스

djdakf1234.tistory.com

 

비슷한글 : 2023.02.14 - [KOPS] - PKOS 5주차 - 프로메테우스 그라파나

 

PKOS 5주차 - 프로메테우스 그라파나

쿠버네티스 공부는 ‘24단계 실습으로 정복하는 쿠버네티스 책을 기준으로 진행. 프로메테우스(Prometheus) 프로메테우스는 웹 서버, 데이터베이스 등 다양한 시스템을 모니터링하고, 특정 조건이

djdakf1234.tistory.com

 

비슷한글 : 2023.02.23 - [KOPS] - PKOS 6주차 - Alerting 얼럿매니저 로깅시스템

 

PKOS 6주차 - Alerting 얼럿매니저 로깅시스템

쿠버네티스 공부는 ‘24단계 실습으로 정복하는 쿠버네티스 책을 기준으로 진행. 이번 6주차에서는 AlertManager와 PLG 스택을 공부한다. alertmanager 란 - 링크1, 링크2, 링크3 쿠버네티스에서 모니터링

djdakf1234.tistory.com


0.  실습 환경 배포

0-1. Amazon EKS 윈클릭 배포 (natgw, ebs addon, ec2 iam role add, irsa lb/efs, preCmd 추가) &기본 설정 : 노드 t3.xlarge(기본값) 사용

  • Amazon EKS 윈클릭 배포 & 기본 설정(CloudFormation으로 진행함)
# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick3.yaml

# CloudFormation 스택 배포 (20~25분 소요)
# aws cloudformation deploy --template-file eks-oneclick3.yaml --stack-name myeks --parameter-overrides KeyName=<My SSH Keyname> SgIngressSshCidr=<My Home Public IP Address>/32 MyIamUserAccessKeyID=<IAM User의 액세스키> MyIamUserSecretAccessKey=<IAM User의 시크릿 키> ClusterBaseName='<eks 이름>' --region ap-northeast-2
예시) aws cloudformation deploy --template-file eks-oneclick3.yaml --stack-name myeks --parameter-overrides KeyName=PJH-aws-test SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32  MyIamUserAccessKeyID=AKIATA.... MyIamUserSecretAccessKey='SX+o7l.....' ClusterBaseName=myeks --region ap-northeast-2

# CloudFormation 스택 배포 완료 후 작업용 EC2 IP 출력
aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text

# 작업용EC2 SSH 접속
ssh -i ~/PJH-aws-test.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)

  • 기본 설정 및 EFS 확인
# default 네임스페이스 적용
kubectl ns default

# (옵션) context 이름 변경
NICK=<각자 자신의 닉네임>
NICK=pjh
kubectl ctx
kubectl config rename-context admin@myeks.ap-northeast-2.eksctl.io $NICK@myeks
Context "admin@myeks.ap-northeast-2.eksctl.io" renamed to "pjh@myeks".

# EFS 확인 : AWS 관리콘솔 EFS 확인해보자
mount -t efs -o tls $EfsFsId:/ /mnt/myefs
df -hT --type nfs4
Filesystem     Type  Size  Used Avail Use% Mounted on
127.0.0.1:/    nfs4  8.0E     0  8.0E   0% /mnt/myefs

# 노드 정보 확인
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
NAME                                               STATUS   ROLES    AGE     VERSION                INSTANCE-TYPE   CAPACITYTYPE   ZONE
ip-192-168-1-190.ap-northeast-2.compute.internal   Ready    <none>   9m42s   v1.24.13-eks-0a21954   t3.xlarge       ON_DEMAND      ap-northeast-2a
ip-192-168-2-42.ap-northeast-2.compute.internal    Ready    <none>   9m48s   v1.24.13-eks-0a21954   t3.xlarge       ON_DEMAND      ap-northeast-2b
ip-192-168-3-55.ap-northeast-2.compute.internal    Ready    <none>   9m41s   v1.24.13-eks-0a21954   t3.xlarge       ON_DEMAND      ap-northeast-2c

eksctl get iamidentitymapping --cluster myeks

# 노드 IP 확인 및 PrivateIP 변수 지정
N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
echo "export N1=$N1" >> /etc/profile
echo "export N2=$N2" >> /etc/profile
echo "export N3=$N3" >> /etc/profile
echo $N1, $N2, $N3
192.168.1.190, 192.168.2.42, 192.168.3.55

# 노드 보안그룹 ID 확인
NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values='*ng1*' --query "SecurityGroups[*].[GroupId]" --output text)
aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32

# 워커 노드 SSH 접속
for node in $N1 $N2 $N3; do ssh ec2-user@$node hostname; done

  • AWS LB/ExternalDNS/EBS/EFS, kube-ops-view 설치
# ExternalDNS
MyDomain=<자신의 도메인>
echo "export MyDomain=<자신의 도메인>" >> /etc/profile
MyDomain=pjhtest.click
echo "export MyDomain=pjhtest.click" >> /etc/profile
MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
echo $MyDomain, $MyDnzHostedZoneId
curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml
MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
serviceaccount/external-dns created
clusterrole.rbac.authorization.k8s.io/external-dns created
clusterrolebinding.rbac.authorization.k8s.io/external-dns-viewer created
deployment.apps/external-dns created

# kube-ops-view
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
kubectl annotate service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=kubeopsview.$MyDomain"
echo -e "Kube Ops View URL = http://kubeopsview.$MyDomain:8080/#scale=1.5"
Kube Ops View URL = http://kubeopsview.pjhtest.click:8080/#scale=1.5

# AWS LB Controller
helm repo add eks https://aws.github.io/eks-charts
helm repo update
helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \
  --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller

# EBS csi driver 설치 확인
eksctl get addon --cluster ${CLUSTER_NAME}
kubectl get pod -n kube-system -l 'app in (ebs-csi-controller,ebs-csi-node)'
kubectl get csinodes

# gp3 스토리지 클래스 생성
kubectl get sc
cat <<EOT > gp3-sc.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: gp3
allowVolumeExpansion: true
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: gp3
  allowAutoIOPSPerGBIncrease: 'true'
  encrypted: 'true'
EOT
kubectl apply -f gp3-sc.yaml
kubectl get sc
NAME            PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
gp2 (default)   kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  17m
gp3             ebs.csi.aws.com         Delete          WaitForFirstConsumer   true                   8s

# EFS csi driver 설치
helm repo add aws-efs-csi-driver https://kubernetes-sigs.github.io/aws-efs-csi-driver/
helm repo update
helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \
    --namespace kube-system \
    --set image.repository=602401143452.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/eks/aws-efs-csi-driver \
    --set controller.serviceAccount.create=false \
    --set controller.serviceAccount.name=efs-csi-controller-sa

# EFS 스토리지클래스 생성 및 확인
curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/examples/kubernetes/dynamic_provisioning/specs/storageclass.yaml
sed -i "s/fs-92107410/$EfsFsId/g" storageclass.yaml
kubectl apply -f storageclass.yaml
kubectl get sc efs-sc


  • 설치 정보 확인
# 이미지 정보 확인
kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c

# eksctl 설치/업데이트 addon 확인
eksctl get addon --cluster $CLUSTER_NAME

# IRSA 확인
eksctl get iamserviceaccount --cluster $CLUSTER_NAME

1.  EKS Console

1-1. 소개 : 쿠버네티스 API를 통해서 리소스 및 정보를 확인할 수 있음 - Docs permissions

  • 구성, 권한 부여 리소스, 정책 리소스, 서비스 리소스 등과 같은 모든 표준 Kubernetes API 리소스 유형을 보고 탐색할 있습니다.
#
kubectl get ClusterRole | grep eks
eks:addon-manager                                                      2023-05-25T03:18:42Z
eks:az-poller                                                          2023-05-25T03:18:38Z
eks:certificate-controller-approver                                    2023-05-25T03:18:38Z
...
  • 클러스터 ARN : arn:aws:eks:ap-northeast-2:1234...:cluster/myeks


1-2. Console 각 메뉴 확인 : 워크숍 링크 활용 - 링크

  1. Workloads : Pods, ReplicaSets, Deployments, and DaemonSets
    • Pods : 네임스페이스 필터, 구조화된 보기 structured view vs 원시 보기 raw view
  2. Cluster : Nodes, Namespaces and API Services
    • Nodes : 노드 상태 및 정보, Taints, Conditions, Labels, Annotations 등
  3. Service and Networking : Pods as Service, Endpoints and Ingresses
    • Service : 서비스 정보, 로드 밸런서(CLB/NLB) URL 정보 등
  4. Config and Secrets : ConfigMap and Secrets
    • ConfigMap & Secrets : 정보 확인, 디코드 Decode 지원
  5. Storage : PVC, PV, Storage Classes, Volume Attachments, CSI Drivers, CSI Nodes
    • PVC : 볼륨 정보, 주석, 이벤트
    • Volume Attachments : PVC가 연결된 CSI Node 정보
  6. Authentication : Service Account
    • Service Account : IAM 역할 arn , add-on 연동
  7. Authorization : Cluster Roles, Roles, ClusterRoleBindings and RoleBindings
    • Cluster Roles & Roles : Roles 에 규칙 확인
  8. Policy : Limit Ranges, Resource Quotas, Network Policies, Pod Disruption Budgets, Pod Security Policies
    • Pod Security Policies : (기본값) eks.privileged 정보 확인
  9. Extensions : Custom Resource Definitions, Mutating Webhook Configurations, and Validating Webhook Configurations
    • CRD 및 Webhook 확인

https://www.eksworkshop.com/docs/observability/resource-view/extensions/webhook-configurations/


2.  Logging in EKS

 

EKS 스터디 - 4주차 1편 - 컨트롤 플레인 로깅

안녕하세요. 이 글은 EKS 컨트롤 플레인 로그수집 방법을 설명합니다. EKS 컨트롤 플레인 로그란? 컨트롤 플레인 발생한 이벤트를 EKS 옵션을 설정하여 로그로 남길 수 있습니다. 디폴트 설정은 로

malwareanalysis.tistory.com

로깅 : control plane logging, node logging, and application logging - Docs


2-1. Control Plane logging : 로그 이름( /aws/eks/<cluster-name>/cluster ) - Docs

  1. Kubernetes API server component logs (**api**) – kube-apiserver-<nnn...>
  2. Audit (**audit**) – kube-apiserver-audit-<nnn...>
  3. Authenticator (**authenticator**) – authenticator-<nnn...>
  4. Controller manager (**controllerManager**) – kube-controller-manager-<nnn...>
  5. Scheduler (**scheduler**) – kube-scheduler-<nnn...>
# 모든 로깅 활성화
aws eks update-cluster-config --region $AWS_DEFAULT_REGION --name $CLUSTER_NAME \
    --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'

# 로그 그룹 확인
aws logs describe-log-groups | jq

# 로그 tail 확인 : aws logs tail help
aws logs tail /aws/eks/$CLUSTER_NAME/cluster | more

# 신규 로그를 바로 출력
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --follow

# 필터 패턴
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --filter-pattern <필터 패턴>

# 로그 스트림이름
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --log-stream-name-prefix <로그 스트림 prefix> --follow
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --log-stream-name-prefix kube-controller-manager --follow
kubectl scale deployment -n kube-system coredns --replicas=1
kubectl scale deployment -n kube-system coredns --replicas=2

# 시간 지정: 1초(s) 1분(m) 1시간(h) 하루(d) 한주(w)
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --since 1h30m

# 짧게 출력
aws logs tail /aws/eks/$CLUSTER_NAME/cluster --since 1h30m --format short

 

  • CloudWatch Log Insights - 링크
# EC2 Instance가 NodeNotReady 상태인 로그 검색
fields @timestamp, @message
| filter @message like /NodeNotReady/
| sort @timestamp desc

# kube-apiserver-audit 로그에서 userAgent 정렬해서 아래 4개 필드 정보 검색
fields userAgent, requestURI, @timestamp, @message
| filter @logStream ~= "kube-apiserver-audit"
| stats count(userAgent) as count by userAgent
| sort count desc

#
fields @timestamp, @message
| filter @logStream ~= "kube-scheduler"
| sort @timestamp desc

#
fields @timestamp, @message
| filter @logStream ~= "authenticator"
| sort @timestamp desc

#
fields @timestamp, @message
| filter @logStream ~= "kube-controller-manager"
| sort @timestamp desc
  • 로깅 끄기
# EKS Control Plane 로깅(CloudWatch Logs) 비활성화
eksctl utils update-cluster-logging --cluster $CLUSTER_NAME --region $AWS_DEFAULT_REGION --disable-types all --approve

# 로그 그룹 삭제
aws logs delete-log-group --log-group-name /aws/eks/$CLUSTER_NAME/cluster

2-2. Control Plane metrics with Prometheus & CW Logs Insights 쿼리 - Docs

# 메트릭 패턴 정보 : metric_name{"tag"="value"[,...]} value
kubectl get --raw /metrics | more
  • Managing etcd database size on Amazon EKS clusters - 링크
# How to monitor etcd database size? >> 아래 10.0.X.Y IP는 어디일까요? >> 아래 주소로 프로메테우스 메트릭 수집 endpoint 주소로 사용 가능한지???
kubectl get --raw /metrics | grep "etcd_db_total_size_in_bytes"
etcd_db_total_size_in_bytes{endpoint="http://10.0.160.16:2379"} 4.665344e+06
etcd_db_total_size_in_bytes{endpoint="http://10.0.32.16:2379"} 4.636672e+06
etcd_db_total_size_in_bytes{endpoint="http://10.0.96.16:2379"} 4.640768e+06

kubectl get --raw=/metrics | grep apiserver_storage_objects |awk '$2>100' |sort -g -k 2

# CW Logs Insights 쿼리
fields @timestamp, @message, @logStream
| filter @logStream like /kube-apiserver-audit/
| filter @message like /mvcc: database space exceeded/
| limit 10

# How do I identify what is consuming etcd database space?
kubectl get --raw=/metrics | grep apiserver_storage_objects |awk '$2>100' |sort -g -k 2
kubectl get --raw=/metrics | grep apiserver_storage_objects |awk '$2>50' |sort -g -k 2
apiserver_storage_objects{resource="clusterrolebindings.rbac.authorization.k8s.io"} 78
apiserver_storage_objects{resource="clusterroles.rbac.authorization.k8s.io"} 92

# CW Logs Insights 쿼리 : Request volume - Requests by User Agent:
fields userAgent, requestURI, @timestamp, @message
| filter @logStream like /kube-apiserver-audit/
| stats count(*) as count by userAgent
| sort count desc

# CW Logs Insights 쿼리 : Request volume - Requests by Universal Resource Identifier (URI)/Verb:
filter @logStream like /kube-apiserver-audit/
| stats count(*) as count by requestURI, verb, user.username
| sort count desc

# Object revision updates
fields requestURI
| filter @logStream like /kube-apiserver-audit/
| filter requestURI like /pods/
| filter verb like /patch/
| filter count > 8
| stats count(*) as count by requestURI, responseStatus.code
| filter responseStatus.code not like /500/
| sort count desc

#
fields @timestamp, userAgent, responseStatus.code, requestURI
| filter @logStream like /kube-apiserver-audit/
| filter requestURI like /pods/
| filter verb like /patch/
| filter requestURI like /name_of_the_pod_that_is_updating_fast/
| sort @timestamp

컨테이너(파드) 로깅

2-3. NGINX 웹서버 배포 - Helm

# NGINX 웹서버 배포
helm repo add bitnami https://charts.bitnami.com/bitnami

# 사용 리전의 인증서 ARN 확인
CERT_ARN=$(aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text)
echo $CERT_ARN

# 도메인 확인
echo $MyDomain

# 파라미터 파일 생성
cat <<EOT > nginx-values.yaml
service:
    type: NodePort

ingress:
  enabled: true
  ingressClassName: alb
  hostname: nginx.$MyDomain
  path: /*
  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: $CLUSTER_NAME-ingress-alb
    alb.ingress.kubernetes.io/group.name: study
    alb.ingress.kubernetes.io/ssl-redirect: '443'
EOT
cat nginx-values.yaml | yh

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

# 확인
kubectl get ingress,deploy,svc,ep nginx
NAME                              CLASS   HOSTS                 ADDRESS                                                         PORTS   AGE
ingress.networking.k8s.io/nginx   alb     nginx.pjhtest.click   myeks-ingress-alb-1429364593.ap-northeast-2.elb.amazonaws.com   80      24s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           25s

NAME            TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/nginx   NodePort   10.100.182.119   <none>        80:32561/TCP   25s

NAME              ENDPOINTS           AGE
endpoints/nginx   192.168.2.39:8080   25s

kubectl get targetgroupbindings # ALB TG 확인
NAME                           SERVICE-NAME   SERVICE-PORT   TARGET-TYPE   AGE
k8s-default-nginx-362d4e5325   nginx          http           ip            74s

# 접속 주소 확인 및 접속
echo -e "Nginx WebServer URL = https://nginx.$MyDomain"
Nginx WebServer URL = https://nginx.pjhtest.click

curl -s https://nginx.$MyDomain
kubectl logs deploy/nginx -f
....
192.168.2.88 - - [25/May/2023:03:48:40 +0000] "GET / HTTP/1.1" 200  409 "-" "ELB-HealthChecker/2.0" "-"
192.168.2.88 - - [25/May/2023:03:48:55 +0000] "GET / HTTP/1.1" 200  409 "-" "ELB-HealthChecker/2.0" "-"
192.168.2.88 - - [25/May/2023:03:49:01 +0000] "GET / HTTP/1.1" 200  615 "-" "curl/7.88.1" "3.36.88.160"
192.168.1.86 - - [25/May/2023:03:49:05 +0000] "GET / HTTP/1.1" 200  409 "-" "ELB-HealthChecker/2.0" "-"
192.168.2.88 - - [25/May/2023:03:49:10 +0000] "GET / HTTP/1.1" 200  409 "-" "ELB-HealthChecker/2.0" "-"
....

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

# (참고) 삭제 시
helm uninstall nginx

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

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

# nginx 웹 접속 시도

# 컨테이너 로그 파일 위치 확인
kubectl exec -it deploy/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를 초과하는 로그는 전체 로그 조회가 불가능함
cat /etc/kubernetes/kubelet-config.yaml
...
containerLogMaxSize: 10Mi
  • (참고) EKS 수정 예시 :테스트 필요 - 링크
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: <cluster-name>
  region: eu-central-1

nodeGroups:
  - name: worker-spot-containerd-large-log
    labels: { instance-type: spot }
    instanceType: t3.large
    minSize: 2
    maxSize: 30
    desiredCapacity: 2
    amiFamily: AmazonLinux2
    containerRuntime: containerd
    availabilityZones: ["eu-central-1a", "eu-central-1b", "eu-central-1c"]
    kubeletExtraConfig:
        containerLogMaxSize: "500Mi"
        containerLogMaxFiles: 5

파드 로깅 : CloudWatch Container Insights + Fluent Bit로 파드 로그 수집 가능 ⇒ 아래에서 메트릭과 함께 다룸

 

EKS 스터디 - 4주차 2편 - pod로깅

pod로깅이란? pod로깅은 data plane 노드 로그와 노드에서 실행 중인 pod로그를 말합니다. pod로깅은 EKS설정을 지원하지 않습니다. 사용자가 도구를 선택해서 pod로그 수집과 저장을 해야 합니다. AWS공

malwareanalysis.tistory.com


3.  Container Insights metrics in Amazon CloudWatch & Fluent Bit (Logs)

CCI (CloudWatch Container Insight) : 노드에 CW Agent 파드와 Fluent Bit 파드가 데몬셋으로 배치되어
Metrics 와 Logs 수집


3-1 . Fluent Bit (as a DaemonSet to send logs to CloudWatch Logs) Integration in CloudWatch Container Insights for EKS - Docs Blog Fluentd TS

https://aws.amazon.com/ko/blogs/containers/fluent-bit-integration-in-cloudwatch-container-insights-for-eks/

  • [수집] 플루언트비트 Fluent Bit 컨테이너를 데몬셋으로 동작시키고, 아래 3가지 종류의 로그CloudWatch Logs 에 전송
    1. /aws/containerinsights/Cluster_Name/application : 로그 소스(All log files in /var/log/containers), 각 컨테이너/파드 로그
    2. /aws/containerinsights/Cluster_Name/host : 로그 소스(Logs from /var/log/dmesg, /var/log/secure, and /var/log/messages), 노드(호스트) 로그
    3. /aws/containerinsights/Cluster_Name/dataplane : 로그 소스(/var/log/journal for kubelet.service, kubeproxy.service, and docker.service), 쿠버네티스 데이터플레인 로그
  • [저장] : CloudWatch Logs 에 로그를 저장, 로그 그룹 별 로그 보존 기간 설정 가능
  • [시각화] : CloudWatch 의 Logs Insights 를 사용하여 대상 로그를 분석하고, CloudWatch 의 대시보드로 시각화한다
  • (참고) Fluent Bit 다양한 소스에서 데이터와 로그를 수집하고 필터로 보강하고 CloudWatch, Kinesis Data Firehose, Kinesis Data Streams Amazon OpenSearch Service 같은 여러 대상으로 보낼 있는 경량 로그 프로세서 전달자입니다.

3-2. 소개 :컨테이너화된 애플리케이션 마이크로서비스에서 메트릭 로그를 수집, 집계 요약합니다. - 링크 Docs

  • CloudWatch Container Insight는 컨테이너형 애플리케이션 및 마이크로 서비스에 대한 모니터링, 트러블 슈팅알람을 위한 완전 관리형 관측 서비스입니다.
  • CloudWatch 콘솔에서 자동화된 대시보드를 통해 container metrics, Prometeus metrics, application logs 및 performance log events를 탐색, 분석 및 시각화할 수 있습니다.
  • CloudWatch Container Insight는 CPU, 메모리, 디스크 및 네트워크와 같은 인프라 메트릭을 자동으로 수집합니다.
  • EKS 클러스터의 crashloop backoffs와 같은 진단 정보를 제공하여 문제를 격리하고 신속하게 해결할 수 있도록 지원합니다.
  • 이러한 대시보드는 Amazon ECS, Amazon EKS, AWS ECS Fargate 그리고 EC2 위에 구동되는 k8s 클러스터에서 사용 가능합니다.


3-3. (사전 확인) 노드의 로그 확인

1. application 로그 소스(All log files in /var/log/containers → 심볼릭 링크 /var/log/pods/<컨테이너>, 각 컨테이너/파드 로그

# 로그 위치 확인
#ssh ec2-user@$N1 sudo tree /var/log/containers
#ssh ec2-user@$N1 sudo ls -al /var/log/containers
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo tree /var/log/containers; echo; done
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo ls -al /var/log/containers; echo; done

# 개별 파드 로그 확인 : 아래 각자 디렉터리 경로는 다름
ssh ec2-user@$N1 sudo tail -f /var/log/pods/default_nginx-685c67bc9-pkvzd_69b28caf-7fe2-422b-aad8-f1f70a206d9e/nginx/0.log

2. host 로그 소스(Logs from /var/log/dmesg, /var/log/secure, and /var/log/messages), 노드(호스트) 로그

# 로그 위치 확인
#ssh ec2-user@$N1 sudo tree /var/log/ -L 1
#ssh ec2-user@$N1 sudo ls -la /var/log/
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo tree /var/log/ -L 1; echo; done
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo ls -la /var/log/; echo; done

# 호스트 로그 확인
#ssh ec2-user@$N1 sudo tail /var/log/dmesg
#ssh ec2-user@$N1 sudo tail /var/log/secure
#ssh ec2-user@$N1 sudo tail /var/log/messages
for log in dmesg secure messages; do echo ">>>>> Node1: /var/log/$log <<<<<"; ssh ec2-user@$N1 sudo tail /var/log/$log; echo; done
for log in dmesg secure messages; do echo ">>>>> Node2: /var/log/$log <<<<<"; ssh ec2-user@$N2 sudo tail /var/log/$log; echo; done
for log in dmesg secure messages; do echo ">>>>> Node3: /var/log/$log <<<<<"; ssh ec2-user@$N3 sudo tail /var/log/$log; echo; done

3. dataplane 로그 소스(/var/log/journal for kubelet.servicekubeproxy.service, and docker.service),
    쿠버네티스 데이터플레인 로그

# 로그 위치 확인
#ssh ec2-user@$N1 sudo tree /var/log/journal -L 1
#ssh ec2-user@$N1 sudo ls -la /var/log/journal
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo tree /var/log/journal -L 1; echo; done

# 저널 로그 확인 - 링크
ssh ec2-user@$N3 sudo journalctl -x -n 200
ssh ec2-user@$N3 sudo journalctl -f

3-4. CloudWatch Container Insight 설치 : cloudwatch-agent & fluent-bit - 링크 & Setting up Fluent Bit - Docs

# 설치
FluentBitHttpServer='On'
FluentBitHttpPort='2020'
FluentBitReadFromHead='Off'
FluentBitReadFromTail='On'
curl -s https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml | sed 's/{{cluster_name}}/'${CLUSTER_NAME}'/;s/{{region_name}}/'${AWS_DEFAULT_REGION}'/;s/{{http_server_toggle}}/"'${FluentBitHttpServer}'"/;s/{{http_server_port}}/"'${FluentBitHttpPort}'"/;s/{{read_from_head}}/"'${FluentBitReadFromHead}'"/;s/{{read_from_tail}}/"'${FluentBitReadFromTail}'"/' | kubectl apply -f -

# 설치 확인
kubectl get-all -n amazon-cloudwatch
kubectl get ds,pod,cm,sa -n amazon-cloudwatch
NAME                              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/cloudwatch-agent   3         3         3       3            3           kubernetes.io/os=linux   14s
daemonset.apps/fluent-bit         3         3         3       3            3           <none>                   14s

NAME                         READY   STATUS    RESTARTS   AGE
pod/cloudwatch-agent-46vv2   1/1     Running   0          14s
pod/cloudwatch-agent-vnght   1/1     Running   0          14s
pod/cloudwatch-agent-xn8sn   1/1     Running   0          14s
pod/fluent-bit-5cgjd         1/1     Running   0          14s
pod/fluent-bit-8p476         1/1     Running   0          14s
pod/fluent-bit-qr5mv         1/1     Running   0          14s

NAME                                DATA   AGE
configmap/cwagent-clusterleader     0      5s
configmap/cwagentconfig             1      14s
configmap/fluent-bit-cluster-info   6      14s
configmap/fluent-bit-config         5      14s
configmap/kube-root-ca.crt          1      14s

NAME                              SECRETS   AGE
serviceaccount/cloudwatch-agent   0         14s
serviceaccount/default            0         14s
serviceaccount/fluent-bit         0         14s

kubectl describe clusterrole cloudwatch-agent-role fluent-bit-role                          # 클러스터롤 확인
kubectl describe clusterrolebindings cloudwatch-agent-role-binding fluent-bit-role-binding  # 클러스터롤 바인딩 확인
kubectl -n amazon-cloudwatch logs -l name=cloudwatch-agent -f # 파드 로그 확인
kubectl -n amazon-cloudwatch logs -l k8s-app=fluent-bit -f    # 파드 로그 확인
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo ss -tnlp | grep fluent-bit; echo; done
>>>>> 192.168.1.244 <<<<<

LISTEN 0      128          0.0.0.0:2020       0.0.0.0:*    users:(("fluent-bit",pid=14354,fd=194)) 

>>>>> 192.168.2.199 <<<<<
LISTEN 0      128          0.0.0.0:2020       0.0.0.0:*    users:(("fluent-bit",pid=14959,fd=197)) 

>>>>> 192.168.3.101 <<<<<
LISTEN 0      128          0.0.0.0:2020       0.0.0.0:*    users:(("fluent-bit",pid=15384,fd=200)) 

# cloudwatch-agent 설정 확인
kubectl describe cm cwagentconfig -n amazon-cloudwatch
{
  "agent": {
    "region": "ap-northeast-2"
  },
  "logs": {
    "metrics_collected": {
      "kubernetes": {
        "cluster_name": "myeks",
        "metrics_collection_interval": 60
      }
    },
    "force_flush_interval": 5
  }
}

# CW 파드가 수집하는 방법 : Volumes에 HostPath를 살펴보자! >> / 호스트 패스 공유??? 보안상 안전한가? 좀 더 범위를 좁힐수는 없을까요?
kubectl describe -n amazon-cloudwatch ds cloudwatch-agent
...
ssh ec2-user@$N1 sudo tree /dev/disk
...

# Fluent Bit Cluster Info 확인
kubectl get cm -n amazon-cloudwatch fluent-bit-cluster-info -o yaml | yh
apiVersion: v1
data:
  cluster.name: myeks
  http.port: "2020"
  http.server: "On"
  logs.region: ap-northeast-2
  read.head: "Off"
  read.tail: "On"
kind: ConfigMap
...

# Fluent Bit 로그 INPUT/FILTER/OUTPUT 설정 확인 - 링크
## 설정 부분 구성 : application-log.conf , dataplane-log.conf , fluent-bit.conf , host-log.conf , parsers.conf
kubectl describe cm fluent-bit-config -n amazon-cloudwatch
...
application-log.conf:
----
[INPUT]
    Name                tail
    Tag                 application.*
    Exclude_Path        /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy*
    Path                /var/log/containers/*.log
    multiline.parser    docker, cri
    DB                  /var/fluent-bit/state/flb_container.db
    Mem_Buf_Limit       50MB
    Skip_Long_Lines     On
    Refresh_Interval    10
    Rotate_Wait         30
    storage.type        filesystem
    Read_from_Head      ${READ_FROM_HEAD}

[FILTER]
    Name                kubernetes
    Match               application.*
    Kube_URL            https://kubernetes.default.svc:443
    Kube_Tag_Prefix     application.var.log.containers.
    Merge_Log           On
    Merge_Log_Key       log_processed
    K8S-Logging.Parser  On
    K8S-Logging.Exclude Off
    Labels              Off
    Annotations         Off
    Use_Kubelet         On
    Kubelet_Port        10250
    Buffer_Size         0

[OUTPUT]
    Name                cloudwatch_logs
    Match               application.*
    region              ${AWS_REGION}
    log_group_name      /aws/containerinsights/${CLUSTER_NAME}/application
    log_stream_prefix   ${HOST_NAME}-
    auto_create_group   true
    extra_user_agent    container-insights
...

# Fluent Bit 파드가 수집하는 방법 : Volumes에 HostPath를 살펴보자!
kubectl describe -n amazon-cloudwatch ds fluent-bit
...
ssh ec2-user@$N1 sudo tree /var/log
...

# (참고) 삭제
curl -s https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml | sed 's/{{cluster_name}}/'${CLUSTER_NAME}'/;s/{{region_name}}/'${AWS_DEFAULT_REGION}'/;s/{{http_server_toggle}}/"'${FluentBitHttpServer}'"/;s/{{http_server_port}}/"'${FluentBitHttpPort}'"/;s/{{read_from_head}}/"'${FluentBitReadFromHead}'"/;s/{{read_from_tail}}/"'${FluentBitReadFromTail}'"/' | kubectl delete -f -
  • 로깅 확인 : CW → 로그 그룹

  • 메트릭 확인 : CW → 인사이트 → Container Insights


3-5. 로그 확인 : nginx 웹서버 - Docs

# 부하 발생
curl -s https://nginx.$MyDomain
yum install -y httpd
ab -c 500 -n 30000 https://nginx.$MyDomain/

# 파드 직접 로그 모니터링
kubectl logs deploy/nginx -f
  • 로그 그룹 → application → 로그 스트림 : nginx 필터링 ⇒ 클릭 후 확인 ⇒ ApacheBench 필터링 확인

  • Logs Insights
# Application log errors by container name : 컨테이너 이름별 애플리케이션 로그 오류
# 로그 그룹 선택 : /aws/containerinsights/<CLUSTER_NAME>/application
stats count() as error_count by kubernetes.container_name 
| filter stream="stderr" 
| sort error_count desc

# All Kubelet errors/warning logs for for a given EKS worker node
# 로그 그룹 선택 : /aws/containerinsights/<CLUSTER_NAME>/dataplane
fields @timestamp, @message, ec2_instance_id
| filter  message =~ /.*(E|W)[0-9]{4}.*/ and ec2_instance_id="<YOUR INSTANCE ID>"
| sort @timestamp desc

# Kubelet errors/warning count per EKS worker node in the cluster
# 로그 그룹 선택 : /aws/containerinsights/<CLUSTER_NAME>/dataplane
fields @timestamp, @message, ec2_instance_id
| filter   message =~ /.*(E|W)[0-9]{4}.*/
| stats count(*) as error_count by ec2_instance_id

# performance 로그 그룹
# 로그 그룹 선택 : /aws/containerinsights/<CLUSTER_NAME>/performance
# 노드별 평균 CPU 사용률
STATS avg(node_cpu_utilization) as avg_node_cpu_utilization by NodeName
| SORT avg_node_cpu_utilization DESC

# 파드별 재시작(restart) 카운트
STATS avg(number_of_container_restarts) as avg_number_of_container_restarts by PodName
| SORT avg_number_of_container_restarts DESC

# 요청된 Pod와 실행 중인 Pod 간 비교
fields @timestamp, @message 
| sort @timestamp desc 
| filter Type="Pod" 
| stats min(pod_number_of_containers) as requested, min(pod_number_of_running_containers) as running, ceil(avg(pod_number_of_containers-pod_number_of_running_containers)) as pods_missing by kubernetes.pod_name 
| sort pods_missing desc

# 클러스터 노드 실패 횟수
stats avg(cluster_failed_node_count) as CountOfNodeFailures 
| filter Type="Cluster" 
| sort @timestamp desc

# 파드별 CPU 사용량
stats pct(container_cpu_usage_total, 50) as CPUPercMedian by kubernetes.container_name 
| filter Type="Container"
| sort CPUPercMedian desc

3-6. 메트릭 확인 : CloudWatch → Insights → Container Insights : 우측 상단(Local Time Zone, 30분) ⇒ 리소스 : myeks 선택

  • Container map

  • 리소스 : 오른쪽 톱니바퀴 - Tx/Rx 클릭

  • 성능 모니터링 : [EKS] 클러스터, 노드, 네임스페이스, 서비스, 파드 등의 단위로 정보 출력 → 각각 변경해서 확인해보자!

  • 성능 모니터링 → 파드 : 특정 파드 선택 후 우측 상단에 작업 클릭 후 View performance logs 선택

  • CloudWatch Logs Insights 화면으로 리다이렉션됩니다. 쿼리를 통해, 원하는 로그를 확인 가능


4.  Metrics-server & kwatch & botkube

4-1. Metrics-server 확인 : kubelet으로부터 수집한 리소스 메트릭을 수집 및 집계하는 클러스터 애드온 구성 요소 - EKS Github Docs CMD

https://kubernetes.io/ko/docs/tasks/debug/debug-cluster/resource-metrics-pipeline/

# 배포
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# 메트릭 서버 확인 : 메트릭은 15초 간격으로 cAdvisor를 통하여 가져옴
kubectl get pod -n kube-system -l k8s-app=metrics-server
kubectl api-resources | grep metrics
kubectl get apiservices |egrep '(AVAILABLE|metrics)'

# 노드 메트릭 확인
kubectl top node

# 파드 메트릭 확인
kubectl top pod -A
kubectl top pod -n kube-system --sort-by='cpu'
kubectl top pod -n kube-system --sort-by='memory'

4-2. kwatch 소개 및 설치/사용 : kwatch는 Kubernetes(K8s) 클러스터의 모든 변경 사항을 모니터링하고, 실행 중인 앱의 충돌을 실시간으로 감지하고, 채널(Slack, Discord 등)에 즉시 알림을 게시하도록 도와줍니다.- 링크 Helm Blog

# 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://URL'
        title: $NICK-EKS
        #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

4-3. Botkube - 공홈 Blog

  • 슬랙 앱 설정 : SLACK_API_BOT_TOKEN 과 SLACK_API_APP_TOKEN 생성 - Docs
export SLACK_API_BOT_TOKEN='각자 토큰값'
export SLACK_API_APP_TOKEN='각자 토큰값'
  • 설치
# repo 추가
helm repo add botkube https://charts.botkube.io
helm repo update

# 변수 지정
export ALLOW_KUBECTL=true
export ALLOW_HELM=true
export SLACK_CHANNEL_NAME=webhook3

#
cat <<EOT > botkube-values.yaml
actions:
  'describe-created-resource': # kubectl describe
    enabled: true
  'show-logs-on-error': # kubectl logs
    enabled: true

executors:
  k8s-default-tools:
    botkube/helm:
      enabled: true
    botkube/kubectl:
      enabled: true
EOT

# 설치
helm install --version v1.0.0 botkube --namespace botkube --create-namespace \
--set communications.default-group.socketSlack.enabled=true \
--set communications.default-group.socketSlack.channels.default.name=${SLACK_CHANNEL_NAME} \
--set communications.default-group.socketSlack.appToken=${SLACK_API_APP_TOKEN} \
--set communications.default-group.socketSlack.botToken=${SLACK_API_BOT_TOKEN} \
--set settings.clusterName=${CLUSTER_NAME} \
--set 'executors.k8s-default-tools.botkube/kubectl.enabled'=${ALLOW_KUBECTL} \
--set 'executors.k8s-default-tools.botkube/helm.enabled'=${ALLOW_HELM} \
-f botkube-values.yaml botkube/botkube

# 참고 : 삭제 시
helm uninstall botkube --namespace botkube
# 연결 상태, notifications 상태 확인
@Botkube ping
@Botkube status notifications

# 파드 정보 조회
@Botkube k get pod
@Botkube kc get pod --namespace kube-system
@Botkube kubectl get pod --namespace kube-system -o wide

# Actionable notifications
@Botkube kubectl
  • 잘못된 이미지 파드 배포 및 확인
# 터미널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
@Botkube k get pod

# 이미지 업데이트 방안2 : set 사용 - iamge 등 일부 리소스 값을 변경 가능!
kubectl set 
kubectl set image pod nginx-19 nginx-pod=nginx:1.19
@Botkube k get pod

# 삭제
kubectl delete pod nginx-19
  • 삭제
helm uninstall botkube --namespace botkube

ChatGPT 활용

 

GitHub - robusta-dev/kubernetes-chatgpt-bot: A ChatGPT bot for Kubernetes issues.

A ChatGPT bot for Kubernetes issues. Contribute to robusta-dev/kubernetes-chatgpt-bot development by creating an account on GitHub.

github.com

 

GitHub - k8sgpt-ai/k8sgpt: Giving Kubernetes Superpowers to everyone

Giving Kubernetes Superpowers to everyone. Contribute to k8sgpt-ai/k8sgpt development by creating an account on GitHub.

github.com

 

PromptOps in application delivery: empowering your workflow with ChatGPT | Cloud Native Computing Foundation

Guest post by Fog Dong, Engineer at Alibaba Cloud, and Maintainer of KubeVela ChatGPT is taking the tech industry by storm, thanks to its unparalleled natural language processing capabilities.

www.cncf.io


5.  프로메테우스-스택

프로메테우스 오퍼레이터 : 프로메테우스 및 프로메테우스 오퍼레이터를 이용하여 메트릭 수집과 알람 기능 실습

 

pkos 스터디 4주차 - 메트릭 오픈소스 프로메테우스

4주 차에서는 메트릭 오픈소스인 프로메테우스 오퍼레이터를 공부했습니다. 프로메테우스 오퍼레이터를 이용하여 메트릭 수집방법과 알림기능 실습했습니다. 이번 주차에는 github copilot도움을

malwareanalysis.tistory.com

Thanos 타노드 : 프로메테우스 확장성과 고가용성 제공

 

[PKOS] Thanos를 통한 고가용성 모니터링(프로메테우스) 시스템 구축하기 | HanHoRang Tech Blog

고가용성 모니터링 시스템 구축(프로메테우스, 타노스)

hanhorang31.github.io


5-1 소개 : 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 HTTP질문 PushPull 수집 방식 장단점? - 링크
  • 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

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

구성 요소


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

  • kube-prometheus-stack Kubernetes 매니페스트, Grafana 대시보드, 문서 스크립트와 결합된 Prometheus 규칙 수집하여 Prometheus Operator 사용하여 Prometheus에서 엔드 엔드 Kubernetes 클러스터 모니터링을 쉽게 운영할 있도록 합니다.
# 모니터링
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"

  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'

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

# alertmanager:
#   ingress:
#     enabled: true
#     ingressClassName: alb
#     hosts: 
#       - alertmanager.$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'
EOT
cat monitor-values.yaml | yh

# 배포
helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.27.2 \
--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
NAME                 	NAMESPACE 	REVISION	UPDATED                                	STATUS  	CHART                        	APP VERSION
kube-prometheus-stack	monitoring	1       	2023-05-26 14:27:51.037346748 +0900 KST	deployed	kube-prometheus-stack-45.27.2	v0.65.1 

kubectl get pod,svc,ingress -n monitoring
NAME                                                            READY   STATUS    RESTARTS   AGE
pod/kube-prometheus-stack-grafana-548f6c896f-jxlnr              3/3     Running   0          54s
pod/kube-prometheus-stack-kube-state-metrics-5d6578867c-8wxss   1/1     Running   0          54s
pod/kube-prometheus-stack-operator-74d474b47b-xsrf5             1/1     Running   0          54s
pod/kube-prometheus-stack-prometheus-node-exporter-d4kgs        1/1     Running   0          55s
pod/kube-prometheus-stack-prometheus-node-exporter-d8tkd        1/1     Running   0          54s
pod/kube-prometheus-stack-prometheus-node-exporter-lkmg2        1/1     Running   0          54s
pod/prometheus-kube-prometheus-stack-prometheus-0               2/2     Running   0          49s

NAME                                                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/kube-prometheus-stack-grafana                    ClusterIP   10.100.222.56    <none>        80/TCP     55s
service/kube-prometheus-stack-kube-state-metrics         ClusterIP   10.100.59.57     <none>        8080/TCP   55s
service/kube-prometheus-stack-operator                   ClusterIP   10.100.224.16    <none>        443/TCP    55s
service/kube-prometheus-stack-prometheus                 ClusterIP   10.100.221.217   <none>        9090/TCP   55s
service/kube-prometheus-stack-prometheus-node-exporter   ClusterIP   10.100.72.224    <none>        9100/TCP   55s
service/prometheus-operated                              ClusterIP   None             <none>        9090/TCP   49s

NAME                                                         CLASS   HOSTS                      ADDRESS                                                         PORTS   AGE
ingress.networking.k8s.io/kube-prometheus-stack-grafana      alb     grafana.pjhtest.click      myeks-ingress-alb-1741080976.ap-northeast-2.elb.amazonaws.com   80      54s
ingress.networking.k8s.io/kube-prometheus-stack-prometheus   alb     prometheus.pjhtest.click   myeks-ingress-alb-1741080976.ap-northeast-2.elb.amazonaws.com   80      54s

kubectl get-all -n monitoring
kubectl get prometheus,servicemonitors -n monitoring
kubectl get crd | grep monitoring
alertmanagerconfigs.monitoring.coreos.com    2023-05-26T05:27:47Z
alertmanagers.monitoring.coreos.com          2023-05-26T05:27:48Z
podmonitors.monitoring.coreos.com            2023-05-26T05:27:48Z
probes.monitoring.coreos.com                 2023-05-26T05:27:48Z
prometheuses.monitoring.coreos.com           2023-05-26T05:27:48Z
prometheusrules.monitoring.coreos.com        2023-05-26T05:27:49Z
servicemonitors.monitoring.coreos.com        2023-05-26T05:27:49Z
thanosrulers.monitoring.coreos.com           2023-05-26T05:27:49Z
  • AWS ELB(ALB) 갯수 확인 → Rule 확인(어떻게 여러 도메인 처리를 하는 걸까?) ⇒ HTTP(80) 인입 시 어떻게 처리하나요?

  • (참고) kube-controller-manager, kube-scheduler 수집 불가? - 구글링

  • 프로메테우스 웹 → Status → Targets 확인 : kube-controller-manager, kube-scheduler 없음 확인

  • (참고) 삭제 시
# helm 삭제
helm uninstall -n monitoring kube-prometheus-stack

# crd 삭제
kubectl delete crd alertmanagerconfigs.monitoring.coreos.com
kubectl delete crd alertmanagers.monitoring.coreos.com
kubectl delete crd podmonitors.monitoring.coreos.com
kubectl delete crd probes.monitoring.coreos.com
kubectl delete crd prometheuses.monitoring.coreos.com
kubectl delete crd prometheusrules.monitoring.coreos.com
kubectl delete crd servicemonitors.monitoring.coreos.com
kubectl delete crd thanosrulers.monitoring.coreos.com

5-3. 프로메테우스 기본 사용 : 모니터링 그래프

  • 모니터링 대상이 되는 서비스는 일반적으로 자체 웹 서버의 /metrics 엔드포인트 경로에 다양한 메트릭 정보를 노출
  • 이후 프로메테우스는 해당 경로에 http get 방식으로 메트릭 정보를 가져와 TSDB 형식으로 저장
# 아래 처럼 프로메테우스가 각 서비스의 9100 접속하여 메트릭 정보를 수집
kubectl get node -owide
kubectl get svc,ep -n monitoring kube-prometheus-stack-prometheus-node-exporter

# 노드의 9100번의 /metrics 접속 시 다양한 메트릭 정보를 확인할수 있음 : 마스터 이외에 워커노드도 확인 가능
ssh ec2-user@$N1 curl -s localhost:9100/metrics
  • 프로메테우스 ingress 도메인으로 웹 접속
# 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 : ?
  • 프로메테우스 설정(Configuration) 확인 : Status → Runtime & Build Information 클릭
    • Storage retention : 5d or 10GiB → 메트릭 저장 기간이 5일 경과 혹은 10GiB 이상 시 오래된 것부터 삭제 ⇒ helm 파라미터에서 수정 가능
  • 프로메테우스 설정(Configuration) 확인 : Status → Command-Line Flags 클릭
    • -log.level : info
    • -storage.tsdb.retention.size : 10GiB
    • -storage.tsdb.retention.time : 5d
  • 프로메테우스 설정(Configuration) 확인 : Status → Configuration ⇒ “node-exporter” 검색
    • job name 을 기준으로 scraping
global:
  scrape_interval: 15s     # 메트릭 가져오는(scrape) 주기
  scrape_timeout: 10s      # 메트릭 가져오는(scrape) 타임아웃
  evaluation_interval: 15s # alert 보낼지 말지 판단하는 주기
...
- job_name: serviceMonitor/monitoring/kube-prometheus-stack-prometheus-node-exporter/0
  scrape_interval: 30s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
...
kubernetes_sd_configs:    # 서비스 디스커버리(SD) 방식을 이용하고, 파드의 엔드포인트 List 자동 반영
  - role: endpoints
    kubeconfig_file: ""
    follow_redirects: true
    enable_http2: true
    namespaces:
      own_namespace: false
      names:
      - monitoring        # 서비스 엔드포인트가 속한 네임 스페이스 이름을 지정, 서비스 네임스페이스가 속한 포트 번호를 구분하여 메트릭 정보를 가져옴
  • 전체 메트릭 대상(Targets) 확인 : Status → Targets
    • 해당 스택은 ‘노드-익스포터’, cAdvisor, 쿠버네티스 전반적인 현황 이외에 다양한 메트릭을 포함
    • 현재 각 Target 클릭 시 메트릭 정보 확인 : 아래 예시
# serviceMonitor/monitoring/kube-prometheus-stack-kube-proxy/0 (3/3 up) 중 노드1에 Endpoint 접속 확인 (접속 주소는 실습 환경에 따라 다름)
curl -s http://192.168.1.216:10249/metrics | tail -n 5
rest_client_response_size_bytes_bucket{host="006fc3f3f0730a7fb3fdb3181f546281.gr7.ap-northeast-2.eks.amazonaws.com",verb="POST",le="4.194304e+06"} 1
rest_client_response_size_bytes_bucket{host="006fc3f3f0730a7fb3fdb3181f546281.gr7.ap-northeast-2.eks.amazonaws.com",verb="POST",le="1.6777216e+07"} 1
rest_client_response_size_bytes_bucket{host="006fc3f3f0730a7fb3fdb3181f546281.gr7.ap-northeast-2.eks.amazonaws.com",verb="POST",le="+Inf"} 1
rest_client_response_size_bytes_sum{host="006fc3f3f0730a7fb3fdb3181f546281.gr7.ap-northeast-2.eks.amazonaws.com",verb="POST"} 626
rest_client_response_size_bytes_count{host="006fc3f3f0730a7fb3fdb3181f546281.gr7.ap-northeast-2.eks.amazonaws.com",verb="POST"} 1

# serviceMonitor/monitoring/kube-prometheus-stack-api-server/0 (2/2 up) 중 Endpoint 접속 확인 (접속 주소는 실습 환경에 따라 다름) 
>> 해당 IP주소는 어디인가요?, 왜 apiserver endpoint는 2개뿐인가요? , 아래 메트릭 수집이 되게 하기 위해서는 어떻게 하면 될까요?
curl -s https://192.168.1.53/metrics | tail -n 5
...

# 그외 다른 타켓의 Endpoint 로 접속 확인 가능 : 예시) 아래는 coredns 의 Endpoint 주소 (접속 주소는 실습 환경에 따라 다름)
curl -s http://192.168.1.75:9153/metrics | tail -n 5
# TYPE process_virtual_memory_bytes gauge
process_virtual_memory_bytes 7.79350016e+08
# HELP process_virtual_memory_max_bytes Maximum amount of virtual memory available in bytes.
# TYPE process_virtual_memory_max_bytes gauge
process_virtual_memory_max_bytes 1.8446744073709552e+19

  • 프로메테우스 설정(Configuration) 확인 : Status → Service Discovery : 모든 endpoint 로 도달 가능 시 자동 발견!, 도달 규칙은 설정Configuration 파일에 정의
    • 예) serviceMonitor/monitoring/kube-prometheus-stack-apiserver/0 경우 해당 address="192.168.1.53:443" 도달 가능 시 자동 발견됨
  • 메트릭을 그래프(Graph)로 조회 : Graph - 아래 PromQL 쿼리(전체 클러스터 노드의 CPU 사용량 합계)입력 후 조회 → Graph 확인
    • 혹은 지구 아이콘(Metrics Explorer) 클릭 시 전체 메트릭 출력되며, 해당 메트릭 클릭해서 확인
1- avg(rate(node_cpu_seconds_total{mode="idle"}[1m]))

# 노드 메트릭
node 입력 후 자동 출력되는 메트릭 확인 후 선택
node_boot_time_seconds

# kube 메트릭
kube 입력 후 자동 출력되는 메트릭 확인 후 선택

6.  그라파나 Grafana

6-1. 소개 및 웹 접속 : TSDB 데이터를 시각화, 다양한 데이터 형식 지원(메트릭, 로그, 트레이스 등) - 링크 9.5

  • Grafana open source software enables you to query, visualize, alert on, and explore your metrics, logs, and traces wherever they are stored.
    • Grafana OSS는 시계열 데이터베이스(TSDB) 데이터를 통찰력 있는 그래프 및 시각화로 변환하는 도구를 제공합니다.
  • 그라파나는 시각화 솔루션으로 데이터 자체를 저장하지 않음 → 현재 실습 환경에서는 데이터 소스프로메테우스를 사용
  • 접속 정보 확인 및 로그인 : 기본 계정 - admin / prom-operator
# 그라파나 버전 확인
kubectl exec -it -n monitoring deploy/kube-prometheus-stack-grafana -- grafana-cli --version
grafana cli version 9.5.1

# ingress 확인
kubectl get ingress -n monitoring kube-prometheus-stack-grafana
kubectl describe ingress -n monitoring kube-prometheus-stack-grafana
Name:             kube-prometheus-stack-grafana
Labels:           app.kubernetes.io/instance=kube-prometheus-stack
                  app.kubernetes.io/managed-by=Helm
                  app.kubernetes.io/name=grafana
                  app.kubernetes.io/version=9.5.1
                  helm.sh/chart=grafana-6.56.2
Namespace:        monitoring
Address:          myeks-ingress-alb-1658946598.ap-northeast-2.elb.amazonaws.com
Ingress Class:    alb
Default backend:  <default>
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  grafana.pjhtest.click  
                         /   kube-prometheus-stack-grafana:80 (192.168.1.211:3000)
Annotations:             alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:207748141400:certificate/8d18f11b-e794-403e-87b6-b9b4313c33df
                         alb.ingress.kubernetes.io/group.name: study
                         alb.ingress.kubernetes.io/listen-ports: [{"HTTPS":443}, {"HTTP":80}]
                         alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
                         alb.ingress.kubernetes.io/scheme: internet-facing
                         alb.ingress.kubernetes.io/ssl-redirect: 443
                         alb.ingress.kubernetes.io/success-codes: 200-399
                         alb.ingress.kubernetes.io/target-type: ip
                         meta.helm.sh/release-name: kube-prometheus-stack
                         meta.helm.sh/release-namespace: monitoring
Events:
  Type    Reason                  Age                From     Message
  ----    ------                  ----               ----     -------
  Normal  SuccessfullyReconciled  66s (x2 over 68s)  ingress  Successfully reconciled

# ingress 도메인으로 웹 접속 : 기본 계정 - admin / prom-operator
echo -e "Grafana Web URL = https://grafana.$MyDomain"
Grafana Web URL = https://grafana.pjhtest.click

  • 우측 상단 : admin 사용자의 개인 설정
  • 기본 대시보드 확인

  1. Search dashboards : 대시보드 검색
  2. Starred : 즐겨찾기 대시보드
  3. Dashboards : 대시보드 전체 목록 확인
  4. Explore : 쿼리 언어 PromQL를 이용해 메트릭 정보를 그래프 형태로 탐색
  5. Alerting : 경고, 에러 발생 시 사용자에게 경고를 전달
  6. Connections : 설정, 예) 데이터 소스 설정 등
  7. Administartor : 사용자, 조직, 플러그인 등 설정
  • Connections → Your connections : 스택의 경우 자동으로 프로메테우스를 데이터 소스로 추가해둠 ← 서비스 주소 확인

# 서비스 주소 확인
kubectl get svc,ep -n monitoring kube-prometheus-stack-prometheus
NAME                                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/kube-prometheus-stack-prometheus   ClusterIP   10.100.242.174   <none>        9090/TCP   6m27s

NAME                                         ENDPOINTS           AGE
endpoints/kube-prometheus-stack-prometheus   192.168.3.42:9090   6m27s
  • 해당 데이터 소스 접속 확인
# 테스트용 파드 배포
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Pod
metadata:
  name: netshoot-pod
spec:
  containers:
  - name: netshoot-pod
    image: nicolaka/netshoot
    command: ["tail"]
    args: ["-f", "/dev/null"]
  terminationGracePeriodSeconds: 0
EOF
kubectl get pod netshoot-pod
NAME           READY   STATUS    RESTARTS   AGE
netshoot-pod   1/1     Running   0          18s

# 접속 확인
kubectl exec -it netshoot-pod -- nslookup kube-prometheus-stack-prometheus.monitoring
kubectl exec -it netshoot-pod -- curl -s kube-prometheus-stack-prometheus.monitoring:9090/graph -v ; echo

# 삭제
kubectl delete pod netshoot-pod

6-2. 대시보드 사용 : 기본 대시보드와 공식 대시보드 가져오기

기본 대시보드

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

공식 대시보드 가져오기 - 링크 추천

  • [Kubernetes / Views / Global] Dashboard → New → Import → 15757 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • [1 Kubernetes All-in-one Cluster Monitoring KR] Dashboard → New → Import → 13770 or 17900 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • [Node Exporter Full] Dashboard → New → Import → 1860 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • kube-state-metrics-v2 가져와보자 : Dashboard ID copied! (13332) 클릭 - 링크
    • [kube-state-metrics-v2] Dashboard → New → Import → 13332 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • [Amazon EKS] **AWS CNI Metrics 16032 - 링크
# 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


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

  • 서비스모니터 동작

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

  • nginx 를 helm 설치 시 프로메테우스 익스포터 Exporter 옵션 설정 시 자동으로 nginx 를 프로메테우스 모니터링에 등록 가능!
    • 프로메테우스 설정에서 nginx 모니터링 관련 내용을 서비스 모니터 CRD로 추가 가능!
  • 기존 애플리케이션 파드에 프로메테우스 모니터링을 추가하려면 사이드카 방식을 사용하며 exporter 컨테이너를 추가!
  • nginx 웹 서버(with helm)에 metrics 수집 설정 추가 - Helm
# 모니터링
watch -d kubectl get pod

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

  service:
    port: 9113

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

# 배포
helm repo add bitnami https://charts.bitnami.com/bitnami
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
  • 서비스 모니터링 생성 후 1분 정도 후에 프로메테우스 웹서버에서 State → Targets 에 nginx 서비스 모니터 추가 확인

 

  • Graph → nginx_ 입력 시 다양한 메트릭 추가 확인 : nginx_connections_active 등

6-4. NGINX 애플리케이션 모니터링 대시보드 추가

  • 그라파나에 12708 대시보드 추가


7.  그라파나 얼럿 Alert

참고 : 그라파나 9.4 버전이 2월 28일 출시 - 링크Alerting 기능이 강화되었고, 이미지 알람 기능도 제공 - 링크
그라파나 9.5 버전이 Alerting 기능 업데이트 - 링크


7-1. 그라파나 얼럿 Docs - 링크 Workshop Blog1 Blog2

- 그라파나 → Alerting → Alert ruels → Create alert rule : nginx 웹 요청 1분 동안 누적 600 이상 시 Alert 설정

  • 아래 Folder 과 Evaluation group 은 +Add new 클릭 후 신규로 만들어 주자

⇒ 오른쪽 상단 Save and exit 클릭


- Contact points → Add contact point 클릭

  • Integration : 슬랙
  • Webhook URL : 각자 웹훅 URL 입력
  • Optional Slack settings → Username : 메시지 구분을 위해서 각자 자신의 닉네임 입력
  • 오른쪽 상단 : Test 해보고 저장


- Notification policies : 기본 정책 수정 Edit - Default contact point(slack)


- nginx 반복 접속 실행 후 슬랙 채널 알람 확인

while true; do curl -s https://nginx.$MyDomain -I | head -n 1; date; sleep 1; done

  • 메트릭 이미지 포함 알람 : 그라파나 이미지를 포함한 슬랙 얼럿 설정 - 링크 & Grafana - Image Render Plugin & Slack Alert 연동 - 링크

8.  kubecost

소개 : OpenCost 링크를 기반으로 구축되었으며 AWS에서 적극 지원, 쿠버네티스 리소스별 비용 분류 가시화 제공

  • Pricing - 링크 : Free(메트릭 15일 보존, Business(메트릭 30일 보존, …), Enterprise(.)
  • Amazon EKS cost monitoring with Kubecost architecture - 링크


설치 및 웹 접속 - 링크 Chart Gallery

  • ingress, service(nlb) 통한 접속은 왜인지 실패… 멤버분들 테스트 해보세요! 링크 링크2 → bastion ec2를 통한 ssh port forwarding 통한 접속 방식으로 우회
# 
cat <<EOT > cost-values.yaml
global:
  grafana:
    enabled: true
    proxy: false

priority:
  enabled: false
networkPolicy:
  enabled: false
podSecurityPolicy:
  enabled: false

persistentVolume:
    storageClass: "gp3"

prometheus:
  kube-state-metrics:
    disabled: false
  nodeExporter:
    enabled: true

reporting:
  productAnalytics: true
EOT

# kubecost chart 에 프로메테우스가 포함되어 있으니, 기존 프로메테우스-스택은 삭제하자 : node-export 포트 충돌 발생
helm uninstall -n monitoring kube-prometheus-stack

# 배포
kubectl create ns kubecost
helm install kubecost oci://public.ecr.aws/kubecost/cost-analyzer --version 1.103.2 --namespace kubecost -f cost-values.yaml

# 배포 확인
kubectl get-all -n kubecost
kubectl get all -n kubecost
NAME                                              READY   STATUS    RESTARTS   AGE
pod/kubecost-cost-analyzer-996544d88-j79wt        2/2     Running   0          78s
pod/kubecost-grafana-867bbf59c7-qs2wl             2/2     Running   0          79s
pod/kubecost-kube-state-metrics-d6d9b7594-xh5qw   1/1     Running   0          78s
pod/kubecost-prometheus-node-exporter-76prk       1/1     Running   0          78s
pod/kubecost-prometheus-node-exporter-mgvdw       1/1     Running   0          78s
pod/kubecost-prometheus-node-exporter-wfknl       1/1     Running   0          79s
pod/kubecost-prometheus-server-77bd8b8d6f-pppbr   2/2     Running   0          79s

NAME                                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
service/kubecost-cost-analyzer              ClusterIP   10.100.232.13    <none>        9003/TCP,9090/TCP   79s
service/kubecost-grafana                    ClusterIP   10.100.129.128   <none>        80/TCP              79s
service/kubecost-kube-state-metrics         ClusterIP   10.100.135.107   <none>        8080/TCP            79s
service/kubecost-prometheus-node-exporter   ClusterIP   None             <none>        9100/TCP            79s
service/kubecost-prometheus-server          ClusterIP   10.100.3.58      <none>        80/TCP              79s

NAME                                               DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/kubecost-prometheus-node-exporter   3         3         3       3            3           <none>          79s

NAME                                          READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kubecost-cost-analyzer        1/1     1            1           79s
deployment.apps/kubecost-grafana              1/1     1            1           79s
deployment.apps/kubecost-kube-state-metrics   1/1     1            1           79s
deployment.apps/kubecost-prometheus-server    1/1     1            1           79s

NAME                                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/kubecost-cost-analyzer-996544d88        1         1         1       79s
replicaset.apps/kubecost-grafana-867bbf59c7             1         1         1       79s
replicaset.apps/kubecost-kube-state-metrics-d6d9b7594   1         1         1       79s
replicaset.apps/kubecost-prometheus-server-77bd8b8d6f   1         1         1       79s


# kubecost-cost-analyzer 파드 IP변수 지정 및 접속 확인
CAIP=$(kubectl get pod -n kubecost -l app=cost-analyzer -o jsonpath={.items[0].status.podIP})
curl -s $CAIP:9090

# 외부에서 bastion EC2 접속하여 특정 파드 접속 방법 : socat(SOcket CAT) 활용 - 링크
yum -y install socat
socat TCP-LISTEN:80,fork TCP:$CAIP:9090
웹 브라우저에서 bastion EC2 IP로 접속

  • 사용법 - 링크1 링크2
  • 삭제: helm uninstall -n kubecost kubecost

9.  AWS 관리형 서비스 AMP & AMG

 

EKS 스터디 - 4주차 3편 - AMP에 EKS메트릭 저장

안녕하세요. 이 글은 EKS메트릭을 AMP(AWS Managed Prometheus)에 저장하고 AMG(AWS Managed Grafana)에서 시각화하는 방법을 설명합니다. AMP란? AMP(Amazon Managed Prometheus)는 서버리스 프로메테우스입니다. AWS가 프

malwareanalysis.tistory.com


(실습 완료 후) 자원 삭제

  • Helm Chart 삭제
helm uninstall -n kube-system kube-ops-view
helm uninstall nginx
helm uninstall botkube --namespace botkube
helm uninstall -n monitoring kube-prometheus-stack
  • 삭제
eksctl delete cluster --name $CLUSTER_NAME && aws cloudformation delete-stack --stack-name $CLUSTER_NAME
  • (옵션) 로깅 삭제 : 위에서 삭제 안 했을 경우 삭제
# EKS Control Plane 로깅(CloudWatch Logs) 비활성화
eksctl utils update-cluster-logging --cluster $CLUSTER_NAME --region $AWS_DEFAULT_REGION --disable-types all --approve
# 로그 그룹 삭제 : 컨트롤 플레인
aws logs delete-log-group --log-group-name /aws/eks/$CLUSTER_NAME/cluster

---
# 로그 그룹 삭제 : 데이터 플레인
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/application
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/dataplane
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/host
aws logs delete-log-group --log-group-name /aws/containerinsights/$CLUSTER_NAME/performance
728x90
반응형

'EKS' 카테고리의 다른 글

EKS CloudFormation  (0) 2024.03.03
5주차 - EKS Autoscaling  (0) 2023.05.30
EKS 3주차 - EKS Storage & Node 관리  (0) 2023.05.12
EKS 2주차 - EKS Networking  (0) 2023.05.09
EKS 1주차 - Amzaon EKS 설치 및 기본 사용  (0) 2023.04.26
Comments