reklam
Automation

Yüzlerce Sunucuda Sıfır Sürpriz: Ansible ile Kurumsal Linux Çekirdek Denetimi, Sessiz Arka Plan Tuzakları ve IOPS/Kapasite Raporlaması

4 dk okuma
reklam

Birkaç düzine sunucudan oluşan bir ortamda konfigürasyon kaymalarını (configuration drift), disk büyüme hızlarını veya çekirdek modülü zafiyetlerini manuel betiklerle takip edebilirsiniz. Ancak yüzlerce Linux sanal makinesi, veritabanı kümesi ve sanallaştırma düğümünden (KVM/Proxmox, ESXi) oluşan kurumsal bir veri merkezinde “her sunucunun aynı standartta kaldığını” varsaymak, gece yarısı yaşanacak bir kesintiye davetiye çıkarmaktır.
Üretim ortamlarında en sinsi kesintiler genellikle iki sebepten çıkar:

  1. İşletim sisteminin varsayılan olarak açık bıraktığı arka plan zamanlayıcılarının (örneğin Ubuntu apt-daily servislerinin) en yoğun işlem saatinde diski ve CPU’yu kilitlemesi.
  2. Veri disklerindeki (LVM / XFS) sessiz büyümenin veya saniye başına düşen IOPS/Thread artışının merkezi olarak raporlanmaması.

Bugünkü yazımızda, Ansible kullanarak yüzlerce sunucuda sessiz performans katillerini nasıl devre dışı bırakacağımızı, çekirdek modülü zafiyet taramalarını nasıl otomatize edeceğimizi ve her sabah e-postanıza/panelinize düşecek bir Disk Büyüme & Veritabanı IOPS Raporu mimarisini nasıl kuracağımızı inceliyoruz.
1. Üretim Sunucularındaki Gizli Saatli Bomba: apt-daily ve unattended-upgrades
Ubuntu 22.04 / 24.04 LTS kurumsal sunucularda varsayılan olarak aktif gelen apt-daily.timer ve apt-daily-upgrade.timer birimleri, günde iki kez rastgele saatlerde tetiklenir. Bu servisler çalıştığında:

  • Paket indekslerini indirip açarken anlık yüksek disk I/O ve CPU yükü yaratır.
  • unattended-upgrades tetiklenirse, PCI-DSS veya kurumsal değişiklik yönetimi (Change Management) onayınız olmadan arka planda bir kütüphaneyi veya çekirdek paketini güncelleyip dpkg kilidini (lock-frontend) açık bırakabilir.

Bu zamanlayıcıları yüzlerce sunucuda tek seferde, idempotent (tekrar çalıştırılabilir) bir Ansible rolüyle tamamen maskelemek (masked) en temiz kurumsal pratiktir:

reklam
---
# playbooks/disable_apt_timers.yml
- name: Üretim Sunucularında Otomatik APT Zamanlayıcılarını Devre Dışı Bırak
hosts: ubuntu_prod_servers
become: true
tasks:
- name: apt-daily ve apt-daily-upgrade servis/timer birimlerini durdur ve maskele
ansible.builtin.systemd:
name: "{{ item }}"
state: stopped
enabled: false
masked: true
daemon_reload: true
loop:
- apt-daily.service
- apt-daily.timer
- apt-daily-upgrade.service
- apt-daily-upgrade.timer

2. Ansible ile Çekirdek Modülü Zafiyet Denetimi (Canlı lsmod Taraması)
Ağ yığını veya çekirdek protokol zafiyetleri (örneğin paket parçalama/tünelleme açıkları olan esp4, esp6, rxrpc gibi modülleri hedef alan CVE’ler) yayınlandığında, güvenlik ekibinin ilk sorusu şudur: “Hangi sunucularımızda bu çekirdek modülleri şu an bellekte yüklü?”
Sunucuları tek tek gezmek yerine, tüm envanterde bellekte aktif olan riskli modülleri saniyeler içinde tarayıp sadece zafiyet barındıran sunucuları raporlayan Ansible Playbook yapısı:

---
# playbooks/audit_kernel_modules.yml
- name: Riskli Çekirdek Modüllerinin Bellekteki Durumunu Denetle
hosts: all
become: true
gather_facts: false
vars:
vulnerable_modules_regex: "^(esp4|esp6|rxrpc|dccp|sctp)"

tasks:
- name: Bellekte yüklü çekirdek modüllerini kontrol et
ansible.builtin.shell: |
set -o pipefail
lsmod | grep -E '{{ vulnerable_modules_regex }}' || true
args:
executable: /bin/bash
register: lsmod_check
changed_when: false

- name: Riskli modül tespit edilen sunucuları raporla
ansible.builtin.debug:
msg: "UYARI! {{ inventory_hostname }} üzerinde aktif modül bulundu: {{ lsmod_check.stdout_lines }}"
when: lsmod_check.stdout | length > 0

3. Standartlaştırılmış LVM ve XFS Disk Hazırlığı (filesystem & lvol)
Yeni bir Redis, PostgreSQL veya OpenSearch düğümü kurarken disk bölümleme, VG/LV oluşturma ve /etc/fstab içine noatime ile bağlama işlemlerini elle yapmak insan hatasına açıktır. Ansible community.general.lvg ve lvol modülleriyle /dev/sdb (veya SAN multipath diski) üzerinde sıfır hatayla standart veri diski oluşturma şablonu:

---
# playbooks/provision_data_disk.yml
- name: Kurumsal Veri Diski (LVM + XFS) Otomasyonu
hosts: db_and_cache_nodes
become: true
vars:
target_disk: "/dev/sdb"
vg_name: "vg_data"
lv_name: "lv_data"
mount_path: "/mnt/data"

tasks:
- name: Fiziksel disk üzerinde Volume Group (VG) oluştur
community.general.lvg:
vg: "{{ vg_name }}"
pvs: "{{ target_disk }}"
pesize: "16M"

- name: Diskin tamamını kapsayan Logical Volume (LV) oluştur
community.general.lvol:
vg: "{{ vg_name }}"
lv: "{{ lv_name }}"
size: 100%FREE

- name: Performans odaklı XFS dosya sistemi ile formatla
community.general.filesystem:
fstype: xfs
dev: "/dev/{{ vg_name }}/{{ lv_name }}"
opts: "-m crc=1,finobt=1"

- name: Dosya sistemini noatime ve nodiratime ile kalıcı olarak mount et
ansible.posix.mount:
path: "{{ mount_path }}"
src: "/dev/{{ vg_name }}/{{ lv_name }}"
fstype: xfs
opts: "rw,noatime,nodiratime,attr2,inode64,noquota"
state: mounted

4. Günlük Disk Büyümesi ve Veritabanı IOPS/Thread Telemetrisi Toplamak
Kapasite planlamasında en değerli veri “Dün diskte ne kadar yer vardı, bugün ne kadar büyüdü ve saniyede kaç Read/Write IOPS üretiliyor?” sorusunun cevabıdır. Ansible (veya AWX / Ansible Automation Platform) ile her sabah çalışıp tüm veritabanı sunucularından blok cihaz IOPS değerlerini (/proc/diskstats veya iostat), aktif bağlantı/thread sayısını ve dizin boyutunu çekip merkezi yönetim sunucusunda tek bir CSV/HTML rapora dönüştüren görev bloğu:

    - name: Anlık Disk IOPS, Kullanım ve Veritabanı Thread Metriklerini Topla
ansible.builtin.shell: |
# Veri diskinin anlık Read/Write IOPS ve await değerlerini al (2 saniye örneklem)
DISK_STATS=$(iostat -x -d 1 2 | awk '/dm-|nvme|sdb/ {line=$0} END {print line}' | awk '{print "R_IOPS:"$2" W_IOPS:"$8" AWAIT:"$14"ms UTIL:"$16"%"}')
# Veri dizini boyutu (GB)
DATA_SIZE=$(df -BG /var/lib/mysql | awk 'NR==2 {print $3}')
# Aktif mysqld / postgres thread sayısı
THREADS=$(ps -eLf | grep -E 'mysqld|postgres' | grep -v grep | wc -l)
echo "${HOSTNAME} | Disk_Used:${DATA_SIZE} | Threads:${THREADS} | ${DISK_STATS}"
register: node_metrics
changed_when: false

- name: Tüm düğümlerden gelen metrikleri merkezi sunucuda (localhost) tek rapora yaz
ansible.builtin.lineinfile:
path: "/var/reports/daily_infra_health_{{ ansible_date_time.date }}.log"
line: "{{ node_metrics.stdout }}"
create: true
delegate_to: localhost
reklam