InfluxDB ile Kubernetes Cluster İzleme ve Metrik Yönetimi
Kubernetes cluster’ınızı izlemek, production ortamında hayatta kalmanın temel koşullarından biri. Pod’lar crash oluyor, node’lar dolup taşıyor, servisler cevap vermiyor ve siz bunları gerçek zamanlı göremiyorsanız, sabahın 3’ünde bir Slack bildirimi yerine müşteri şikayetiyle uyanan türden birisiniz demektir. InfluxDB, zaman serisi verilerini depolamak için tasarlanmış yapısıyla Kubernetes metriklerini toplamak ve analiz etmek için oldukça güçlü bir seçenek sunar. Bu yazıda, InfluxDB’yi Kubernetes cluster’ınıza entegre edecek, Telegraf ile metrikleri toplayacak ve anlamlı sorgular yazacaksınız.
Neden InfluxDB?
Prometheus + Grafana ikilisi Kubernetes monitoring için çok yaygın kullanılır ve harika bir çözümdür. Ancak InfluxDB’nin bazı avantajları vardır. InfluxQL ve Flux sorgu dilleri ile karmaşık zaman serisi analizleri yapmak daha sezgiseldir. Yüksek yazma hızlarında performans kaybı yaşanmaz. InfluxDB 2.x ile gelen built-in dashboard’lar, Grafana olmadan da temel görselleştirme yapmanıza izin verir. Öte yandan InfluxDB Cloud ile on-premise kurulumu arasında geçiş yapmak oldukça kolaydır.
Gerçek dünya senaryosu olarak şunu düşünün: 15 node’lu, 200’den fazla pod çalıştıran bir e-ticaret platformu yönetiyorsunuz. Black Friday yaklaşıyor ve her metriğin anlık olarak izlenmesi gerekiyor. Prometheus’un retention policy’si dolmuş, eski verileri sorgulamak için ayrı bir sistem kurmak istemiyorsunuz. InfluxDB bu noktada uzun dönem retention ve downsampling özellikleriyle devreye giriyor.
Ortam Gereksinimleri
Kuruluma geçmeden önce neye ihtiyacınız olduğunu netleştirelim.
- Çalışan bir Kubernetes cluster (en az 1.20+)
- kubectl erişimi ve admin yetkileri
- Helm 3.x kurulu
- En az 4GB RAM ve 2 CPU’ya sahip bir node (InfluxDB için)
- Persistent Volume desteği (storageClass tanımlı olmalı)
InfluxDB’yi Kubernetes’e Kurma
Helm Repository Ekleme
InfluxDB’nin resmi Helm chart’ını kullanacağız. Bu hem kurulumu kolaylaştırır hem de güncellemeleri yönetmeyi basitleştirir.
helm repo add influxdata https://helm.influxdata.com/
helm repo update
helm search repo influxdata/influxdb2
Bu komutun çıktısında mevcut chart versiyonlarını göreceksiniz. Şu an için 2.x branch’ini kullanmanızı öneririm çünkü InfluxDB 2.x, built-in UI, token tabanlı kimlik doğrulama ve Flux sorgu dili gibi kritik özellikler sunuyor.
Namespace Oluşturma
Monitoring bileşenlerini ayrı bir namespace altında toplamak, RBAC yönetimi ve kaynak izolasyonu açısından büyük kolaylık sağlar.
kubectl create namespace monitoring
kubectl label namespace monitoring purpose=monitoring
InfluxDB Values Dosyası Hazırlama
Varsayılan değerlerle kurulum yapmak yerine, production’a uygun bir values dosyası oluşturalım.
# influxdb-values.yaml
image:
repository: influxdb
tag: 2.7.1-alpine
pullPolicy: IfNotPresent
persistence:
enabled: true
storageClass: "standard"
accessMode: ReadWriteOnce
size: 50Gi
resources:
requests:
memory: "2Gi"
cpu: "500m"
limits:
memory: "4Gi"
cpu: "2000m"
adminUser:
organization: "k8s-monitoring"
bucket: "kubernetes"
user: "admin"
password: "guclu-bir-sifre-koyun"
token: "uzun-ve-rastgele-bir-token-buraya"
service:
type: ClusterIP
port: 8086
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
hostname: influxdb.your-domain.com
tls: true
livenessProbe:
path: "/health"
scheme: "HTTP"
initialDelaySeconds: 30
readinessProbe:
path: "/ready"
scheme: "HTTP"
initialDelaySeconds: 5
Şimdi bu dosyayla kurulumu gerçekleştirelim.
helm upgrade --install influxdb influxdata/influxdb2
--namespace monitoring
--values influxdb-values.yaml
--wait
--timeout 10m
Kurulum tamamlandıktan sonra pod’un ayağa kalktığını doğrulayın.
kubectl get pods -n monitoring -l app.kubernetes.io/name=influxdb2
kubectl logs -n monitoring -l app.kubernetes.io/name=influxdb2 --tail=50
Telegraf ile Kubernetes Metriklerini Toplama
InfluxDB yalnızca veri depolar. Metrikleri toplamak için Telegraf kullanacağız. Telegraf, InfluxData ekosisteminin bir parçası ve yüzlerce input plugin’e sahip bir metrik toplayıcı.
Kubernetes ortamında Telegraf’ı DaemonSet olarak deploy edeceğiz. Bu şekilde her node üzerinde bir Telegraf pod’u çalışır ve o node’a ait metrikleri toplar.
RBAC Yetkilendirmesi
Telegraf’ın Kubernetes API’sine erişebilmesi için gerekli yetkileri tanımlamamız gerekiyor.
# telegraf-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: telegraf
namespace: monitoring
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: telegraf
rules:
- apiGroups: [""]
resources:
- nodes
- nodes/proxy
- nodes/metrics
- services
- endpoints
- pods
- namespaces
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "apps"]
resources:
- deployments
- replicasets
- daemonsets
- statefulsets
verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics", "/metrics/cadvisor"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: telegraf
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: telegraf
subjects:
- kind: ServiceAccount
name: telegraf
namespace: monitoring
kubectl apply -f telegraf-rbac.yaml
Telegraf ConfigMap
Telegraf konfigürasyonu bir ConfigMap olarak saklanacak. Bu yapı, konfigürasyon değişikliklerini pod’ları yeniden oluşturmadan uygulamanıza imkan tanır (elbette pod restart gerekir ama image yeniden çekilmez).
# telegraf-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: telegraf-config
namespace: monitoring
data:
telegraf.conf: |
[agent]
interval = "30s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "5s"
flush_interval = "30s"
flush_jitter = "5s"
precision = ""
hostname = "$HOSTNAME"
omit_hostname = false
[[outputs.influxdb_v2]]
urls = ["http://influxdb-influxdb2.monitoring.svc.cluster.local:8086"]
token = "$INFLUXDB_TOKEN"
organization = "k8s-monitoring"
bucket = "kubernetes"
[[inputs.kubernetes]]
url = "https://$HOSTIP:10250"
bearer_token = "/var/run/secrets/kubernetes.io/serviceaccount/token"
insecure_skip_verify = true
[[inputs.kube_inventory]]
url = "https://kubernetes.default.svc"
bearer_token = "/var/run/secrets/kubernetes.io/serviceaccount/token"
insecure_skip_verify = true
namespace = ""
resource_include = ["deployments", "endpoints", "ingress",
"nodes", "pods", "services", "statefulsets"]
[[inputs.cpu]]
percpu = true
totalcpu = true
collect_cpu_time = false
report_active = false
[[inputs.disk]]
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]
[[inputs.diskio]]
[[inputs.mem]]
[[inputs.net]]
[[inputs.processes]]
[[inputs.system]]
Telegraf DaemonSet
# telegraf-daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: telegraf
namespace: monitoring
labels:
app: telegraf
spec:
selector:
matchLabels:
app: telegraf
template:
metadata:
labels:
app: telegraf
spec:
serviceAccountName: telegraf
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: telegraf
image: telegraf:1.28-alpine
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
env:
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: HOSTIP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: INFLUXDB_TOKEN
valueFrom:
secretKeyRef:
name: influxdb-token
key: token
volumeMounts:
- name: telegraf-config
mountPath: /etc/telegraf
- name: proc
mountPath: /rootfs/proc
readOnly: true
- name: sys
mountPath: /rootfs/sys
readOnly: true
- name: docker-socket
mountPath: /var/run/docker.sock
readOnly: true
securityContext:
privileged: true
volumes:
- name: telegraf-config
configMap:
name: telegraf-config
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name: docker-socket
hostPath:
path: /var/run/docker.sock
hostNetwork: false
hostPID: true
InfluxDB token’ını Secret olarak oluşturun.
kubectl create secret generic influxdb-token
--from-literal=token="uzun-ve-rastgele-bir-token-buraya"
--namespace monitoring
Tüm kaynakları uygulayın.
kubectl apply -f telegraf-configmap.yaml
kubectl apply -f telegraf-daemonset.yaml
kubectl get pods -n monitoring -l app=telegraf
InfluxDB’de Bucket ve Retention Policy Yönetimi
Kubernetes metriklerinin boyutu hızla büyür. Ham verileri sonsuza kadar saklamak hem maliyetli hem de pratik değil. InfluxDB’nin retention policy ve task özellikleri burada devreye giriyor.
# InfluxDB CLI ile bağlanma
kubectl exec -it -n monitoring
$(kubectl get pod -n monitoring -l app.kubernetes.io/name=influxdb2 -o jsonpath='{.items[0].metadata.name}')
-- influx bucket list --org k8s-monitoring
Downsampled metrikler için ayrı bir bucket oluşturalım. Ham veriler 7 gün, örneklenmiş veriler 90 gün saklanacak.
kubectl exec -it -n monitoring
$(kubectl get pod -n monitoring -l app.kubernetes.io/name=influxdb2 -o jsonpath='{.items[0].metadata.name}')
-- influx bucket create
--name kubernetes-downsampled
--org k8s-monitoring
--retention 2160h
Flux ile Kullanışlı Sorgular Yazma
InfluxDB 2.x’in Flux sorgu dili, SQL’e kıyasla zaman serisi verileri için çok daha güçlü. Birkaç gerçek dünya senaryosu için sorgu örnekleri hazırlayalım.
Pod CPU Kullanımı Sorgulama
InfluxDB UI’da veya Grafana üzerinden kullanabileceğiniz sorgular.
// Son 1 saatin pod CPU kullanımı - namespace bazında gruplanmış
from(bucket: "kubernetes")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "kubernetes_pod_container")
|> filter(fn: (r) => r._field == "cpu_usage_nanocores")
|> map(fn: (r) => ({r with _value: float(v: r._value) / 1000000.0}))
|> group(columns: ["namespace", "pod_name"])
|> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
|> yield(name: "pod_cpu_usage")
Node Memory Kullanımı ve Alert Eşiği
// Node memory kullanımı yüzde olarak
from(bucket: "kubernetes")
|> range(start: -30m)
|> filter(fn: (r) => r._measurement == "kubernetes_node")
|> filter(fn: (r) => r._field == "memory_working_set_bytes")
|> group(columns: ["node_name"])
|> aggregateWindow(every: 1m, fn: last, createEmpty: false)
|> map(fn: (r) => ({
r with
_value: float(v: r._value) / (1024.0 * 1024.0 * 1024.0)
}))
|> yield(name: "node_memory_gb")
Downsampling Task Oluşturma
Ham verileri her saat örnekleyerek başka bir bucket’a yazacak bir task tanımlayalım.
// InfluxDB UI > Tasks > Create Task bölümünde kullanın
option task = {
name: "kubernetes-downsampling",
every: 1h,
offset: 5m
}
from(bucket: "kubernetes")
|> range(start: -task.every)
|> filter(fn: (r) =>
r._measurement == "kubernetes_pod_container" or
r._measurement == "kubernetes_node"
)
|> aggregateWindow(every: 5m, fn: mean, createEmpty: false)
|> to(bucket: "kubernetes-downsampled", org: "k8s-monitoring")
Alert Yapılandırması
InfluxDB 2.x’in built-in alerting sistemi, harici bir araç olmadan bildirim göndermenize olanak tanır. Slack entegrasyonu için örnek bir alert tanımı.
# InfluxDB CLI ile check oluşturma
kubectl exec -it -n monitoring
$(kubectl get pod -n monitoring -l app.kubernetes.io/name=influxdb2 -o jsonpath='{.items[0].metadata.name}')
-- influx check create threshold
--name "High Node Memory Usage"
--query 'from(bucket:"kubernetes") |> range(start: -5m) |> filter(fn:(r) => r._measurement == "mem") |> filter(fn:(r) => r._field == "used_percent") |> last()'
--field "_value"
--crit-min 90
--warn-min 80
--every 1m
--org k8s-monitoring
Slack notification endpoint oluşturmak için ise InfluxDB UI’ı kullanmak daha pratik. Alerts > Notification Endpoints > Create yolunu izleyip Slack webhook URL’nizi girin.
Performans Tuning ve Sorun Giderme
InfluxDB Konfigürasyon Optimizasyonu
Yüksek yazma yoğunluğunda karşılaşılan sorunların büyük kısmı cache boyutu ve shard yapılandırmasından kaynaklanır. InfluxDB’nin config.toml dosyasını ConfigMap olarak yönetebilirsiniz.
# Mevcut konfigürasyonu kontrol etme
kubectl exec -it -n monitoring
$(kubectl get pod -n monitoring -l app.kubernetes.io/name=influxdb2 -o jsonpath='{.items[0].metadata.name}')
-- influx server-config
Yaygın Sorunlar ve Çözümleri
Telegraf pod’ları InfluxDB’ye bağlanamıyor:
DNS çözümlemesi sorunları sıkça görülür. Service adının doğru olduğundan emin olun.
kubectl exec -it -n monitoring
$(kubectl get pod -n monitoring -l app=telegraf -o jsonpath='{.items[0].metadata.name}')
-- nslookup influxdb-influxdb2.monitoring.svc.cluster.local
Yüksek cardinality sorunu:
Kubernetes label’larının hepsi tag olarak alınırsa cardinality patlar. Telegraf konfigürasyonuna aşağıdaki filtreleri ekleyin.
[[inputs.kube_inventory]]
url = "https://kubernetes.default.svc"
bearer_token = "/var/run/secrets/kubernetes.io/serviceaccount/token"
insecure_skip_verify = true
[inputs.kube_inventory.tagdrop]
pod_labels = ["*"]
[inputs.kube_inventory.taginclude]
pod_labels = ["app", "version", "environment"]
Disk dolma problemi:
InfluxDB’nin disk kullanımını düzenli kontrol edin.
kubectl exec -it -n monitoring
$(kubectl get pod -n monitoring -l app.kubernetes.io/name=influxdb2 -o jsonpath='{.items[0].metadata.name}')
-- df -h /var/lib/influxdb2
Retention policy’niz çalışmıyorsa bucket ayarlarını doğrulayın.
kubectl exec -it -n monitoring
$(kubectl get pod -n monitoring -l app.kubernetes.io/name=influxdb2 -o jsonpath='{.items[0].metadata.name}')
-- influx bucket list --org k8s-monitoring
Yedekleme Stratejisi
Production’da veri kaybı yaşamamak için düzenli yedekleme şart.
# CronJob ile otomatik yedekleme
cat <<EOF | kubectl apply -f -
apiVersion: batch/v1
kind: CronJob
metadata:
name: influxdb-backup
namespace: monitoring
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: influxdb-backup
image: influxdb:2.7.1-alpine
command:
- /bin/sh
- -c
- |
influx backup /backup/$(date +%Y%m%d)
--host http://influxdb-influxdb2.monitoring.svc.cluster.local:8086
--token $INFLUXDB_TOKEN
--org k8s-monitoring
env:
- name: INFLUXDB_TOKEN
valueFrom:
secretKeyRef:
name: influxdb-token
key: token
volumeMounts:
- name: backup-storage
mountPath: /backup
restartPolicy: OnFailure
volumes:
- name: backup-storage
persistentVolumeClaim:
claimName: influxdb-backup-pvc
EOF
Grafana Entegrasyonu
InfluxDB’nin built-in UI’ı temel ihtiyaçlar için yeterli, ancak Grafana ile çok daha zengin dashboard’lar oluşturabilirsiniz. Grafana data source eklemek için.
- Type: InfluxDB seçin
- Query Language: Flux seçin
- URL:
http://influxdb-influxdb2.monitoring.svc.cluster.local:8086 - Organization:
k8s-monitoring - Token: InfluxDB token’ınız
- Default Bucket:
kubernetes
Grafana Dashboard ID 13502 (InfluxDB 2.x Kubernetes monitoring), doğrudan import edebileceğiniz hazır bir dashboard sunuyor. Import ettikten sonra data source’u kendi InfluxDB kurulumunuzla eşleştirin.
Sonuç
InfluxDB ile Kubernetes cluster monitoring kurulumu ilk bakışta karmaşık görünebilir, ancak parçalara ayırdığınızda oldukça mantıklı bir yapı ortaya çıkıyor. InfluxDB veri depolar, Telegraf metrik toplar, Flux sorgular yazar ve built-in alerting bildirim gönderir. Bu dört bileşen bir arada çalıştığında, cluster’ınızda ne olup bittiğini gerçek zamanlı ve tarihsel olarak takip edebiliyorsunuz.
Özellikle vurgulamak istediğim birkaç nokta var. Cardinality yönetimi production’da en sık sorun yaratan konuların başında gelir, tag seçimlerine dikkat edin. Retention policy ve downsampling’i baştan doğru kurmak, ileride disk krizleriyle uğraşmaktan sizi kurtarır. DaemonSet yapısı sayesinde cluster büyüdükçe monitoring altyapısı da otomatik olarak ölçeklenir ve bu gerçekten büyük bir avantaj.
Son olarak, bu altyapıyı kurmak yetmez; düzenli olarak alert kurallarını gözden geçirin, yedeklemelerin çalıştığını doğrulayın ve Telegraf ile InfluxDB versiyonlarını güncel tutun. Monitoring sisteminizin kendisini de izlemeniz gerektiğini unutmayın, aksi halde izleme aracınız çöktüğünde bunu en son siz öğrenirsiniz.
