Kubernetes 기반의 monitoring 을 구현한다면 최우선 순위로 검토되는 오픈소스는 단연 Prometheus 이다. 최근에는 Kubernetes 위에 실행되는 Pod와 같은 자원을 효과적으로 관리하기 위해서 Operator 를 활용하고 있는 추세인데 이에 맞춰 Prometheus 에서도 Operator 를 지원하고 있다. 일반적으로 Operator 는 중심이 되는 프로그램, 즉 Pod 와 같이 CustomResource를 정의하면 자동으로 해당 프로그램을 띄우는 방식으로 사용된다. 하지만 Prometheus Operator 는 Prometheus 자체를 띄우고 관리하는 방식이 아니라 Prometheus 에서 사용되는 설정 등을 관리하기 위해서 사용된다. 한마디로 말하면 Prometheus Operator와 Prometheus 를 모두 설치하고, Operator 로 Prometheus 설정을 CustomResource 로 관리하는 방식이다.
그럼 이제 Prometheus Operator 와 Prometheus 를 설치해 보자. 둘다 모두 prometheus-community 에서 제공하는 helm chart 를 helm3 를 이용하여 설치한다.
helm repo 를 아래와 같이 등록한다.
$ helm repo add prometheus https://prometheus-community.github.io/helm-charts
$ helm repo update
$ helm search repo prometheus
많은 차트들이 검색되는데 그중에서 kube-prometheus-stack chart 로 Prometheus Operator 와 Prometheus 를 설치한다.
1. Prometheus Operator 설치
helm chart 에서 Oeveride 할 value 를 아래와 같이 지정한다.
# vi prometheus-operator-values.yaml
namespaceOverride: prometheus
fullnameOverride: prometheus-operator
defaultRules:
create: false
alertmanager:
enabled: false
grafana:
enabled: false
kubeApiServer:
enabled: false
kubelet:
enabled: false
kubeControllerManager:
enabled: false
coreDns:
enabled: false
kubeDns:
enabled: false
kubeEtcd:
enabled: false
kubeScheduler:
enabled: false
kubeProxy:
enabled: false
kubeStateMetrics:
enabled: false
nodeExporter:
enabled: false
prometheus:
enabled: false
prometheusOperator:
enabled: true
resources:
limits:
cpu: 2
memory: 2Gi
requests:
cpu: 1
memory: 1Gi
serviceMonitor:
selfMonitor: false
nodeSelector:
monitoring: enabled
createCustomResource: true
cleanupCustomResource: true
cleanupCustomResourceBeforeInstall: true
Prometheus Operator 를 설치할 namespace는 namespaceOverride 에 prometheus 로 지정한다.
Deployments 로 생성될 이름은 fullnameOverride 로 prometheus-operator 로 지정한다.
Operator 만 명시적으로 생성할 의도로 나머지 prometheus, exporter, alertmanager 등은 enabled: false 로 지정하여 생성하지 않는다.
Prometheus Operator 가 생성될 노드를 nodeSelector 로 지정할 수 있으며 여기서는 monitoring: enabled 로 세팅했으므로 Kubernetes node 에 해당 label 이 설정된 노드가 있어야 한다.
$ kubectl create ns prometheus
$ kubectl label namespace prometheus name=prometheus
$ kubectl label node k1-node01 monitoring=enabled
$ kubectl label node k1-node02 monitoring =enabled
$ kubectl label node k1-node03 monitoring =enabled
$ kubectl create secret generic etcd-client-cert -n prometheus \
--from-file=etcd-ca=/etc/ssl/etcd/ssl/ca.pem \
--from-file=etcd-client=/etc/ssl/etcd/ssl/member-k1-master01.pem \
--from-file=etcd-client-key=/etc/ssl/etcd/ssl/member-k1-master01-key.pem
prometheus namespace 에 label을 name=prometheus 로 준 이유는 나중에 CustomeResource 인 Service Monitor 가 prometheus namespace 안에 생성되면 자동으로 해당 설정을 적용하기 위해서 Operator 에 알려주는 정보이다. 별도로 설정하지 않아도 prometheus namesapce 에는 자동으로 설정된다.
또 한가지 알아야 할 것은 etcd metric 을 가져오기 위해서는 endpoint 뿐만이 아니라 mTLS 인증서도 있어야 한다. kubernetes 를 kubespary 로 설치하였다면 master 노드의 해당 위치에 etcd 인증서가 있으니 이를 가지고 secret 을 미리 생성해 놓아야 metric 을 가져올 수 있다.
이제 helm 명령어로 Prometheus Operator를 설치한다. upgrade -i 옵션을 주면 설치가 안되어 있을 경우에는 create 명령과 동일하고 설치가 되어 있을 경우에는 upgrade 명령과 동일하다.
$ helm upgrade -i prometheus-operator prometheus/kube-prometheus-stack --version 14.0.1 -f prometheus-operator-values.yaml -n prometheus
2. Prometheus 설치
동일한 kube-prometheus-stack 차트로 prometheus 를 설치한다.
# vi prometheus-values.yaml
defaultRules:
create: false
alertmanager:
enabled: true
service:
type: NodePort
nodePort: 30903
alertmanagerSpec:
nodeSelector:
monitoring: enabled
grafana:
enabled: false
kubeApiServer:
enabled: true
serviceMonitor:
namespaceSelector:
matchNames:
- default
kubeEtcd:
enabled: true
endpoints:
- 192.168.30.13
- 192.168.30.14
- 192.168.30.15
serviceMonitor:
scheme: https
insecureSkipVerify: false
serverName: localhost
caFile: /etc/prometheus/secrets/etcd-client-cert/etcd-ca
certFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client
keyFile: /etc/prometheus/secrets/etcd-client-cert/etcd-client-key
kubeStateMetrics:
enabled: false
nodeExporter:
enabled: false
prometheusOperator:
enabled: false
serviceMonitor:
selfMonitor: true
prometheus:
enabled: true
service:
type: NodePort
nodePort: 30008
# Service for thanos service discovery on sidecar
# Enable this can make Thanos Query can use
# `--store=dnssrv+_grpc._tcp.${kube-prometheus-stack.fullname}-thanos-discovery.${namespace}.svc.cluster.local` to discovery
# Thanos sidecar on prometheus nodes
# (Please remember to change ${kube-prometheus-stack.fullname} and ${namespace}. Not just copy and paste!)
thanosService:
enabled: false
annotations: {}
labels: {}
portName: grpc
port: 10901
targetPort: "grpc"
thanosIngress:
enabled: false
type: NodePort
nodePort: 30901
prometheusSpec:
externalLabels:
cluster: k1
nodeSelector:
monitoring: enabled
secrets:
- etcd-client-cert
ruleNamespaceSelector:
matchLabels:
name: prometheus
ruleSelectorNilUsesHelmValues: false
serviceMonitorNamespaceSelector:
matchLabels:
name: prometheus
serviceMonitorSelectorNilUsesHelmValues: false
podMonitorNamespaceSelector:
matchLabels:
name: prometheus
podMonitorSelectorNilUsesHelmValues: false
retention: 10d
replicas: 1
storageSpec:
volumeClaimTemplate:
spec:
storageClassName: rbd
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi
## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#thanosspec
thanos:
version: v0.18.0
kubeEtcd 는 etcd 가 master 3대에 설치되어 있어 endpoint에 해당 ip 를 모두 넣었으며 caFile, certFile, keyFile 은 앞서 설치한 secret 명을 경로로 포함하고 있다. alertmanager 와 prometheus 모두 nodePort 로 설치하여 접근할 수 있다.
serviceMonitorNamespaceSelector 와 podMonitorNamespaceSelector 를 지정하여 Monitor 할 대상을 CustomResource 를 통해 자동으로 설정할 수 있다. 앞서 prometheus namespace 를 생성할 때 label 을 name=prometheus 로 지정한 이유가 바로 이 부분이다.
마지막으로 Prometheus 가 사용할 storage class 는 rbd 로 지정하여 자동으로 생성되게 설정한다.
helm 으로 Prometheus 를 설치하는 명령은 다음과 같다.
$ helm upgrade -i prometheus prometheus/kube-prometheus-stack --version 14.0.1 -f prometheus-values.yaml -n prometheus
Prometheus 접속 url: http://<node-ip>:30008
alertmanager 접속 url: http://<node-ip>:30903