eBPF ile Gelişmiş Linux Performans İzleme ve Dinamik Tracing

Performans sorunlarını eski araçlarla gidermek bazen kör adamın fil tarif etmesine benziyor: bir parçayı görüyorsunuz ama büyük resmi kaçırıyorsunuz. top, vmstat, iostat gibi klasik araçlar yüzeysel bilgi verir, ama bir web sunucusunun neden ara ara yavaşladığını, hangi kernel çağrısının darboğaz yarattığını ya da bir container’ın neden beklenmedik ağ gecikmesi yaşadığını anlamak için çok daha derine inmek gerekir. İşte bu noktada eBPF (extended Berkeley Packet Filter) devreye giriyor ve Linux performans analizini tamamen başka bir seviyeye taşıyor.

eBPF Nedir ve Neden Bu Kadar Güçlüdür

eBPF, Linux kernel’ının içinde çalışan küçük sandbox programları yazmanızı sağlayan bir teknolojidir. Kernel modülü yazmak zorunda kalmadan, sistemi yeniden başlatmadan, hatta uygulamayı durdurmadan kernel olaylarını izleyebilir, metrikleri toplayabilir ve hatta ağ trafiğini programatik olarak yönlendirebilirsiniz.

Klasik bir kernel modülü yazdığınızda, bir hata sistemin çökmesine neden olabilir. eBPF programları ise kernel’a yüklenmeden önce bir verifier (doğrulayıcı) sürecinden geçer. Bu verifier, programın sonsuz döngüye girmeyeceğini, geçersiz bellek adreslerine erişmeyeceğini ve sistemi tehlikeye atmayacağını garantiler. Bu güvenlik katmanı sayesinde eBPF’yi production ortamında bile çekinmeden kullanabilirsiniz.

eBPF programları şu hook noktalarına bağlanabilir:

  • kprobes/kretprobes: Herhangi bir kernel fonksiyonunun giriş/çıkışını izler
  • uprobes/uretprobes: Kullanıcı alanı uygulamalarının fonksiyonlarını izler
  • tracepoints: Kernel’ın statik iz noktaları
  • perf events: CPU sayaçları ve donanım olayları
  • XDP (eXpress Data Path): Ağ paketi işleme için son derece düşük gecikme

BCC ve bpftrace: Ana Araçlarınız

eBPF ile doğrudan çalışmak C kodu yazmayı gerektiriyor ve oldukça karmaşık. Neyse ki BCC (BPF Compiler Collection) ve bpftrace bu işi son derece kolaylaştırıyor.

Ubuntu/Debian üzerinde kurulum:

# BCC kurulumu
sudo apt-get update
sudo apt-get install -y bpfcc-tools linux-headers-$(uname -r)

# bpftrace kurulumu
sudo apt-get install -y bpftrace

# Kernel sürümünü kontrol edin, eBPF için 4.4+ gerekli, 5.x önerilen
uname -r

# BCC araçlarının kurulduğunu doğrulayın
ls /usr/share/bcc/tools/

RHEL/CentOS üzerinde:

# EPEL repo'su gerekli
sudo dnf install -y epel-release
sudo dnf install -y bcc-tools bpftrace kernel-devel

# PATH'e ekleyin
export PATH=$PATH:/usr/share/bcc/tools
echo 'export PATH=$PATH:/usr/share/bcc/tools' >> ~/.bashrc

Gerçek Dünya Senaryo 1: Disk I/O Darboğazını Tespit Etmek

Bir üretim sunucusunda iostat yüksek await değerleri gösteriyor ama tam olarak hangi process ve hangi dosyalar bu yükü yaratıyor bilemiyorsunuz. BCC’nin biolatency ve biotop araçları burada inanılmaz faydalı oluyor.

# Disk I/O gecikmelerini histogram olarak göster (10 saniye boyunca)
sudo /usr/share/bcc/tools/biolatency 10 1

# Hangi process'lerin en fazla disk I/O yaptığını göster
sudo /usr/share/bcc/tools/biotop

# Hangi dosyaların okunup yazıldığını takip et
sudo /usr/share/bcc/tools/filetop -C

# Belirli bir process'in dosya operasyonlarını izle
sudo /usr/share/bcc/tools/opensnoop -p $(pgrep mysql)

biolatency çıktısında şöyle bir histogram görürsünüz:

usecs               : count     distribution
0 -> 1          : 0        |                    |
2 -> 3          : 12       |                    |
4 -> 7          : 2893     |********************|
8 -> 15         : 4721     |***********************|
16 -> 31        : 1205     |****                |
32 -> 63        : 89       |                    |
64 -> 127       : 234      |*                   |
128 -> 255      : 891      |***                 |
256 -> 511      : 23       |                    |

128-255 ve 256-511 microsecond aralığındaki spike’lar SSD için normalin üzerinde. Bu durumda blktrace ile daha derin inceleme yapılabilir, ama eBPF sayesinde zaten hangi prosesler bu gecikmelere yol açtığını biliyorsunuz.

Gerçek Dünya Senaryo 2: Ağ Performansı ve Paket Kaybı Analizi

Microservice mimarisinde container’lar arası ağ gecikmelerini anlamak için tcptop ve tcpretrans araçları paha biçilmez.

# TCP bağlantı gecikmelerini izle
sudo /usr/share/bcc/tools/tcptop

# TCP retransmit'leri izle - paket kaybının kanıtı
sudo /usr/share/bcc/tools/tcpretrans

# Yeni TCP bağlantılarını gerçek zamanlı izle
sudo /usr/share/bcc/tools/tcpconnect

# TCP bağlantı kabullerini izle
sudo /usr/share/bcc/tools/tcpaccept

# Belirli bir port üzerindeki TCP trafiğini incele
sudo /usr/share/bcc/tools/tcpretrans -l

Bir Kubernetes cluster’ında pod’lar arası yüksek latency yaşıyorsanız tcpretrans çıktısı şöyle görünür:

TIME     PID    IP LADDR:LPORT          T> RADDR:RPORT          STATE
14:32:01 0      4  10.0.1.15:45231      R> 10.0.2.23:8080       ESTABLISHED
14:32:01 0      4  10.0.1.15:45231      R> 10.0.2.23:8080       ESTABLISHED
14:32:03 0      4  10.0.1.15:45234      R> 10.0.2.23:8080       ESTABLISHED

Aynı kaynak porta sürekli retransmit görüyorsanız, network policy veya CNI katmanında bir sorun var demektir.

bpftrace ile Özel Sorgular Yazmak

bpftrace, eBPF için awk benzeri bir dil sunar. Tek satır sorgulardan karmaşık script’lere kadar her şeyi yazabilirsiniz.

# Sistemdeki tüm exec() çağrılarını izle
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s -> %sn", comm, str(args->filename)); }'

# Her 5 saniyede en çok read() yapan process'leri göster
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_read {
    @reads[comm] = count();
}
interval:s:5 {
    print(@reads);
    clear(@reads);
}'

# Disk yazma gecikmelerini process bazlı histogram olarak göster
sudo bpftrace -e '
kprobe:blk_account_io_start {
    @start[arg0] = nsecs;
}
kprobe:blk_account_io_done /@start[arg0]/ {
    @usecs = hist((nsecs - @start[arg0]) / 1000);
    delete(@start[arg0]);
}'

Bu son örnek özellikle güçlü: kernel’ın I/O başlangıç ve bitiş fonksiyonlarına kprobe takarak nanosecond hassasiyetinde gecikme histogramı çiziyorsunuz. Bunu eski araçlarla yapmak neredeyse imkansız.

Gerçek Dünya Senaryo 3: CPU Performans Sorunları ve Flame Graph

Bir Java uygulaması CPU’yu %90 kullanıyor ama jstack thread dump’ları size net bir cevap vermiyor. eBPF tabanlı profiling burada devreye girer.

# CPU profiling - her saniye stack trace örneği al (30 saniye)
sudo /usr/share/bcc/tools/profile -F 99 30

# Belirli bir PID için CPU profiling
sudo /usr/share/bcc/tools/profile -p $(pgrep java) -F 99 30 > /tmp/java_profile.txt

# Off-CPU analizi - process'in NEDEN beklediğini göster
sudo /usr/share/bcc/tools/offcputime -p $(pgrep nginx) 5

# Wakeup chain analizi
sudo /usr/share/bcc/tools/wakeuptime -p $(pgrep nginx) 5

profile çıktısını Flame Graph’a dönüştürmek için Brendan Gregg’in araçlarını kullanabilirsiniz:

# FlameGraph araçlarını indirin
git clone https://github.com/brendangregg/FlameGraph /opt/flamegraph

# CPU profiling çıktısını flame graph'a dönüştür
sudo /usr/share/bcc/tools/profile -F 99 -f 30 > /tmp/profile_out.txt
/opt/flamegraph/flamegraph.pl /tmp/profile_out.txt > /var/www/html/cpu_flamegraph.svg

# Off-CPU flame graph için
sudo /usr/share/bcc/tools/offcputime -f 5 > /tmp/offcpu_out.txt
/opt/flamegraph/flamegraph.pl --color=io --title="Off-CPU Time" 
    /tmp/offcpu_out.txt > /var/www/html/offcpu_flamegraph.svg

Flame graph’ta en geniş “plato” bölgeler, CPU zamanının nerede harcandığını görsel olarak anlatır. Java uygulamalarında GC ile ilgili frame’ler genişse bellek baskısı var demektir.

Gerçek Dünya Senaryo 4: MySQL/PostgreSQL Sorgu Analizi

Veritabanı yavaşlamaları sysadmin’lerin kabusu. eBPF ile uygulama koduna dokunmadan sorgu sürelerini izleyebilirsiniz.

# MySQL sorgu gecikmelerini izle
sudo /usr/share/bcc/tools/dbslower mysql -m 1

# PostgreSQL sorgu gecikmelerini izle (1ms üzeri sorgular)
sudo /usr/share/bcc/tools/dbslower postgresql -m 1

# Yavaş sorguları dosyaya kaydet
sudo /usr/share/bcc/tools/dbslower mysql -m 5 2>&1 | 
    tee /var/log/slow_queries_ebpf.log

dbslower çıktısı şöyle görünür:

Tracing database queries for pids 2847 slower than 1 ms...
TIME(s)    PID     MS QUERY
0.000000   2847  45.23 SELECT * FROM orders WHERE customer_id = 12345 AND status = 'pending'
0.045230   2847   2.11 UPDATE inventory SET quantity = quantity - 1 WHERE product_id = 789
0.047341   2847  123.4 SELECT o.*, c.email FROM orders o JOIN customers c ON o.cid = c.id WHERE o.created_at > '2024-01-01'

123ms süren o JOIN sorgusu hemen dikkat çekiyor. Index eksikliği olduğunu anlarsınız.

Güvenlik İzleme: Şüpheli Aktiviteleri Yakalamak

eBPF sadece performans için değil, güvenlik izleme için de mükemmel bir araç.

# Privilege escalation girişimlerini izle
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_setuid {
    if (args->uid == 0) {
        printf("UID 0 girişimi! PID: %d, Process: %sn", pid, comm);
    }
}'

# /etc/passwd ve /etc/shadow okumalarını izle
sudo /usr/share/bcc/tools/opensnoop | grep -E "passwd|shadow"

# Reverse shell girişimlerini izle - dışarıya bağlanan shell process'leri
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_connect {
    if (comm == "bash" || comm == "sh" || comm == "zsh") {
        printf("Shell bağlantı girişimi! PID: %d, Comm: %sn", pid, comm);
    }
}'

Bu tür izleme, bir IDS/IPS sisteminin yakalayamayacağı kernel seviyesindeki anomalileri tespit etmenizi sağlar.

Performans İzleme Dashboard’u Oluşturmak

eBPF araçlarını prometheus ve grafana ile entegre etmek için ebpf_exporter kullanabilirsiniz.

# ebpf_exporter kurulumu
wget https://github.com/cloudflare/ebpf_exporter/releases/latest/download/ebpf_exporter_linux_amd64.tar.gz
tar xzf ebpf_exporter_linux_amd64.tar.gz
sudo mv ebpf_exporter /usr/local/bin/

# Örnek konfigürasyon oluştur
cat > /etc/ebpf_exporter/config.yaml << 'EOF'
programs:
  - name: bio_latency
    metrics:
      histograms:
        - name: bio_latency_seconds
          help: Block I/O latency histogram
          table: io_latency
          bucket_type: exp2
          bucket_min: 0
          bucket_max: 26
          labels:
            - name: device
              size: 32
              decoders:
                - name: string
EOF

# Exporter'ı başlat
sudo systemctl start ebpf_exporter
sudo systemctl enable ebpf_exporter

Grafana dashboard’unda bio_latency_seconds metriği üzerinden gerçek zamanlı I/O gecikme histogramı çizebilirsiniz.

Sık Yapılan Hatalar ve İpuçları

eBPF araçlarını kullanırken birkaç pratik noktaya dikkat etmek gerekiyor:

  • Kernel başlıkları eksik: linux-headers-$(uname -r) paketinin kurulu olduğundan emin olun, yoksa BCC araçları derleme hatası verir
  • Yanlış hook noktası: Kernel sürümleri arasında fonksiyon isimleri değişebilir. bpftrace -l 'kprobe:tcp' ile mevcut probe noktalarını listeleyin
  • Production yükü: eBPF programları çok düşük overhead üretir ama yüksek frekanslı tracing (her paket için çalışan XDP gibi) yine de CPU kullanır. Sampling rate’i ayarlayın
  • Stack derinliği: Bazı kernel konfigürasyonlarında PERF_MAX_STACK_DEPTH sınırı var. sysctl kernel.perf_event_max_stack ile kontrol edin
  • Root yetkisi: Çoğu eBPF operasyonu root gerektirir ama CAP_BPF capability ile daha granüler yetki verilebilir
# Mevcut probe noktalarını listele
sudo bpftrace -l 'tracepoint:syscalls:*'
sudo bpftrace -l 'kprobe:*sock*'

# Kernel BPF desteğini kontrol et
sudo bpftool feature probe kernel

# Yüklü BPF programlarını listele
sudo bpftool prog list

# BPF map'lerini incele
sudo bpftool map list

USE Method ile eBPF’yi Birleştirmek

Brendan Gregg’in USE Method (Utilization, Saturation, Errors) metodolojisini eBPF araçlarıyla sistematik bir şekilde uygulayabilirsiniz:

  • CPU Utilization: profile ile CPU flame graph, hangi kodun ne kadar zaman aldığını gösterir
  • CPU Saturation: runqlat ile run queue gecikmelerini ölçün, process’lerin ne kadar beklediklerini görün
  • Memory Saturation: oomkill ile OOM killer aktivitelerini izleyin
  • Disk Utilization: biolatency ve biosnoop ile I/O verimliliğini ölçün
  • Network Errors: tcpretrans ve tcpdrop ile paket kayıplarını tespit edin
# Run queue gecikmesi - CPU doygunluğunun göstergesi
sudo /usr/share/bcc/tools/runqlat 5 1

# OOM killer izleme
sudo /usr/share/bcc/tools/oomkill

# Paket drop'larını izle
sudo /usr/share/bcc/tools/tcpdrop

runqlat çıktısında process’lerin run queue’da milisaniyeler beklediğini görüyorsanız CPU kapasitesi yetersiz demektir, yüksek %idle görseniz bile.

Sonuç

eBPF, Linux sistem yönetiminde gerçek anlamda oyun değiştiren bir teknoloji. “Sistemi yeniden başlatmadan”, “kodu değiştirmeden”, “performans kaybı yaratmadan” derin sistem izlemesi yapabilmek birkaç yıl önce hayal bile edilemezdi. Brendan Gregg’in dediği gibi: “eBPF Linux için ne JavaScript tarayıcı için ise odur.”

Pratikte başlamak için şu yolu öneririm: önce biolatency ve tcpretrans gibi hazır BCC araçlarıyla tanışın. Ardından bpftrace ile tek satırlık sorgular yazmayı öğrenin. Son aşamada kendi eBPF programlarınızı C veya Go ile yazmaya geçebilirsiniz. BCC’nin Python API’si de bu geçiş için mükemmel bir köprü.

Production ortamında eBPF’yi bir kriz anında değil, sakin dönemde test edin. Araçların davranışını baseline alın, anomali tespiti için threshold’lar belirleyin. Prometheus ile entegre ettiğinizde tarihsel veriyi de elde edersiniz ve “dün gece saat 3’te ne oldu?” sorusunu artık “bilmiyorum” diye cevaplamak zorunda kalmazsınız.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir