SSH'den REST'e: güvenlik odaklı Slack EMR veri hattı modernizasyonu
(slack.engineering)- Slack veri platformunda günlük arama indeksleme, analiz işleri ve benzeri kritik veri hatlarını çalıştıran 700'den fazla SSH tabanlı Operator bulunuyordu; tüm işler üretim AWS EMR kümelerine doğrudan SSH bağlantısı gerektiriyor ve bu da geniş bir güvenlik saldırı yüzeyi oluşturuyordu
- Bu SSH bağımlılığı yalnızca bir güvenlik riski değildi; aynı zamanda Spark on Kubernetes, EMR on EKS geçişi ve Whitecastle girişiminin tamamlanması gibi altyapı modernizasyonlarının önündeki temel engeldi
- Çözüm olarak YARN Distributed Shell kullanılarak keyfi kabuk komutlarının bile YARN konteynerlerinde çalıştırılması sağlandı ve Slack'in kendi REST ağ geçidi Quarry üzerinden tüm iş gönderimleri birleştirildi
- 8 veri bölgesine yayılmış 700'den fazla iş, kesinti olmadan (zero downtime) taşındı ve üç çeyrek içinde SSH tamamen ortadan kaldırıldı
- Sonuç olarak saldırı yüzeyi küçüldü, iş güvenilirliği arttı, görünürlük iyileşti; ayrıca Whitecastle'ın tamamlanması ve Spark on Kubernetes gibi yeni nesil altyapılar için temel oluşturuldu
Arka plan: SSH tabanlı veri platformunun oluşumu
- Yaklaşık 2017'de kurulan Slack veri platformu, Airflow'un EMR kümelerinde iş çalıştırması için en doğrudan yol olarak SSH yaklaşımını benimsedi
SSHOperatorile EMR master düğümüne bağlanıpspark-submitgibi komutlar çalıştırılıyordu
- Sonrasında ekipler, farklı kullanım amaçlarına göre (yalnızca Spark değil; MapReduce, AWS CLI, özel Python betikleri de dahil) kendi özel SSH tabanlı Operator'lerini geliştirdi
- Sonuç olarak üretim ortamında 700'den fazla SSH tabanlı iş birikti
SSH yaklaşımının gerçek maliyeti
-
Olası güvenlik riskleri
- Hesaplama kümelerine doğrudan SSH erişimi saldırı yüzeyini büyütüyordu
- Orkestrasyon worker'ları genelinde anahtar dağıtımı ve rotasyonu operasyonel yükü artırıyordu
- Ayrıntılı denetim için birden çok sistem günlüğünün ilişkilendirilmesi gerekiyordu
- Özel security group'lar ve özel yapılandırmalar nedeniyle yetki yönetimi karmaşıklaşıyordu
-
Operasyonel sorunlar
- İşler dağıtılmak yerine doğrudan EMR master düğümünde çalıştığı için kaynak çekişmesi yaşanıyordu
- Kubernetes Pod yeniden başladığında SSH bağlantısı kopuyor ve işler başarısız oluyordu
- Uzun süren işler bağlantı kapansa bile çalışmaya devam ederek zombi süreçlere dönüşebiliyordu
- Bağlantı koptuğunda işin başarılı mı başarısız mı olduğu anlaşılamıyordu
-
Modernizasyonun önündeki engeller
- Spark on Kubernetes ve EMR on EKS'e geçiş mümkün değildi (önce SSH bağımlılığının kaldırılması gerekiyordu)
- Son ana hesap EMR kümesi alt hesaba taşınamadığı için Whitecastle girişimi tamamlanamıyordu
- Whitecastle, güvenlik ve ağ izolasyonunu güçlendirmek için Slack'in AWS altyapısını alt hesaplara taşıma girişimiydi
- Uygun iş izleme ve görünürlük sağlanamıyordu
-
Temsili örnek — Search Infrastructure ekibi
- Slack arama işlevinin çekirdeğini oluşturan, terabaytlarca veriyle günlük Solr arama indeksi oluşturan hat
- SSH tabanlı iş gönderimine bağımlı olduğundan yukarıdaki güvenilirlik sorunlarının tümüne açıktı
REST tabanlı iş gönderiminin temel fikri
-
SSH'nin yapısal sınırları
- SSH oturumu durum tutan doğrudan bir bağlantıdır; Pod yeniden başlatma gibi durumlarda bağlantı koparsa komut çalışmaya devam edebilir, başarısız olabilir ya da geride sahipsiz süreçler bırakabilir
- Yeniden bağlanıp durumu güvenilir şekilde doğrulamanın bir yolu yoktur
-
REST alternatifi
- YARN, Trino, Snowflake gibi modern hesaplama motorları HTTP API ile iş gönderimini destekler
- POST iş isteği → iş kimliği döner
- GET iş durumu sorgusu → çalışıyor/tamamlandı/başarısız bilgisi alınır
- DELETE iş → düzgün iptal edilir
- İş yaşam döngüsü sunucu tarafında yönetilir; istemci yeniden başlasa bile iş çalışmayı sürdürür ve durumu sorgulanabilir
- YARN, Trino, Snowflake gibi modern hesaplama motorları HTTP API ile iş gönderimini destekler
-
YARN'ın rolü ve sınırları
- Hadoop iş yüklerinde (MapReduce, Spark, Hive) YARN hem kaynak yöneticisidir hem de REST API sunar
- Ancak
aws s3 sync,hadoop distcpgibi keyfi kabuk komutları çalıştıran 300'den fazla CLI tabanlı iş için hazır bir REST API yoktu - Bunu çözen kritik unsur YARN Distributed Shell oldu
Dönüm noktası: YARN Distributed Shell
- Spark için Livy REST API, Hive için HiveServer2 bulunduğundan geçiş görece daha basitti
- Buna karşılık MapReduce işleri ve 300'den fazla CLI tabanlı iş için hazır kullanılabilir bir REST API olmadığından problem zordu
-
Gereksinimler
- Mimarinin doğal akışına uyan basit bir REST tabanlı çözüm
- Mevcut kimlik doğrulama/yetkilendirme mekanizmalarının kullanılması (özel güvenlik katmanına gerek olmadan)
- Tescilli bir çözüm yerine açık kaynak protokollerin (standart YARN API) kullanılması
- Minimum karmaşıklıkla özel iş çalıştırma altyapısı kurup işletmekten kaçınmak
-
Değerlendirilip elenen seçenekler
- Uzak komut çalıştırma için özel bir wrapper servis geliştirmek
- Ansible, Salt gibi uzaktan çalıştırma çatılarını kullanmak
- YARN'a sıfırdan yeni bir iş türü eklemek
- Bunların tümü aşırı karmaşıklık, özel güvenlik uygulaması ihtiyacı ve yeni bağımlılıklar nedeniyle uygun bulunmadı
-
YARN Distributed Shell'in keşfi
org.apache.hadoop.yarn.applications.distributedshell.ApplicationMasterile keyfi kabuk betikleri YARN konteyneri içinde çalıştırılabiliyordu- Bu özellik zaten YARN'ın içindeydi, aynı REST API'yi kullanıyordu ve özel bir güvenlik katmanı gerektirmiyordu
-
Çalışma şekli
- 1. Komut betiğini S3'e yükle (ör.
aws s3 sync /tmp/data/ s3://bucket/output/) - 2. Distributed Shell yapılandırmasıyla YARN'a gönder
application-typedeğeriMAPREDUCEolarak ayarlanır,am-container-speciçineDISTRIBUTEDSHELLSCRIPTLOCATION,DISTRIBUTEDSHELLSCRIPTLEN,DISTRIBUTEDSHELLSCRIPTTIMESTAMPgibi ortam değişkenleri eklenir
- 3. YARN konteyner ayırır, betiği indirir ve çalıştırır
- YARN; bellek/vCore gibi kaynak sınırlarını, konteyner izolasyonunu, yeniden deneme ve hata toleransını, düzgün iptali ve YARN UI tabanlı günlüklemeyi yönetir
- 1. Komut betiğini S3'e yükle (ör.
- Bu kararla yalnızca Hadoop iş yükleri değil,
aws s3 sync,hadoop distcp, özel Python betikleri de dahil her şey YARN konteynerlerinde çalıştırılabilir hale geldi
Çözüm: Quarry
- Quarry, EMR/YARN, Trino, Snowflake gibi birden çok hesaplama motoruna iş göndermek için geliştirilmiş Slack'in REST tabanlı iş gönderim ağ geçididir
- Kimlik doğrulama, güvenilirlik ve görünürlük sorunlarını zaten çözmüş durumdaydı ve SSH'yi kaldırma ihtiyacına tam uyuyordu
-
Quarry'nin işlevleri
- Kimlik doğrulama: SSH anahtarları yerine servisler arası token kullanımı
- İş gönderimi: YARN, Trino ve Snowflake'e REST API üzerinden iletim
- Durum takibi: İş durumlarının sunucu tarafında izlenmesi
- Yaşam döngüsü yönetimi: REST API üzerinden düzgün iptal ve temizlik
- Görünürlük: Tüm iş gönderimleri için yapılandırılmış log, metrik ve tracing sağlanması
-
Mimari değişim
- Önce:
Airflow → SSH Connection → EMR Master Node → Execute Command - Sonra:
Airflow → Quarry REST API → YARN ResourceManager → EMR Container - Airflow Operator, SSH bağlantısı kurmak yerine Quarry'ye HTTP isteği gönderir; Quarry işi YARN'a iletir ve durumu poll eder
- Airflow Pod yeniden başlasa bile iş yaşamaya devam eder, bağlantı yönetimini Quarry üstlenir
- Önce:
-
Quarry'nin güçlü yönleri
- YARN Distributed Shell desteği sayesinde genel amaçlı bir iş gönderim ağ geçidine dönüştü
- Spark işleri, Hive sorguları ve kabuk betikleri aynı REST API üzerinden geçti
- SSH kimlik bilgileri ve kümeye doğrudan erişim tamamen kaldırıldı; yalnızca kimlik doğrulamalı, sunucu tarafında izlenen REST çağrıları kaldı
Geçiş yolculuğu
- 8 bağımsız veri bölgesine yayılmış 700'den fazla üretim işi, farklı ağ yapılandırmaları ve veri egemenliği gereksinimleri, ayrıca arama indeksleme gibi kesintisiz çalışması gereken iş yükleri nedeniyle sistemli bir plan gerektiriyordu
-
Aşamalı yaklaşım
- Aşama 1 – Kavram kanıtı (PoC): Pilot işlerle Quarry tabanlı yaklaşım doğrulandı, ilk Quarry Operator geliştirildi ve dev ortamında test edildi
- Aşama 2 – Güvenlik incelemesi: Güvenlik ekibiyle birlikte kimlik bilgilerini kaldırma planı yapıldı ve REST tabanlı yaklaşımın güvenlik gereksinimlerini karşıladığı doğrulandı
- Aşama 3 – OKR tabanlı uygulama: Bir Key Result olarak tanımlanıp yönetim görünürlüğü sağlandı; bu aşamada %80 geçiş kilometre taşı aşıldı
- Aşama 4 – Toplu geçiş: Search Infrastructure, Data Engineering & Analytics, ML Services ve diğer ekipler paralel çalışarak kalan iş yüklerini tüm bölgelere taşıdı
- Aşama 5 – Son temizlik: Eksik DAG'ler tamamlandı, tüm legacy SSH Operator'leri kaldırıldı ve %100'e ulaşıldı
-
Geçiş sayıları
- 7 Operator türünde 700'den fazla iş taşındı
- Koordineli rollout ile 8 bağımsız veri bölgesine uygulandı
- 5 ekip yeni Operator'lere geçti
- İş açısından kritik servislerde kesinti yaşanmadı
- İlk pilot aşamadan SSH'nin %100 kaldırılmasına kadar süreç 3 çeyrekte tamamlandı
Geçiş sırasında karşılaşılan zorluklar
-
Zorluk 1 — Virtual Memory Check hatası
- Veri export DAG'lerinin taşınması sırasında, SSH ile sorunsuz çalışan işler vmem check hatasıyla başarısız oldu
- Neden: SSH işleri doğrudan master düğümde çalıştırdığı için YARN kaynak zorlamasını atlatıyordu; Quarry ise işleri düzgün şekilde YARN'a gönderdiğinden sanal bellek sınırını aşan konteynerler reddediliyordu
- Çözüm: AWS en iyi uygulamalarına uygun olarak tüm kümelerde vmem kontrolü devre dışı bırakıldı —
"yarn.nodemanager.vmem-check-enabled": "false"- Bu, Linux sanal bellek muhasebesinin güvenilir olmaması ve fiziksel bellek sınırının yeterli görülmesi yönündeki AWS tavsiyesiyle uyumluydu
- Ders: SSH birçok sorunu gizlediği için, düzgün YARN gönderimine geçildiğinde daha önce görünmeyen kaynak sınırı problemlerinin ortaya çıkması beklenmelidir; dev ortamında kapsamlı test yapılmalıdır
-
Zorluk 2 — Ağ ayrımı ve EKM bağlantı sorunu
- Dev arama altyapısı işlerini dev kümeden staging analiz kümesine taşırken EKM (Enterprise Key Management) bağlantı zaman aşımı yaşandı
- Hata:
Unable to execute HTTP request: Connect to sts.amazonaws.com:443 failed: connect timed out - Neden: Orijinal kümede anahtar yönetimi uç noktasına ağ yönlendirmesi vardı; ancak daha sıkı ağ segmentinde bulunan staging analiz kümesi aynı bağlantıya sahip değildi ve böylece iş yapılandırmasında açıkça belirtilmemiş ağ topolojisi bağımlılığı ortaya çıktı
- Çözüm: Arama altyapısı işleri, dev servislere yönlendirme yapabilen dev ETL kümesine taşındı; üretim Hive kataloğu gerektiren işler staging'de bırakıldı ve ek yükü karşılamak için dev ETL kümesi büyütüldü
- Ders: Ağ topolojisi kritik önemdedir; hangi işin hangi kümede çalışacağına karar vermeden önce ağ ayrımını ve hesap sınırlarını anlamak gerekir
-
Zorluk 3 — Çok bölgeli karmaşıklık
- Veri egemenliği gereksinimleri nedeniyle 8 bağımsız veri bölgesinde EMR kümeleri çalıştırılıyordu; bu yüzden SSH'yi kaldırmak fiilen 8 paralel geçiş anlamına geldi
-
Karmaşıklık unsurları
- Yapılandırma yönetimi: Her bölge için ayrı Quarry yapılandırması, küme uç noktaları ve ağ yönlendirme kuralları gerekiyordu
- Test yükü: Tüm kod değişikliklerinin 8 bölgenin tamamında doğrulanması gerekiyordu
- Sıralı dağıtım: Eşzamanlı dağıtım mümkün değildi; rollout bölge bazında kademeli yapıldı
- Bölgeye özgü sorunlar: Ağ yapıları, veri egemenliği kuralları ve küme sürümü farkları
-
Nasıl ele alındı
- Tek bir pilot bölgede (çoğunlukla ABD tabanlı) doğrulama yapıldı
- Bölge bazlı yapılandırma gereksinimleri belgelendi
- Bölge farkındalığı olan Quarry Operator geliştirildi
- Kademeli rollout ve bölge bazlı öğrenimler uygulandı
- Her bölgenin geçiş ilerlemesi ayrı ayrı izlendi
- Ders: Çok bölgeli altyapı sadece N kat değil, bölgeye özgü arıza modları nedeniyle N kat daha da zor olabilir; bölgeler arası koordinasyon ve bölge bazlı hata ayıklama için yeterli zaman ayrılmalıdır
Sonuç
- SSH tamamen kaldırıldı; tüm üretim işleri Quarry üzerinden REST tabanlı gönderime geçirildi
-
Güvenlik kazanımları
- 8 bağımsız veri bölgesindeki tüm üretim EMR kümelerinde SSH erişimi kaldırıldı, saldırı yüzeyi büyük ölçüde küçüldü
- SSH anahtar dağıtımı servisler arası token tabanlı kimlik doğrulamaya dönüştürüldü ve REST API log'larıyla düzgün denetim izi sağlandı
- Tüm iş gönderimleri Quarry üzerinden yapılandırılmış loglarla kaydedildi
- Son AWS ana hesap EMR kümesi alt hesaba taşınarak Whitecastle girişimi tamamlandı
- Özel security group'lar ve karmaşık yetki yönetimi kaldırılarak uyumluluk süreçleri sadeleştirildi
-
Operasyonel iyileştirmeler
- Master düğüm kaynak çekişmesi ortadan kalktı; Hadoop dışı tüm işler uygun kaynak tahsisine sahip dağıtılmış YARN konteynerlerinde çalıştı
- İstemci Kubernetes Pod'u yeniden başlasa bile işler ayakta kaldığından iş güvenilirliği ciddi ölçüde arttı; zombi süreçler kayboldu ve REST API üzerinden düzgün sonlandırma mümkün hale geldi
- Quarry API ile yapılandırılmış iş durumu/log/metrikleri sunuldu; iş yaşam döngüsünün tamamı izlenebilir, YARN konteyner log'ları görülebilir ve doğru araçlarla hata ayıklama yapılabilir hale geldi
-
Gelecek için temel
- SSH bağımlılığının kalkmasıyla Spark on Kubernetes geçişi mümkün hale geldi
- REST tabanlı mimari cloud-native pratiklerle uyumlu hale geldi
- Karmaşık SSH yapılandırmaları yerine daha basit ve bakımı kolay Quarry Operator sayesinde ekiplerin adaptasyonu kolaylaştı
- Airflow, EMR altyapısının ayrıntılarından ayrıştırıldı
- Tüm iş gönderimleri Quarry üzerinde standartlaştırıldı, böylece gelecekteki değişiklikler kolaylaştı
- Tamamlanmanın ardından iki yıllık üretim işletimi, mimari kararların doğruluğunu teyit etti; güvenlik, operasyonel kararlılık ve altyapı esnekliği birlikte iyileşti
Çıkarılan dersler
-
İyi çalışan noktalar
- Kademeli geçiş: Dev → GovDev/CommDev → Prod sıralı rollout ve Operator türü bazlı geçiş sayesinde her adımda öğrenim birikti
- Güçlü ekip iş birliği: Search, Analytics, Data Engineering, ML, Marketing gibi farklı alanlardan ekipler hızlı code review ve ortak iletişim kanallarıyla birlikte çalıştı
- Analitik tabanlı ilerleme takibi: Tüm bölgelerde geçiş durumunu gösteren dashboard kuruldu, Airflow veritabanı sorgularıyla kalan SSH tabanlı işler tespit edildi
-
Bugün yeniden yapılsa farklı yapılacaklar
- Ağ topolojisi önceden haritalanmalıydı: EKM bağlantısı gibi ağ ayrımı sorunları geç fark edildi; Whitecastle hesap sınırları ve ağ yönlendirmesi küme geçişinden önce belgelenmeliydi
- Kaynak sınırı testleri daha erken yapılmalıydı: vmem check sorunu geç aşamada ortaya çıktı; ilk pilot aşamadan itibaren SSH ile YARN kaynak sınırı davranış farkı test edilmeliydi
- Operator kısıtları daha önceden duyurulmalıydı: Son aşamada yeni SSHOperator kullanımına kısıt getirildiğinde bazı ekipler bunu bilmiyordu; tüm Airflow kullanıcılarına önceden daha güçlü duyuru yapılmalıydı
-
Büyük ölçekli geçişler için en iyi uygulamalar
- Geçişten önce izlemeyi kurun: Kalan işleri her zaman görebileceğiniz dashboard'u erken oluşturun, Airflow DB sorgularından yararlanın
- Çoklu ortam testi yapın: Dev, CommDev, GovDev ortamlarında test ederek ortama özgü sorunları üretim öncesinde yakalayın; özellikle hesap sınırları arası testler ağ ayrımı problemlerini erken ortaya çıkarır
- Operator'leri kademeli olarak devreden çıkarın: CrunchExecOperator, S3SyncOperator gibi bileşenleri bir seferde bir tane kaldırın; her aşamayı kendi test ve doğrulamasına sahip mini bir proje gibi yönetin; hız biraz düşse de risk ciddi biçimde azalır
Henüz yorum yok.