쿠버네티스에 프로메테우스(Prometheus) 오퍼레이터 설치하기
프로메테우스(Prometheus)는 모니터링 시스템을 말한다. 프로메테우스는 파일 기반의 타임시리즈(Time-Series) 데이터베이스다. 시스템의 메트릭스들을 수집하기 위해서는 익스포터(Exportor) 를 설치해야 한다. 이외에도 알람을 전달해주는 AlertManager 도 있는데, 전체적인 아키텍쳐는 다음과 같다.
프로메테우스는 쿠버네티스에서도 설치가 가능한데, 이글은 쿠버네티스에 프로메테우스 설치에 대한 글이다.
환경
환경은 다음과 같다.
- Kubernetes 버전: 1.20
- Kubernetes Nodes: Master 3개, Worker 3개
- Prometheus 설치 방법: Helm Operator
설치
프로메테우스(Prometheus) 설치는 매우 다양한데, 검색을 해보면 Helm 을 이용한 방법 그중에서도 오퍼레이터(Operator) 를 이용한 방법이 많이 소개 되어 있다. 여기서도 이 오퍼레이터를 이용한 방법을 사용하고자 한다.
Prometheus Operator 로 검색을 해보면 github 저장소를 찾을 수 있다.
- GitHub – prometheus-operator/prometheus-operator: Prometheus Operator creates/configures/manages Prometheus clusters atop Kubernetes
중간에 보면 Prometheus Operator vs kube-prometheus vs community helm chart 가 보인다. 자세히 읽어보면 쿠버네티스에 설치할 수 있는 방법이 세 가지로 나뉜다는 것을 알수 있다.
이중에서 나는 Helm chart 를 이용한 방법을 이용할 생각이다.
노드 레이블 설정
노드에 레이블을 설정하게 되면 쿠버네티스에 앱을 배포할때에 레이블을 지정함으로써 특정 노드에 생성되도록 강제할 수 있다. 프로메테우스 오퍼레이터 설치를 특정 노드에 하기 위해서 레이블을 부여할 생각이다. 대상 노드는 kworker3.systemv.local 노드이며 다음과 같이 레이블을 할당해 줬다.
1 2 3 4 5 6 7 |
$ kubectl get node --show-labels NAME STATUS ROLES AGE VERSION LABELS kworker1.systemv.local Ready <none> 97d v1.20.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=kworker1.systemv.local,kubernetes.io/os=linux kworker2.systemv.local Ready <none> 97d v1.20.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=kworker2.systemv.local,kubernetes.io/os=linux kworker3.systemv.local Ready <none> 97d v1.20.6 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=kworker3.systemv.local,kubernetes.io/os=linux $ kubectl label nodes kworker3.systemv.local system.rule=monitoring node/kworker3.systemv.local labeled |
kworker3.systemv.local 노드에 system.rule=monitoring 레이블이 새겨졌다.
Helm Chart 가지고 오기
Helm 를 이용하면 명령어 한줄로 설치가 되지만 설정을 변경하기 위해서는 챠트(Chart) 를 수정해줘야 한다. 이를 위해서 챠트를 다운받아야만 한다. Helm 챠트는 프로메테우스 커뮤니티에서 관리하고 있다.
1 2 3 4 5 6 7 |
$ git clone https://github.com/prometheus-community/helm-charts.git $ cd helm-charts/charts $ ls alertmanager prometheus-adapter prometheus-couchdb-exporter prometheus-mongodb-exporter prometheus-pingdom-exporter prometheus-redis-exporter prometheus-to-sd kube-prometheus-stack prometheus-blackbox-exporter prometheus-druid-exporter prometheus-mysql-exporter prometheus-postgres-exporter prometheus-snmp-exporter kube-state-metrics prometheus-cloudwatch-exporter prometheus-elasticsearch-exporter prometheus-nats-exporter prometheus-pushgateway prometheus-stackdriver-exporter prometheus prometheus-consul-exporter prometheus-kafka-exporter prometheus-node-exporter prometheus-rabbitmq-exporter prometheus-statsd-exporter |
많은 챠트가 존재하는데, 여기서 설치 대상은 kube-prometheus-stack 이다.
설정을 하기위해서 프로메테우스 오퍼레이터의 구성을 살펴볼 필요가 있다.
- Prometheus – 프로메테우스 리소스 정의가 되어 있다. 프로메테우스를 위한 파드(Pod) 의 리플리카(Replica) 갯수, 퍼시스턴스 볼륨 구성등이다. 프로메테이스 오퍼레이터는 파드를 StatefulSet 으로 배포 한다. 그리고 어떤 애플리케이션, 혹은 리소스를 모니터링할 것이지를 지정하는 것인데, 이것은 ServiceMonitor 로 설정이 이루어 진다.
- ServiceMonitor – 프로메테우스 오퍼레이터는 어노테이션 기반의 서비스 디스커버리를 지원하지 않으며 대신 PodMonitor, ServiceMonitor 를 이용한다. ServiceMonitor는 애플리케이션이나 서비스의 리소스를 모니터링할 것인지를 지정한다. 쿠버네티스의 NodeSelector 처럼 LableSelector 로 서비스의 리소스를 선택할 수 있고, 엔드포인트(EndPoint) 를 통해서 애플리케이션의 메트릭을 수집할 수 있다. ServiceMonitor 는 rule 을 기반으로 Prometheus의 모니터링 대상이 되는 ServiceMonitor를 scan하여 해당 정보를 Secret으로 배포한다. 그리고 이 Secret을 Prometheus StatefulSet에 마운트한다. 이런 방식으로 Prometheus 팟은 자신이 모니터링할 Service가 무엇인지 알 수 있다.
- Altermanager – 알람 매니저 이다. 프로메테우스 컴포넌트중에 하나다.
- PodMonitor – 파드에 대한 모니터다. 역시나 LabelSelector 를 통해서 모니터링하고자 하는 파드를 지정할 수 있다.
위 내용을 잘 알야하는 이유는 kube-prometheus-stack 디렉토리에 values.yaml 파일에 구조와 연관이 있다.
values.yaml 파일 편집
프로메테우스 오퍼레이터를 Helm 으로 설치할 때에는 values.yaml 파일의 설정을 참고하도록 되어 있다. values.yaml 에는 altermanager, Grafana, Prometheus 등에 대한 설정 값들이 들어가 있다. 앞에서 특정 노드에 배포하도록 하기 위해서 worker3.systemv.local 노드에 레이블링을 해줬기 때문에 이들 컴포넌트의 NodeSeletor 를 지정해 줘야 한다.
1 2 3 4 5 |
## Define which Nodes the Pods are scheduled on. ## ref: https://kubernetes.io/docs/user-guide/node-selection/ ## nodeSelector: system.rule: monitoring |
Grafana, Altermanager, Prometheus 의 파드들은 system.rule=monitoring 레이블링 된 노드에만 설치되도록 해뒀다.
Node Exportor 는 system.rule=monitoring 레이블링을 할당하지 않는다. 이들은 노드마다 작동되어야 하기 때문이다.
Helm 설치
이제 설치를 해야 하는데, 설치하기 앞서 의존성 챠트를 업데이트 해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ cd charts/kube-prometheus-stack/ $ helm dependency update Getting updates for unmanaged Helm repositories... ...Successfully got an update from the "https://grafana.github.io/helm-charts" chart repository Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "ingress-nginx" chart repository ...Successfully got an update from the "prometheus-community" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. ⎈Happy Helming!⎈ Saving 3 charts Downloading kube-state-metrics from repo https://prometheus-community.github.io/helm-charts Downloading prometheus-node-exporter from repo https://prometheus-community.github.io/helm-charts Downloading grafana from repo https://grafana.github.io/helm-charts Deleting outdated charts |
이제 다음과 같이 설치를 실행해 준다.
1 2 3 4 5 6 7 8 9 10 11 |
$ helm install -f values.yaml promethus --namespace=monitoring . NAME: promethus LAST DEPLOYED: Sun Jul 25 09:08:15 2021 NAMESPACE: monitoring STATUS: deployed REVISION: 1 NOTES: kube-prometheus-stack has been installed. Check its status by running: kubectl --namespace monitoring get pods -l "release=promethus" Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator. |
확인
이제 확인을 해보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ kubectl get pod -n monitoring -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES alertmanager-promethus-kube-prometheus-alertmanager-0 2/2 Running 0 5m52s 10.31.4.1 kworker3.systemv.local <none> <none> prometheus-promethus-kube-prometheus-prometheus-0 2/2 Running 0 5m51s 10.31.4.2 kworker3.systemv.local <none> <none> promethus-grafana-5d7bb49d46-w9447 2/2 Running 0 6m19s 10.31.4.63 kworker3.systemv.local <none> <none> promethus-kube-prometheus-operator-5b8849665f-b47dq 1/1 Running 0 6m19s 10.31.4.62 kworker3.systemv.local <none> <none> promethus-kube-state-metrics-7f4995ccfb-5l2tb 1/1 Running 0 6m19s 10.31.20.15 kworker1.systemv.local <none> <none> promethus-prometheus-node-exporter-g8hvx 1/1 Running 0 6m19s 192.168.96.49 kworker1.systemv.local <none> <none> promethus-prometheus-node-exporter-mwdwd 1/1 Running 0 6m19s 192.168.96.50 kworker2.systemv.local <none> <none> promethus-prometheus-node-exporter-p684h 1/1 Running 0 6m19s 192.168.96.51 kworker3.systemv.local <none> <none> $ $ kubectl get svc -n monitoring -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR alertmanager-operated ClusterIP None <none> 9093/TCP,9094/TCP,9094/UDP 9m59s app.kubernetes.io/name=alertmanager prometheus-operated ClusterIP None <none> 9090/TCP 9m58s app.kubernetes.io/name=prometheus promethus-grafana ClusterIP 10.32.0.231 <none> 80/TCP 10m app.kubernetes.io/instance=promethus,app.kubernetes.io/name=grafana promethus-kube-prometheus-alertmanager ClusterIP 10.32.0.135 <none> 9093/TCP 10m alertmanager=promethus-kube-prometheus-alertmanager,app=alertmanager promethus-kube-prometheus-operator ClusterIP 10.32.0.147 <none> 443/TCP 10m app=kube-prometheus-stack-operator,release=promethus promethus-kube-prometheus-prometheus ClusterIP 10.32.0.148 <none> 9090/TCP 10m app.kubernetes.io/name=prometheus,prometheus=promethus-kube-prometheus-prometheus promethus-kube-state-metrics ClusterIP 10.32.0.71 <none> 8080/TCP 10m app.kubernetes.io/instance=promethus,app.kubernetes.io/name=kube-state-metrics promethus-prometheus-node-exporter ClusterIP 10.32.0.162 <none> 9100/TCP 10m app=prometheus-node-exporter,release=promethus |
이렇게 설치가 된것으로 보이지만, 사실 프로메테우스의 오퍼레이터는 CRD 를 이용해 리소스를 생성하였기 때문에 이를 알아야 한다. CRD 를 포함한 monitoring 네임스페이스에 모든 리소스를 보기 위해서 다음과 같이 할 수 있다.
1 |
$ kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get --show-kind --ignore-not-found -n monitoring |
이를 통해 확인할 수 있는 CRD 예로 ServiceMonitor, Prometheus 등을 확인해 볼 수 있다.
필자는 Metallb 를 이용해서 LoadBalancer 를 사용할 수 있기 때문에 grafana, prometheus 서비스에 대해서 타입을 ClusterIP 를 LoadBalancer 로 변경해 외부접속이 가능하도록 할 수 있다.
1 2 3 4 |
$ kubectl get svc -n monitoring NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE prometheus-grafana LoadBalancer 10.32.0.147 192.168.111.3 80:30015/TCP 83m prometheus-kube-prometheus-prometheus LoadBalancer 10.32.0.142 192.168.111.4 9090:31559/TCP 83m |
Metallb 에 의해서 EXTERNAL-IP 에 외부접속 IP 가 할당 되었다.