AWS/[AEWS] EKS

[ AEWS 4주차 ] 정리

BigCo 2024. 3. 30. 17:54

1. Logging in EKS 란?


AWS EKS (Amazon Elastic Kubernetes Service) 로깅은 AWS EKS 클러스터에서 발생하는 로그를 수집, 저장, 및 분석하는 프로세스를 가리킵니다. Kubernetes 클러스터에서 실행되는 애플리케이션 및 서비스에 대한 로그를 관리하기 위해 중요합니다.

AWS EKS 로깅은 다음과 같은 목적으로 사용됩니다:

1. 문제 해결 및 디버깅: 애플리케이션 또는 서비스에 문제가 발생할 때 로그는 해당 문제를 해결하는 데 중요한 정보를 제공합니다. 로그를 통해 애플리케이션의 동작을 이해하고, 잠재적인 문제를 식별하고, 디버깅할 수 있습니다.

2. 보안 감사 및 준수: 보안 이벤트 및 중요한 작업을 추적하기 위해 로그는 보안 감사 및 준수 요구 사항을 충족하는 데 사용될 수 있습니다.

3. 성능 모니터링 및 최적화: 로그는 애플리케이션의 성능을 모니터링하고, 리소스 사용을 최적화하며, 확장 및 조정을 위한 인사이트를 제공합니다.

 


AWS EKS 로깅은 일반적으로 다음과 같은 방법으로 구현됩니다


1. Amazon CloudWatch Logs: AWS EKS 클러스터에서 발생하는 로그를 수집하고 저장하는 데 사용됩니다. CloudWatch Logs는 로그 그룹을 생성하여 로그를 저장하고, 필터링하고, 검색하고, 모니터링할 수 있는 기능을 제공합니다.

2. Amazon S3: 로그를 보관하고 장기 보존을 위해 Amazon S3에 저장할 수 있습니다.

3. Amazon Elasticsearch Service (Amazon ES): 로그를 수집하고 검색 및 분석하기 위해 Amazon ES에 로그를 전송할 수 있습니다.

4, AWS Partner Solutions: AWS 파트너 솔루션을 사용하여 로그를 수집, 분석 및 시각화할 수 있습니다.

이러한 방법을 사용하여 AWS EKS 로깅을 설정하면 클러스터에서 발생하는 로그를 효과적으로 관리하고 분석하여 애플리케이션의 안정성, 보안 및 성능을 향상시킬 수 있습니다.

 

 

#2. 실습환경 배포

# YAML 파일 다운로드
curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick3.yaml

# CloudFormation 스택 배포
예시) aws cloudformation deploy --template-file eks-oneclick3.yaml --stack-name myeks --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32  MyIamUserAccessKeyID=AKIA5... MyIamUserSecretAccessKey='CVNa2...' 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 ~/.ssh/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)
or
ssh -i ~/.ssh/kp-gasida.pem root@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)
~ password: qwe123
기본설정

# default 네임스페이스 적용
kubectl ns default

# 노드 정보 확인 : t3.xlarge
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
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

# 노드 보안그룹 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 -o StrictHostKeyChecking=no ec2-user@$node hostname; done

 

AWS LB/ExternalDNS/EBS, kube-ops-view 설치

# ExternalDNS
MyDomain=<자신의 도메인>
echo "export MyDomain=<자신의 도메인>" >> /etc/profile
MyDomain=gasida.link
echo "export MyDomain=gasida.link" >> /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 -

# 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"

# 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
kubectl apply -f https://raw.githubusercontent.com/gasida/PKOS/main/aews/gp3-sc.yaml
kubectl get 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

# EC2 Instance Profile에 IAM Role 정보 확인
cat myeks.yaml | grep managedNodeGroups -A20 | yh
managedNodeGroups: 
- amiFamily: AmazonLinux2
  desiredCapacity: 3
  disableIMDSv1: true
  disablePodIMDS: false
  iam: 
    withAddonPolicies: 
      albIngress: false
      appMesh: false
      appMeshPreview: false
      autoScaler: false
      awsLoadBalancerController: false  >> IRSA 사용
      certManager: true
      cloudWatch: true
      ebs: true
      efs: false
      externalDNS: true
      fsx: false
      imageBuilder: true
      xRay: true

 

 

# Control Plane loggin 로그이름(/aws/eks/<cluster-name>/cluster)

 

  • 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
    
    • CloudWatch Log Insight Query with AWS CLI
    # CloudWatch Log Insight Query
    aws logs get-query-results --query-id $(aws logs start-query \\
    --log-group-name '/aws/eks/myeks/cluster' \\
    --start-time `date -d "-1 hours" +%s` \\
    --end-time `date +%s` \\
    --query-string 'fields @timestamp, @message | filter @logStream ~= "kube-scheduler" | sort @timestamp desc' \\
    | jq --raw-output '.queryId')
    
    • 로깅 끄기
    • 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
      
      • CloudWatch Log Insight Query with AWS CLI
      # CloudWatch Log Insight Query
      aws logs get-query-results --query-id $(aws logs start-query \\
      --log-group-name '/aws/eks/myeks/cluster' \\
      --start-time `date -d "-1 hours" +%s` \\
      --end-time `date +%s` \\
      --query-string 'fields @timestamp, @message | filter @logStream ~= "kube-scheduler" | sort @timestamp desc' \\
      | jq --raw-output '.queryId')
      
      • 로깅 끄기
      # 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
      

 

 

# NGIN 웹서버 배포 (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

# 파라미터 파일 생성 : 인증서 ARN 지정하지 않아도 가능! 혹시 https 리스너 설정 안 될 경우 인증서 설정 추가(주석 제거)해서 배포 할 것
cat <<EOT > nginx-values.yaml
service:
  type: NodePort
  
networkPolicy:
  enabled: false

ingress:
  enabled: true
  ingressClassName: alb
  hostname: nginx.$MyDomain
  pathType: Prefix
  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 15.14.0 -f nginx-values.yaml

# 확인
kubectl get ingress,deploy,svc,ep nginx
kubectl get targetgroupbindings # ALB TG 확인

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

## 외부에서는 접속이 잘되나, myeks EC2에서 url 접속이 잘 되지 않을 경우 : 이전 aws DNS cache 영향(추정)
dig +short nginx.$MyDomain
dig +short nginx.$MyDomain @192.168.0.2
dig +short nginx.$MyDomain @1.1.1.1
dig +short nginx.$MyDomain @8.8.8.8
cat /etc/resolv.conf
sed -i "s/^nameserver 192.168.0.2/nameserver 1.1.1.1/g" /etc/resolv.conf
cat /etc/resolv.conf
dig +short nginx.$MyDomain
dig +short nginx.$MyDomain @8.8.8.8
dig +short nginx.$MyDomain @192.168.0.2
curl -s https://nginx.$MyDomain
----

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

# (참고) 삭제 시
helm uninstall nginx

 

 

 

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

  • 수집] 플루언트비트 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 의 대시보드로 시각화한다

 

  • 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 클러스터에서 사용 가능합니다.

 

노드의 로그 확인

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

 

# 로그 위치 확인
#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

# 설치
aws eks create-addon --cluster-name $CLUSTER_NAME --addon-name amazon-cloudwatch-observability
aws eks list-addons --cluster-name myeks --output table

# 설치 확인
kubectl get-all -n amazon-cloudwatch
kubectl get ds,pod,cm,sa,amazoncloudwatchagent -n amazon-cloudwatch
kubectl describe clusterrole cloudwatch-agent-role amazon-cloudwatch-observability-manager-role    # 클러스터롤 확인
kubectl describe clusterrolebindings cloudwatch-agent-role-binding amazon-cloudwatch-observability-manager-rolebinding  # 클러스터롤 바인딩 확인
kubectl -n amazon-cloudwatch logs -l app.kubernetes.io/component=amazon-cloudwatch-agent -f # 파드 로그 확인
kubectl -n amazon-cloudwatch logs -l k8s-app=fluent-bit -f    # 파드 로그 확인

# cloudwatch-agent 설정 확인
kubectl describe cm cloudwatch-agent-agent -n amazon-cloudwatch

#Fluent bit 파드 수집하는 방법 : Volumes에 HostPath를 살펴보자! >> / 호스트 패스 공유??? 보안상 안전한가? 좀 더 범위를 좁힐수는 없을까요? 
kubectl describe -n amazon-cloudwatch ds cloudwatch-agent
...
  Volumes:
   ...
   rootfs:
    Type:          HostPath (bare host directory volume)
    Path:          /
    HostPathType:  

...
ssh ec2-user@$N1 sudo tree /dev/disk
...


# 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
...

# (참고) 삭제
aws eks delete-addon --cluster-name $CLUSTER_NAME --addon-name amazon-cloudwatch-observability

 

 

 

Fluent bit 파드가 수집하는 방법 : Volumes에 HostPath

  • host에서 사용하는 docker.sock가 Pod에 mount 되어있는 상태에서 악의적인 사용자가 해당 Pod에 docker만 설치할 수 있다면, mount된 dock.sock을 이용하여 host의 docker에 명령을 보낼 수 있게 된다(docker가 client-server 구조이기 때문에 가능).이는 container escape라고도 할 수 있다.

 

 

로그 확인 : nginx 웹서버

# 부하 발생
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 필터링 확인

# 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

 

 

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

 

  • 성능 모니터링 : [EKS] 클러스터, 노드, 네임스페이스, 서비스, 파드 등의 단위로 정보 출력 → 각각 변경해서 확인해보자!
  • 성능 모니터링 → 파드 : 특정 파드 선택 후 우측 상단에 작업 클릭 후 View performance logs 선택
    • CloudWatch Logs Insights 화면으로 리다이렉션됩니다. 쿼리를 통해, 원하는 로그를 확인 가능
      • 성능 모니터링 : [EKS] 클러스터, 노드, 네임스페이스, 서비스, 파드 등의 단위로 정보 출력 → 각각 변경해서 확인해보자

 

 

 

 

#4. Metrics-server & kwatch & botkube

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

# 배포
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'

 

# 닉네임
NICK=<각자 자신의 닉네임>
NICK=gasida

# configmap 생성
cat <<EOT > ~/kwatch-config.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: kwatch
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: kwatch
  namespace: kwatch
data:
  config.yaml: |
    alert:
      slack:
        webhook: 'https://hooks.slack.com/services/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'
        title: $NICK-EKS
        #text: Customized text in slack message
    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.5/deploy/deploy.yaml

 

#5. 프로메테우스 - 스택

 

  • 소개 : 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/
  • 제공 기능
  • 프로메테우스-스택 설치 : 모니터링에 필요한 여러 요소를 **단일 차트(스택)**으로 제공 ← 시각화(그라파나), 이벤트 메시지 정책(경고 임계값, 경고 수준) 등 - Helm
    • kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator.
    # 모니터링
    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 < monitor-values.yaml
    **prometheus**:
      prometheusSpec:
        podMonitorSelectorNilUsesHelmValues: false
        serviceMonitorSelectorNilUsesHelmValues: false
        retention: 5d
        retentionSize: "10GiB"
        **storageSpec**:
          volumeClaimTemplate:
            spec:
              storageClassName: **gp3**
              accessModes: ["ReadWriteOnce"]
              resources:
                requests:
                  storage: 30Gi
    
      ingress:
        enabled: true
        ingressClassName: alb
        hosts: 
          - prometheus.$MyDomain
        paths: 
          - /*
        annotations:
          alb.ingress.kubernetes.io/scheme: internet-facing
          alb.ingress.kubernetes.io/target-type: ip
          alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
          alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
          alb.ingress.kubernetes.io/success-codes: 200-399
          **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
          alb.ingress.kubernetes.io/group.name: study
          alb.ingress.kubernetes.io/ssl-redirect: '443'**
    
    **grafana**:
      defaultDashboardsTimezone: Asia/Seoul
      adminPassword: prom-operator
    
      ingress:
        enabled: true
        ingressClassName: alb
        hosts: 
          - grafana.$MyDomain
        paths: 
          - /*
        annotations:
          alb.ingress.kubernetes.io/scheme: internet-facing
          alb.ingress.kubernetes.io/target-type: ip
          alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
          alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
          alb.ingress.kubernetes.io/success-codes: 200-399
          **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
          alb.ingress.kubernetes.io/group.name: study
          alb.ingress.kubernetes.io/ssl-redirect: '443'**
    
      **persistence**:
        enabled: true
        type: sts
        storageClassName: "gp3"
        accessModes:
          - ReadWriteOnce
        size: 20Gi
    
    **defaultRules:
      create: false**
    **kubeControllerManager:
      enabled: false
    kubeEtcd:
      enabled: false
    kubeScheduler:
      enabled: false**
    **alertmanager:
      enabled: false**
    EOT
    cat monitor-values.yaml | yh
    
    # 배포
    helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version **57.1.0** \\
    --**set** prometheus.prometheusSpec.scrapeInterval='15s' --**set** prometheus.prometheusSpec.evaluationInterval='15s' \\
    -f **monitor-values.yaml** --namespace monitoring
    
    # 확인
    ~~## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송~~
    ## grafana : 프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리
    ## prometheus-0 : 모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장
    ## node-exporter : 노드익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출
    ## operator : 시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원
    ## kube-state-metrics : 쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드
    helm list -n monitoring
    kubectl get pod,svc,ingress,pvc -n monitoring
    kubectl get-all -n monitoring
    **kubectl get prometheus,servicemonitors -n monitoring**
    ~~~~**kubectl get crd | grep monitoring
    kubectl df-pv**
    
    • AWS ELB(ALB) 갯수 확인 → Rule 확인(어떻게 여러 도메인 처리를 하는 걸까?) ⇒ HTTP(80) 인입 시 어떻게 처리하나요?
    • (참고) kube-controller-manager, kube-scheduler 수집 불가? - 구글링
      • 프로메테우스 웹 → Status → Targets 확인 : kube-controller-manager, kube-scheduler 없음 확인
    • (참고) 삭제 시
    • 소개 : 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/
    • 제공 기능
    • 프로메테우스-스택 설치 : 모니터링에 필요한 여러 요소를 **단일 차트(스택)**으로 제공 ← 시각화(그라파나), 이벤트 메시지 정책(경고 임계값, 경고 수준) 등 - Helm
      • kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator.
      # 모니터링
      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 < monitor-values.yaml
      **prometheus**:
        prometheusSpec:
          podMonitorSelectorNilUsesHelmValues: false
          serviceMonitorSelectorNilUsesHelmValues: false
          retention: 5d
          retentionSize: "10GiB"
          **storageSpec**:
            volumeClaimTemplate:
              spec:
                storageClassName: **gp3**
                accessModes: ["ReadWriteOnce"]
                resources:
                  requests:
                    storage: 30Gi
      
        ingress:
          enabled: true
          ingressClassName: alb
          hosts: 
            - prometheus.$MyDomain
          paths: 
            - /*
          annotations:
            alb.ingress.kubernetes.io/scheme: internet-facing
            alb.ingress.kubernetes.io/target-type: ip
            alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
            alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
            alb.ingress.kubernetes.io/success-codes: 200-399
            **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
            alb.ingress.kubernetes.io/group.name: study
            alb.ingress.kubernetes.io/ssl-redirect: '443'**
      
      **grafana**:
        defaultDashboardsTimezone: Asia/Seoul
        adminPassword: prom-operator
      
        ingress:
          enabled: true
          ingressClassName: alb
          hosts: 
            - grafana.$MyDomain
          paths: 
            - /*
          annotations:
            alb.ingress.kubernetes.io/scheme: internet-facing
            alb.ingress.kubernetes.io/target-type: ip
            alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
            alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
            alb.ingress.kubernetes.io/success-codes: 200-399
            **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
            alb.ingress.kubernetes.io/group.name: study
            alb.ingress.kubernetes.io/ssl-redirect: '443'**
      
        **persistence**:
          enabled: true
          type: sts
          storageClassName: "gp3"
          accessModes:
            - ReadWriteOnce
          size: 20Gi
      
      **defaultRules:
        create: false**
      **kubeControllerManager:
        enabled: false
      kubeEtcd:
        enabled: false
      kubeScheduler:
        enabled: false**
      **alertmanager:
        enabled: false**
      EOT
      cat monitor-values.yaml | yh
      
      # 배포
      helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version **57.1.0** \\
      --**set** prometheus.prometheusSpec.scrapeInterval='15s' --**set** prometheus.prometheusSpec.evaluationInterval='15s' \\
      -f **monitor-values.yaml** --namespace monitoring
      
      # 확인
      ~~## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송~~
      ## grafana : 프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리
      ## prometheus-0 : 모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장
      ## node-exporter : 노드익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출
      ## operator : 시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원
      ## kube-state-metrics : 쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드
      helm list -n monitoring
      kubectl get pod,svc,ingress,pvc -n monitoring
      kubectl get-all -n monitoring
      **kubectl get prometheus,servicemonitors -n monitoring**
      ~~~~**kubectl get crd | grep monitoring
      kubectl df-pv**
      
      • AWS ELB(ALB) 갯수 확인 → Rule 확인(어떻게 여러 도메인 처리를 하는 걸까?) ⇒ HTTP(80) 인입 시 어떻게 처리하나요?
      • (참고) kube-controller-manager, kube-scheduler 수집 불가? - 구글링
        • 프로메테우스 웹 → Status → Targets 확인 : kube-controller-manager, kube-scheduler 없음 확인
      • (참고) 삭제 시
      • 소개 : 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/
      • 제공 기능
      • 프로메테우스-스택 설치 : 모니터링에 필요한 여러 요소를 **단일 차트(스택)**으로 제공 ← 시각화(그라파나), 이벤트 메시지 정책(경고 임계값, 경고 수준) 등 - Helm
        • kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator.
        # 모니터링
        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 < monitor-values.yaml
        **prometheus**:
          prometheusSpec:
            podMonitorSelectorNilUsesHelmValues: false
            serviceMonitorSelectorNilUsesHelmValues: false
            retention: 5d
            retentionSize: "10GiB"
            **storageSpec**:
              volumeClaimTemplate:
                spec:
                  storageClassName: **gp3**
                  accessModes: ["ReadWriteOnce"]
                  resources:
                    requests:
                      storage: 30Gi
        
          ingress:
            enabled: true
            ingressClassName: alb
            hosts: 
              - prometheus.$MyDomain
            paths: 
              - /*
            annotations:
              alb.ingress.kubernetes.io/scheme: internet-facing
              alb.ingress.kubernetes.io/target-type: ip
              alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
              alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
              alb.ingress.kubernetes.io/success-codes: 200-399
              **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
              alb.ingress.kubernetes.io/group.name: study
              alb.ingress.kubernetes.io/ssl-redirect: '443'**
        
        **grafana**:
          defaultDashboardsTimezone: Asia/Seoul
          adminPassword: prom-operator
        
          ingress:
            enabled: true
            ingressClassName: alb
            hosts: 
              - grafana.$MyDomain
            paths: 
              - /*
            annotations:
              alb.ingress.kubernetes.io/scheme: internet-facing
              alb.ingress.kubernetes.io/target-type: ip
              alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
              alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
              alb.ingress.kubernetes.io/success-codes: 200-399
              **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
              alb.ingress.kubernetes.io/group.name: study
              alb.ingress.kubernetes.io/ssl-redirect: '443'**
        
          **persistence**:
            enabled: true
            type: sts
            storageClassName: "gp3"
            accessModes:
              - ReadWriteOnce
            size: 20Gi
        
        **defaultRules:
          create: false**
        **kubeControllerManager:
          enabled: false
        kubeEtcd:
          enabled: false
        kubeScheduler:
          enabled: false**
        **alertmanager:
          enabled: false**
        EOT
        cat monitor-values.yaml | yh
        
        # 배포
        helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version **57.1.0** \\
        --**set** prometheus.prometheusSpec.scrapeInterval='15s' --**set** prometheus.prometheusSpec.evaluationInterval='15s' \\
        -f **monitor-values.yaml** --namespace monitoring
        
        # 확인
        ~~## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송~~
        ## grafana : 프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리
        ## prometheus-0 : 모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장
        ## node-exporter : 노드익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출
        ## operator : 시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원
        ## kube-state-metrics : 쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드
        helm list -n monitoring
        kubectl get pod,svc,ingress,pvc -n monitoring
        kubectl get-all -n monitoring
        **kubectl get prometheus,servicemonitors -n monitoring**
        ~~~~**kubectl get crd | grep monitoring
        kubectl df-pv**
        
        • AWS ELB(ALB) 갯수 확인 → Rule 확인(어떻게 여러 도메인 처리를 하는 걸까?) ⇒ HTTP(80) 인입 시 어떻게 처리하나요?
        • (참고) kube-controller-manager, kube-scheduler 수집 불가? - 구글링
          • 프로메테우스 웹 → Status → Targets 확인 : kube-controller-manager, kube-scheduler 없음 확인
        • (참고) 삭제 시
        • 소개 : 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/
        • 제공 기능
        • 프로메테우스-스택 설치 : 모니터링에 필요한 여러 요소를 **단일 차트(스택)**으로 제공 ← 시각화(그라파나), 이벤트 메시지 정책(경고 임계값, 경고 수준) 등 - Helm
          • kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards, and Prometheus rules combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with Prometheus using the Prometheus Operator.
          # 모니터링
          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 < monitor-values.yaml
          **prometheus**:
            prometheusSpec:
              podMonitorSelectorNilUsesHelmValues: false
              serviceMonitorSelectorNilUsesHelmValues: false
              retention: 5d
              retentionSize: "10GiB"
              **storageSpec**:
                volumeClaimTemplate:
                  spec:
                    storageClassName: **gp3**
                    accessModes: ["ReadWriteOnce"]
                    resources:
                      requests:
                        storage: 30Gi
          
            ingress:
              enabled: true
              ingressClassName: alb
              hosts: 
                - prometheus.$MyDomain
              paths: 
                - /*
              annotations:
                alb.ingress.kubernetes.io/scheme: internet-facing
                alb.ingress.kubernetes.io/target-type: ip
                alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
                alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
                alb.ingress.kubernetes.io/success-codes: 200-399
                **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
                alb.ingress.kubernetes.io/group.name: study
                alb.ingress.kubernetes.io/ssl-redirect: '443'**
          
          **grafana**:
            defaultDashboardsTimezone: Asia/Seoul
            adminPassword: prom-operator
          
            ingress:
              enabled: true
              ingressClassName: alb
              hosts: 
                - grafana.$MyDomain
              paths: 
                - /*
              annotations:
                alb.ingress.kubernetes.io/scheme: internet-facing
                alb.ingress.kubernetes.io/target-type: ip
                alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
                alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
                alb.ingress.kubernetes.io/success-codes: 200-399
                **alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
                alb.ingress.kubernetes.io/group.name: study
                alb.ingress.kubernetes.io/ssl-redirect: '443'**
          
            **persistence**:
              enabled: true
              type: sts
              storageClassName: "gp3"
              accessModes:
                - ReadWriteOnce
              size: 20Gi
          
          **defaultRules:
            create: false**
          **kubeControllerManager:
            enabled: false
          kubeEtcd:
            enabled: false
          kubeScheduler:
            enabled: false**
          **alertmanager:
            enabled: false**
          EOT
          cat monitor-values.yaml | yh
          
          # 배포
          helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version **57.1.0** \\
          --**set** prometheus.prometheusSpec.scrapeInterval='15s' --**set** prometheus.prometheusSpec.evaluationInterval='15s' \\
          -f **monitor-values.yaml** --namespace monitoring
          
          # 확인
          ~~## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송~~
          ## grafana : 프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리
          ## prometheus-0 : 모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장
          ## node-exporter : 노드익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출
          ## operator : 시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원
          ## kube-state-metrics : 쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드
          helm list -n monitoring
          kubectl get pod,svc,ingress,pvc -n monitoring
          kubectl get-all -n monitoring
          **kubectl get prometheus,servicemonitors -n monitoring**
          ~~~~**kubectl get crd | grep monitoring
          kubectl df-pv**
          
          • AWS 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
          
        # 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
      # 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
    # 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