이번주는 EKS Observability를 주제로 로깅, 메트릭, 기타 가시화를 위한 툴에 대해 알아보았습니다.
Logging
kubernetes에서 로깅은 EFK/ELK 스택을 주로 사용합니다.
이는 로그 데이터의 인덱싱과 검색을 담당하는 Elasticsearch, 데이터를 수집하고 필터링 및 변환하는 fluentd/fluentbit 또는 logstash, 데이터의 시각화를 담당하는 Kibana로 이루어져 있습니다. EFK 설치는 이전 글을 참고하시면 됩니다.
하지만 EKS에서는 fluentbit과 CloudWatch를 사용하는 Container Insights를 통해서도 로그 수집이 가능합니다. 이는 조금 뒤에 자세히 살펴보겠습니다.
Metric
Prometheus
프로메테우스는 대표적인 모니터링 솔루션 중 하나로 metric을 시계열 데이터로 수집, 저장합니다.
exporter를 타겟에 설정하고 service discovery를 통해 해당 타켓을 찾고 metric을 수집합니다.
Thanos
타노스는 프로메테우스를 조금 더 안정적으로 운영하기 위해 사용하는 솔루션입니다.
프로메테우스는 단일 노드에서 로컬 디스크에 데이터를 저장하고 처리하기 때문에 HA 구성과 확장성에 한계가 있습니다. 이때 타노스를 사용하여 해결할 수 있습니다.
타노스는 여러 프로메테우스 서버로부터 metric을 수집하여 통합된 쿼리를 할 수 있는 환경을 제공하고, Amazon S3와 같은 object 스토리지에 데이터를 백업 저장하여 안정성을 높입니다.
Metric Server
메트릭 서버는 kubelet을 통해 자원의 메트릭을 수집하고 apiserver를 통해 데이터를 제공하여 HPA, VPA, Cluster Autoscaler 등이 사용할 수 있는 환경을 제공합니다.
EKS에 기본적으로 설치되어 있지 않기 때문에 확장성을 위해 별도 설치가 필요합니다.
EKS에서의 logging 및 metric 수집방법
이제 EKS에서의 모니터링 방법을 조금 더 상세하게 알아보겠습니다.
Control Plane logging
EKS는 Control Plane에 대해 5개의 로그를 제공합니다.
- API server
- Audit : 클러스터에 대한 user, 관리자, 시스템 구성요소들의 동작을 기록
- Authenticator : RBAC 인증에 대한 기록
- Controller manager : core control loop를 관리하는 컴포넌트에 대한 로깅
- Scheduler : 클러스터 내에서 pod를 스케쥴링하는 kube-scheduler에 대한 로그
AWS 콘솔에서 각각의 로그를 별개로 enable할 수 있으며 해당 로그는 아래와 같은 이름의 CloudWatch loggroup에 저장됩니다.
- /aws/eks/{클러스터명}/cluster
로그 활성화 시 많은 양의 로그가 생기므로 비용 관리를 위해 retention 설정이 필요합니다.
CloudWatch Container Insights (logging + metric)
CloudWatch Container Insights는 AWS에서 제공하는 툴로, EKS 클러스터에 대한 metric과 로그 수집 기능을 제공합니다.
metric은 cloudwatch agent로, metric은 fluentbit을 통해 CloudWatch로 수집됩니다. 이때 노드뿐만 아니라 클러스터 내 pod의 로그도 포함됩니다.
Prometheus + Grafana (metric)
EKS에서도 오픈소스로 설치가 가능하며 최근 AWS 관리형 그라파나와 프로메테우스도 서울 리전에 제공되어 사용이 가능합니다.
실습
이제 클러스터 생성 후에 프로메테우스 스택을 설치해보겠습니다.
이번 주에는 해당 cloudformation yaml을 활용해 배포를 진행했습니다. 참고로 도메인과 acm 인증서가 필요합니다.
ACM 생성
ACM request
미리 구입한 도메인에 대해서 ACM을 생성하겠습니다.
도메인 이름에 구입한 도메인과 하위 레벨의 도메인을 모두 포함하게 설정합니다.
나머지는 기본 값으로 두고 Request를 클릭하면 됩니다.
ACM validataion
인증서를 생성한 후에는 Pending validation 상태인 것을 볼수있고, acm 상세 페이지에서 인증을 위한 레코드를 확인할 수 있습니다.
해당 레코드를 Route53 hosted zone에 등록하면 인증이 완료됩니다.
Route 53 -> Create record
클러스터 구성 (cloudformation 배포 이후)
external dns 설치
## external dns 설치
$ MyDomain=<자신의 도메인>
$ echo "export MyDomain=<자신의 도메인>" >> /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 -
## 설치 확인
$ k get po -n kube-system | grep -i external
external-dns-5755dcdf9d-v9dfq 1/1 Running 0 70s
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 gp3 storage class 설정
$ 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 32m
gp3 ebs.csi.aws.com Delete WaitForFirstConsumer true 2s
프로메테우스 스택 구성
$ kubectl create ns monitoring
# 사용 리전의 인증서 ARN 확인
$ CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
echo $CERT_ARN
$ 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
EOT
$ 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
$ helm list -n monitoring
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
kube-prometheus-stack monitoring 1 2023-05-21 16:33:20.856083368 +0900 KST deployed kube-prometheus-stack-45.27.2 v0.65.1
프로메테우스 및 grafana 도메인 확인
k get ing -n monitoring
NAME CLASS HOSTS ADDRESS PORTS AGE
kube-prometheus-stack-grafana alb grafana.ixxxxxxi.click myeks-ingress-alb-208029157.ap-northeast-2.elb.amazonaws.com 80 98s
kube-prometheus-stack-prometheus alb prometheus.ixxxxxxi.click myeks-ingress-alb-208029157.ap-northeast-2.elb.amazonaws.com 80 98s
grafana 도메인으로 정상 접속이 가능한 것을 볼 수 있고, 접속 정보는 admin/prom-operator 입니다.
프로메테우스에서는 타겟을 확인할 수 있습니다.
타겟에는 api-server와 node에서 제공하는 메트릭이 포함되어 있습니다.
참고 문서
'Kubernetes > EKS Study' 카테고리의 다른 글
[6주차] EKS Security (0) | 2023.06.11 |
---|---|
[5주차] EKS Autoscaling (0) | 2023.05.24 |
[3주차] EKS Storage (0) | 2023.05.09 |
EKS에서 볼륨 snapscheduler 설치하기 (0) | 2023.05.09 |
EKS에서 pvc로 생성한 ebs에 태그 추가하기 (0) | 2023.05.09 |