티스토리 뷰
안녕하세요. CloudNet@ K8S Study를 진행하며 해당 내용을 이해하고 공유하기 위해 작성한 글입니다. DevOps 이정훈님의 도서 ‘24단계 실습으로 정복하는 쿠버네티스’ 의 내용을 바탕으로 스터디를 하며 어떻게 k8s에 적용할지 고민하며 정리해봤습니다.
사전 환경
# YAML 파일 다운로드
$ curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/kops-oneclick-f1.yaml
# CloudFormation 스택 배포 : 노드 인스턴스 타입 변경 - MasterNodeInstanceType=t3.medium WorkerNodeInstanceType=c5d.large
$ aws cloudformation deploy --template-file kops-oneclick-f1.yaml --stack-name mykops --parameter-overrides KeyName=kp-hayley3 SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=AKIA5... MyIamUserSecretAccessKey='CVNa2...' ClusterBaseName='wellbeconnected.com' S3StateStore='hayley-bucket-test' MasterNodeInstanceType=c5a.2xlarge WorkerNodeInstanceType=c5a.2xlarge --region ap-northeast-2
# CloudFormation 스택 배포 완료 후 kOps EC2 IP 출력
$ aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text
# 13분 후 작업 SSH 접속
$ ssh -i ~/.ssh/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)
# EC2 instance profiles 에 IAM Policy 추가(attach) : 처음 입력 시 적용이 잘 안될 경우 다시 한번 더 입력 하자! - IAM Role에서 새로고침 먼저 확인!
$ aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name masters.$KOPS_CLUSTER_NAME
$ aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name nodes.$KOPS_CLUSTER_NAME
# 메트릭 서버 확인 : 메트릭은 15초 간격으로 cAdvisor를 통하여 가져옴
Metric Server
쿠버네티스에서메트릭 API(Metrics API) 는 자동 스케일링 및 비슷한 사용 사례를 지원하기 위한 기본적인 메트릭 집합을 제공합니다. 이 API는 노드와 파드의 리소스 사용량 정보를 제공하며, 여기에는 CPU 및 메모리 메트릭이 포함됩니다. [참고]
위 아키텍처 구성요소는 아래와 같습니다.
- cAdvisor: kubelet에 포함된 컨테이너 메트릭을 수집, 집계, 노출하는 데몬
- kubelet: 컨테이너 리소스 관리를 위한 노드 에이전트. 리소스 메트릭은 kubelet API 엔드포인트 /metrics/resource 및 /stats 를 사용하여 접근 가능하다.
- 요약 API: /stats 엔드포인트를 통해 사용할 수 있는 노드 별 요약된 정보를 탐색 및 수집할 수 있도록 kubelet이 제공하는 API
- metrics-server: 각 kubelet으로부터 수집한 리소스 메트릭을 수집 및 집계하는 클러스터 애드온 구성 요소. API 서버는 HPA, VPA 및 kubectl top 명령어가 사용할 수 있도록 메트릭 API를 제공한다. metrics-server는 메트릭 API에 대한 기준 구현(reference implementation) 중 하나이다.
- 메트릭 API: 워크로드 오토스케일링에 사용되는 CPU 및 메모리 정보로의 접근을 지원하는 쿠버네티스 API. 이를 클러스터에서 사용하려면, 메트릭 API를 제공하는 API 확장(extension) 서버가 필요하다.
# 메트릭 서버 확인 : 메트릭은 15초 간격으로 cAdvisor를 통하여 가져옴
$ kubectl get pod -n kube-system -l k8s-app=metrics-server
NAME READY STATUS RESTARTS AGE
metrics-server-5f65d889cd-2kczm 1/1 Running 0 122m
metrics-server-5f65d889cd-7djfg 1/1 Running 0 122m
$ kubectl get apiservices |egrep '(AVAILABLE|metrics)'
NAME SERVICE AVAILABLE AGE
v1beta1.metrics.k8s.io kube-system/metrics-server True 122m
# 노드 메트릭 확인
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
i-03fc63391c0173dfa 127m 1% 2199Mi 13%
i-050bf5be7d03f3f78 35m 0% 1047Mi 6%
i-0b0b3876e6b26f550 33m 0% 992Mi 6%
# 파드 메트릭 확인
$ kubectl top pod -A
# CPU 높은 순으로 정렬되는 것 확인
$ kubectl top pod -n kube-system --sort-by='cpu'
NAME CPU(cores) MEMORY(bytes)
kube-apiserver-i-03fc63391c0173dfa 37m 329Mi
etcd-manager-main-i-03fc63391c0173dfa 16m 109Mi
kube-controller-manager-i-03fc63391c0173dfa 12m 52Mi
etcd-manager-events-i-03fc63391c0173dfa 7m 31Mi
# Memory 높은 순으로 정렬되는 것 확인
$ kubectl top pod -n kube-system --sort-by='memory'
NAME CPU(cores) MEMORY(bytes)
kube-apiserver-i-03fc63391c0173dfa 36m 330Mi
etcd-manager-main-i-03fc63391c0173dfa 15m 108Mi
ebs-csi-controller-8bcf48fc-9j7rb 3m 52Mi
kube-controller-manager-i-03fc63391c0173dfa 10m 52Mi
프로메테우스
Prometheus 는 SoundCloud 사에서 만들어진 monitoring과 alerting toolkit open-source systems 입니다.
주요 특징 & 기능
- a multi-dimensional data model with time series data(=TSDB, 시계열 데이터베이스)
- PromQL, a flexible query language
- 수집방식:Pull방식(에이전트는 메트릭을 수집하며, 중앙 시스템으로 데이터 전송을 위한 정보가 보통 에이전트에 포함되어있다.)
- service discovery지원
프로메테우스 설치
# 모니터링
$ kubectl create ns monitoring
$ watch kubectl get pod,pvc,svc,ingress -n monitoring
# 사용 리전의 인증서 ARN 확인
$ CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
$ echo "alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN"
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:903575331688:certificate/3f025fab-6859-4cad-9d60-0c5887053d70
# 설치
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
# 파라미터 파일 생성
$ cat <<EOT > ~/monitor-values.yaml
alertmanager:
ingress:
enabled: true
ingressClassName: alb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/group.name: "monitoring"
hosts:
- alertmanager.$KOPS_CLUSTER_NAME
paths:
- /*
grafana:
defaultDashboardsTimezone: Asia/Seoul
adminPassword: prom-operator
ingress:
enabled: true
ingressClassName: alb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/group.name: "monitoring"
hosts:
- grafana.$KOPS_CLUSTER_NAME
paths:
- /*
prometheus:
ingress:
enabled: true
ingressClassName: alb
annotations:
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
alb.ingress.kubernetes.io/success-codes: 200-399
alb.ingress.kubernetes.io/group.name: "monitoring"
hosts:
- prometheus.$KOPS_CLUSTER_NAME
paths:
- /*
prometheusSpec:
podMonitorSelectorNilUsesHelmValues: false
serviceMonitorSelectorNilUsesHelmValues: false
retention: 5d
retentionSize: "10GiB"
EOT
# 배포
$ helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.7.1 \
--set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' \
-f monitor-values.yaml --namespace monitoring
# 확인
## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송
## grafana : 프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리
## prometheus-0 : 모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장
## node-exporter : 노드익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출
## operator : 시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원
## kube-state-metrics : 쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드
$ helm list -n monitoring
$ kubectl get pod,svc,ingress -n monitoring
$ kubectl get-all -n monitoring
$ kubectl get prometheus,alertmanager -n monitoring
NAME VERSION DESIRED READY RECONCILED AVAILABLE AGE
prometheus.monitoring.coreos.com/kube-prometheus-stack-prometheus v2.42.0 1 0 True False 24s
NAME VERSION REPLICAS READY RECONCILED AVAILABLE AGE
alertmanager.monitoring.coreos.com/kube-prometheus-stack-alertmanager v0.25.0 1 0 True False 24s
$ kubectl get prometheusrule -n monitoring
$ kubectl get servicemonitors -n monitoring
$ kubectl get crd | grep monitoring
alertmanagerconfigs.monitoring.coreos.com 2023-04-02T06:37:48Z
alertmanagers.monitoring.coreos.com 2023-04-02T06:37:48Z
podmonitors.monitoring.coreos.com 2023-04-02T06:37:48Z
probes.monitoring.coreos.com 2023-04-02T06:37:48Z
prometheuses.monitoring.coreos.com 2023-04-02T06:37:48Z
prometheusrules.monitoring.coreos.com 2023-04-02T06:37:48Z
servicemonitors.monitoring.coreos.com 2023-04-02T06:37:48Z
thanosrulers.monitoring.coreos.com 2023-04-02T06:37:48Z
# 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
프로메테우스 기본 사용
- 모니터링 대상이 되는 서비스는 일반적으로 자체 웹 서버의 /metrics 엔드포인트 경로에 다양한 메트릭 정보를 노출합니다.
- 이후 프로메테우스는 해당 경로에 http get 방식으로 메트릭 정보를 가져와 TSDB 형식으로 저장합니다.
# 아래 처럼 프로메테우스가 각 서비스의 9100 접속하여 메트릭 정보를 수집
$ kubectl get node -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
i-03fc63391c0173dfa Ready control-plane 177m v1.24.11 172.30.40.130 13.125.243.173 Ubuntu 20.04.5 LTS 5.15.0-1031-aws containerd://1.6.18
i-050bf5be7d03f3f78 Ready node 175m v1.24.11 172.30.49.70 13.125.235.86 Ubuntu 20.04.5 LTS 5.15.0-1031-aws containerd://1.6.18
i-0b0b3876e6b26f550 Ready node 175m v1.24.11 172.30.92.67 54.180.99.208 Ubuntu 20.04.5 LTS 5.15.0-1031-aws containerd://1.6.18
$ kubectl get svc,ep -n monitoring kube-prometheus-stack-prometheus-node-exporter
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kube-prometheus-stack-prometheus-node-exporter ClusterIP 100.65.94.228 <none> 9100/TCP 3m20s
NAME ENDPOINTS AGE
endpoints/kube-prometheus-stack-prometheus-node-exporter 172.30.40.130:9100,172.30.49.70:9100,172.30.92.67:9100 3m20s
# 마스터노드에 lynx 설치
$ ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME hostname
$ ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME sudo apt install lynx -y
# 노드의 9100번의 /metrics 접속 시 다양한 메트릭 정보를 확인할수 있음 : 마스터 이외에 워커노드도 확인 가능
$ ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME lynx -dump localhost:9100/metrics
프로메테우스 ingress 도메인으로 웹 접속
# ingress 확인
$ kubectl get ingress -n monitoring kube-prometheus-stack-prometheus
NAME CLASS HOSTS ADDRESS PORTS AGE
kube-prometheus-stack-prometheus alb prometheus.wellbeconnected.com k8s-monitoring-0096407009-272894402.ap-northeast-2.elb.amazonaws.com 80 5m20s
$ kubectl describe ingress -n monitoring kube-prometheus-stack-prometheus
# 프로메테우스 ingress 도메인으로 웹 접속
$ echo -e "Prometheus Web URL = https://prometheus.$KOPS_CLUSTER_NAME"
Prometheus Web URL = https://prometheus.wellbeconnected.com
# 웹 상단 주요 메뉴 설명
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) 중 마스터 노드에 Endpoint 접속 확인
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME curl -s http://localhost:10249/metrics
# 그외 다른 타켓의 Endpoint 로 접속 확인 가능 : 예시) 아래는 coredns 의 Endpoint 주소 (접속 주소는 실습 환경에 따라 다름)
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME curl -s http://172.30.60.50:9153/metrics
- 프로메테우스 설정(Configuration) 확인 : Status → Service Discovery : 모든 endpoint 로 도달 가능 시 자동 발견!, 도달 규칙은 설정Configuration 파일에 정의
— 예) serviceMonitor/monitoring/kube-prometheus-stack-apiserver/0 경우 해당 address=”172.30.62.105:443" 도달 가능 시 자동 발견됨
- 메트릭을 그래프(Graph)로 조회 : Graph — 아래 PromQL 쿼리(전체 클러스터 노드의 CPU 사용량 합계)입력 후 조회 → Graph 확인
그라파나
TSDB 데이터를 시각화, 다양한 데이터 형식 지원합니다.(메트릭, 로그, 트레이스 등)
- 접속 정보 확인 및 로그인 : 기본 계정 — admin / prom-operator
# ingress 확인
$ kubectl get ingress -n monitoring kube-prometheus-stack-grafana
NAME CLASS HOSTS ADDRESS PORTS AGE
kube-prometheus-stack-grafana alb grafana.wellbeconnected.com k8s-monitoring-0096407009-272894402.ap-northeast-2.elb.amazonaws.com 80 39m
$ kubectl describe ingress -n monitoring kube-prometheus-stack-grafana
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.3.8
helm.sh/chart=grafana-6.51.5
Namespace: monitoring
Address: k8s-monitoring-0096407009-272894402.ap-northeast-2.elb.amazonaws.com
Ingress Class: alb
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
grafana.wellbeconnected.com
/ kube-prometheus-stack-grafana:80 (172.30.93.53:3000)
Annotations: alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:ap-northeast-2:903575331688:certificate/3f025fab-6859-4cad-9d60-0c5887053d70
alb.ingress.kubernetes.io/group.name: monitoring
alb.ingress.kubernetes.io/listen-ports: [{"HTTPS":443}, {"HTTP":80}]
alb.ingress.kubernetes.io/scheme: internet-facing
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 39m ingress Successfully reconciled
# ingress 도메인으로 웹 접속
$ echo -e "Grafana Web URL = https://grafana.$KOPS_CLUSTER_NAME"
Grafana Web URL = https://grafana.wellbeconnected.com
- configuration -Data sources 스택의 경우 자동으로 프로메테우스를 데이터 소스로 추가해둠
# 서비스 주소 확인
$ 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 100.68.135.113 <none> 9090/TCP 47m
NAME ENDPOINTS AGE
endpoints/kube-prometheus-stack-prometheus 172.30.83.64:9090 47m
해당 데이터 소스 접속 확인
# 테스트용 파드 배포
$ kubectl apply -f ~/pkos/2/netshoot-2pods.yaml
$ kubectl get pod
# 접속 확인
$ kubectl exec -it pod-1 -- nslookup kube-prometheus-stack-prometheus.monitoring
Server: 169.254.20.10
Address: 169.254.20.10#53
Name: kube-prometheus-stack-prometheus.monitoring.svc.cluster.local
Address: 100.68.135.113
$ kubectl exec -it pod-1 -- curl -s kube-prometheus-stack-prometheus.monitoring:9090/graph -v
> GET /graph HTTP/1.1
> Host: kube-prometheus-stack-prometheus.monitoring:9090
> User-Agent: curl/7.87.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 02 Apr 2023 07:27:45 GMT
< Content-Length: 734
< Content-Type: text/html; charset=utf-8
<
* Connection #0 to host kube-prometheus-stack-prometheus.monitoring left intact
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="theme-color" content="#000000"/><script>const GLOBAL_CONSOLES_LINK="",GLOBAL_AGENT_MODE="false",GLOBAL_READY="true"</script><link rel="manifest" href="./manifest.json" crossorigin="use-credentials"/><title>Prometheus Time Series Collection and Processing Server</title><script defer="defer" src="./static/js/main.c1286cb7.js"></script><link href="./static/css/main.cb2558a0.css" rel="stylesheet"></head><body class="bootstrap"><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div>
# 삭제
$ kubectl delete -f ~/pkos/2/netshoot-2pods.yaml
대시보드 사용
- 기본 대시보드
- 공식 대시보드 : [1 Kubernetes All-in-one Cluster Monitoring KR] 13370 처럼 대시보드 ID를 Import 해서 적용할 수 있습니다.
NGINX 웹서버 배포 및 애플리케이션 모니터링 설정 및 접속
nginx 웹 서버 helm 설치
#
$ helm repo add bitnami https://charts.bitnami.com/bitnami
# 파라미터 파일 생성 : 서비스 모니터 방식으로 nginx 모니터링 대상을 등록하고, export 는 9113 포트 사용, nginx 웹서버 노출은 AWS CLB 기본 사용
$ cat <<EOT > ~/nginx-values.yaml
metrics:
enabled: true
service:
port: 9113
serviceMonitor:
enabled: true
namespace: monitoring
interval: 10s
EOT
# 배포
$ helm install nginx bitnami/nginx --version 13.2.23 -f nginx-values.yaml
# CLB에 ExternanDNS 로 도메인 연결
$ kubectl annotate service nginx "external-dns.alpha.kubernetes.io/hostname=nginx.$KOPS_CLUSTER_NAME"
# 확인
$ kubectl get pod,svc,ep
NAME READY STATUS RESTARTS AGE
pod/nginx-697fd655bf-wfscg 0/2 ContainerCreating 0 9s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 100.64.0.1 <none> 443/TCP 3h52m
service/nginx LoadBalancer 100.70.203.119 <pending> 80:30480/TCP,9113:30790/TCP 9s
NAME ENDPOINTS AGE
endpoints/kubernetes 172.30.40.130:443 3h52m
endpoints/nginx <none> 9s
$ kubectl get servicemonitor -n monitoring nginx
NAME AGE
nginx 9s
$ kubectl get servicemonitor -n monitoring nginx -o json | jq
# nginx 파드내에 컨테이너 갯수 확인
$ kubectl get pod -l app.kubernetes.io/instance=nginx
NAME READY STATUS RESTARTS AGE
nginx-697fd655bf-wfscg 2/2 Running 0 52s
$ kubectl describe pod -l app.kubernetes.io/instance=nginx
# 접속 주소 확인 및 접속
$ echo -e "Nginx WebServer URL = http://nginx.$KOPS_CLUSTER_NAME"
Nginx WebServer URL = http://nginx.wellbeconnected.com
$ curl -s http://nginx.$KOPS_CLUSTER_NAME
$ kubectl logs deploy/nginx -f
Defaulted container "nginx" out of: nginx, metrics
nginx 07:35:57.09
nginx 07:35:57.09 Welcome to the Bitnami nginx container
nginx 07:35:57.09 Subscribe to project updates by watching https://github.com/bitnami/containers
nginx 07:35:57.09 Submit issues and feature requests at https://github.com/bitnami/containers/issues
nginx 07:35:57.10
nginx 07:35:57.10 INFO ==> ** Starting NGINX setup **
nginx 07:35:57.11 INFO ==> Validating settings in NGINX_* env vars
nginx 07:35:57.11 INFO ==> No custom scripts in /docker-entrypoint-initdb.d
nginx 07:35:57.11 INFO ==> Initializing NGINX
realpath: /bitnami/nginx/conf/vhosts: No such file or directory
nginx 07:35:57.12 INFO ==> ** NGINX setup finished! **
nginx 07:35:57.13 INFO ==> ** Starting NGINX **
# 반복 접속
$ while true; do curl -s http://nginx.$KOPS_CLUSTER_NAME -I | head -n 1; date; sleep 1; done
- 위와 같이 서비스 모니터링 생성 후 프로메테우스 웹서버-> status -> targets에 nginx 서비스 모니터가 추가된 것을 확인할 수 있습니다.
Nginx 애플리케이션 모니터링 대시보드 추가
- ID 12708 을 Import 해줍니다.
Kwatch
- kwatch는 Kubernetes(K8s) 클러스터의 모든 변경 사항을 모니터링하고, 실행 중인 앱의 충돌을 실시간으로 감지하고, 채널에 알림을 게시하도록 도와줍니다.
# 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: '접근할 webhook 주소'
#title:
#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
Alerting 프로메테우스 Alert Manager
프로메테우스의 임곗값 도달 시 경고 메시지를 얼럿매니저에 푸시 이벤트로 전달하고, 얼럿매니저는 이를 가공후 이메일/슬랙 등에 전달합니다.
# EC2 인스턴스 모니터링
$ while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --output text | sort; echo "------------------------------" ;date; sleep 1; done
# 인스턴스그룹 정보 확인
$ kops get ig
NAME ROLE MACHINETYPE MIN MAX ZONES
control-plane-ap-northeast-2a ControlPlane c5a.2xlarge 1 1 ap-northeast-2a
nodes-ap-northeast-2a Node c5a.2xlarge 1 1 ap-northeast-2a
nodes-ap-northeast-2c Node c5a.2xlarge 1 1 ap-northeast-2c
# 노드 추가
$ kops edit ig nodes-ap-northeast-2a --set spec.minSize=2 --set spec.maxSize=2
# 적용
$ kops update cluster --yes && echo && sleep 3 && kops rolling-update cluster
NAME STATUS NEEDUPDATE READY MIN TARGET MAX NODES
control-plane-ap-northeast-2a Ready 0 1 1 1 11
nodes-ap-northeast-2a Ready 0 1 2 2 21
nodes-ap-northeast-2c Ready 0 1 1 1 11
# 워커노드 증가 확인
$ while true; do kubectl get node; echo "------------------------------" ;date; sleep 1; done
Alert Manager 접속
# ingress 도메인으로 웹 접속
$ echo -e "Alertmanager Web URL = https://alertmanager.$KOPS_CLUSTER_NAME"
Alert Manager 대시보드 karma 컨테이너로 실행
# 실행
$ docker run -d -p 80:8080 -e ALERTMANAGER_URI=https://alertmanager.$KOPS_CLUSTER_NAME ghcr.io/prymitive/karma:latest
# 확인
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ff49a779f0e9 ghcr.io/prymitive/karma:latest "/karma" 4 seconds ago Up 3 seconds 0.0.0.0:80->8080/tcp, :::80->8080/tcp wizardly_margulis
Alert Manager 대시보드 karma 웹 접속 주소 확인
$ echo -e "karma Web URL = http://$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)"
karma Web URL = http://13.124.253.31
프로메테우스 웹 Alert & Alert Manager 웹 karma
- 프로메테우스 웹 접속 후 상단 Alert 메뉴 확인 : 시스템 경고 정책은 prometheusrules CRD로 관리합니다.
# 프로메테우스 룰 확인
$ kubectl get prometheusrules -n monitoring
$ kubectl get prometheusrules -n monitoring kube-prometheus-stack-kubernetes-system-controller-manager -o json | jq
# 룰 전체 확인
$ kubectl get prometheusrules -n monitoring -o json | more
# 메트릭 이름 확인
$ kubectl get prometheusrules -n monitoring -o json | grep '"record":' | sed 's/^ *//'
$ kubectl get prometheusrules -n monitoring -o json | grep '"record":' | sed 's/^ *//' | wc -l
85
# 얼럿 이름 확인
$ kubectl get prometheusrules -n monitoring -o json | grep '"alert":' | sed 's/^ *//'
# 얼럿 갯수 확인
$ kubectl get prometheusrules -n monitoring -o json | grep '"alert":' | sed 's/^ *//' | wc -l
134
아래와 같이 3개의 Alert 개수가 확인됩니다.
슬랙 채널 및 웹훅 URL 생성 및 얼럿매니저 설정 적용
# 웹훅 URL 정보
https://hooks.slack.com/services/XXXXXXX
WEBHOOK='https://hooks.slack.com/services/XXXXXXX'
# 샘플 메시지 보내기
curl -X POST --data-urlencode "payload={\"channel\": \"#webhook2\", \"username\": \"pkosbot\", \"text\": \"$KOPS_CLUSTER_NAME 다음주 종강! - 봇 제공\"}" $WEBHOOK
curl -X POST --data-urlencode "payload={\"channel\": \"#webhook2\", \"username\": \"pkosbot\", \"text\": \"$KOPS_CLUSTER_NAME 다음주 종강! - 봇 제공\", \"icon_emoji\": \":ghost:\"}" $WEBHOOK
얼럿매니저에 웹훅 URL 정보 반영
cat <<EOT > ~/alertmanager-slack.yaml
alertmanager:
config:
global:
resolve_timeout: 5m
slack_api_url: 'https://hooks.slack.com/services/XXXXXXX'
route:
group_by: ['job'] # namespace
group_wait: 10s
group_interval: 1m
repeat_interval: 5m
receiver: 'slack-notifications'
routes:
- receiver: 'slack-notifications'
matchers:
- alertname =~ "InfoInhibitor|Watchdog"
receivers:
- name: 'slack-notifications'
slack_configs:
- channel: '#webhook2'
send_resolved: true
title: '[{{.Status | toUpper}}] {{ .CommonLabels.alertname }}'
text: |
*Description:* {{ .CommonAnnotations.description }}
EOT
# helm 업그레이드로 얼럿매니저에 웹훅 URL 정보 반영
$ helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack --reuse-values -f alertmanager-slack.yaml --namespace monitoring
PLG 스택
- Promtail + Loki + Grafana 여러 파드의 로그들을 중앙 서버에 저장하고 이를 조회할 수 있습니다.
Loki 설치
- Loki에 저장한 로그는 LogQL(PromQL과 유사)을 이용해 조회 할 수 있으며, 그라파나 웹이나 logcli를 이용해 조회 가능합니다.
# 모니터링
$ kubectl create ns loki
$ watch kubectl get pod,pvc,svc,ingress -n loki
# Repo 추가
$ helm repo add grafana https://grafana.github.io/helm-charts
# 파라미터 설정 파일 생성
$ cat <<EOT > ~/loki-values.yaml
persistence:
enabled: true
size: 20Gi
serviceMonitor:
enabled: true
EOT
# 배포
$ helm install loki grafana/loki --version 2.16.0 -f loki-values.yaml --namespace loki
# 설치 확인 : 데몬셋, 스테이트풀셋, PVC 확인
$ helm list -n loki
$ kubectl get pod,pvc,svc,ds,sts -n loki
$ kubectl get-all -n loki
$ kubectl get servicemonitor -n loki
$ kubectl krew install df-pv && kubectl df-pv
# curl 테스트 용 파드 생성
$ kubectl delete -f ~/pkos/2/netshoot-2pods.yaml
$ kubectl apply -f ~/pkos/2/netshoot-2pods.yaml
# 로키 gateway 접속 확인
$ kubectl exec -it pod-1 -- curl -s http://loki.loki.svc:3100/api/prom/label
# (참고) 삭제 시
$ helm uninstall loki -n loki
$ kubectl delete pvc -n loki --all
Promtail 설치
- Promtail은 데몬셋으로 실행되며 각 로그에 로그를 중앙 로키 서버에 전달, Promtail 외에도 도커, FluentD 등 다른 로그수집 에이전트 사용 할 수 있습니다.
# 파라미터 설정 파일 생성
$ cat <<EOT > ~/promtail-values.yaml
serviceMonitor:
enabled: true
config:
serverPort: 3101
clients:
- url: http://loki-headless:3100/loki/api/v1/push
#defaultVolumes:
# - name: pods
# hostPath:
# path: /var/log/pods
EOT
# 배포
$ helm install promtail grafana/promtail --version 6.0.0 -f promtail-values.yaml --namespace loki
# (참고) 파드 로그는 /var/log/pods에 저장
$ ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ls /var/log/pods
# 설치 확인 : 데몬셋, 스테이트풀셋, PVC 확인
$ helm list -n loki
$ kubectl get pod,pvc,svc,ds,sts,servicemonitor -n loki
$ kubectl get-all -n loki
# (참고) 삭제 시
$ helm uninstall promtail -n loki
그라파나에서 로그 확인
- 아래와 같이 그라파나 Configuration — Data Source에 데이터 소스를 추가해줍니다.
- HTTP URL : http://loki-headless.loki:3100 ⇒ Save & Test
- Logfilters : Job → default/nginx 값 선택 ⇒ 우측 상단 Run query 클릭
- Loki 로그 확인 대시보드 : 15141
자원 삭제
# nginx 삭제
$ helm uninstall nginx
# promtail 삭제
$ helm uninstall promtail -n loki
# loki 삭제
$ helm uninstall loki -n loki
$ kubectl delete pvc -n loki --all
# 프로메테우스 스택 삭제
$ helm uninstall -n monitoring kube-prometheus-stack
$ kops delete cluster --yes && aws cloudformation delete-stack --stack-name mykops
blog migration project
written in 2023.4.2
https://medium.com/techblog-hayleyshim/k8s-monitoring-prometheus-grafana-loki-6fe7cb22b576
'IT > Container&k8s' 카테고리의 다른 글
[k8s] cluster install - cri-o runtime error (0) | 2023.10.29 |
---|---|
[k8s] Security (0) | 2023.10.29 |
[k8s] GitOps(Image registy, Source repository, Continuous Delivery) (0) | 2023.10.29 |
[k8s] Storage (0) | 2023.10.29 |
[k8s] Network (0) | 2023.10.29 |
- Total
- Today
- Yesterday
- IaC
- AI
- 파이썬
- OS
- NW
- controltower
- handson
- 국제 개발 협력
- cloud
- k8s cni
- k8s calico
- terraform
- gcp serverless
- GCP
- 혼공챌린지
- S3
- EKS
- k8s
- 혼공단
- NFT
- AWS
- VPN
- security
- cni
- PYTHON
- 도서
- SDWAN
- GKE
- 혼공파
- operator
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |