Rancher Hatası: Olay Yeri İnceleme
Bugün sizlere herkesin başına gelebilecek, karmaşık gibi görünen ama aslında birkaç önlemle engelleyebileceğiniz, başımızdan geçen bir olayı anlatmak istiyorum.
Şirket içerisinde geliştirdiğimiz uygulamaların test ortamları için bir Kubernetes Cluster’ı kullanıyoruz. Bu Kubernetes Cluster’ını yönetmek için de high-availability olarak kurduğumuz Rancher’dan faydalanıyoruz. 1 master ve 3 node bulunan bu cluster’da şimdilik 4 adet projenin test ortamını yönetiyoruz.
1 Temmuz sabahı uyandığımda Rancher’ın çökmüş olduğunu gördüm. Bununla birlikte hata takip sistemi olarak kullandığımız Sentry’den de bazı hataların düştüğünü farkettim.
Hatanın tespiti
Öncelikle sorunu tespit etmek için ilk olarak Rancher master sunucusuna bağlanıp node’ların durumuna bakmak istedim.
kubectl cluster-info
Bu komutu çalıştırdığımda herhangi bir sonuç alamadım çünkü uzunca bir süre cevap vermedi. Ardından bütün namespace’lerdeki podları listelemek istedim.
kubectl get pods --all-namespaces
Bu şekilde listelediğimde 1000'e yakın belki de daha fazla podun Evicted statüsünde kaldığını gördüm. Evicted olarak görünen podlardan bir tanesine describe dedim.
kubectl -n application describe pod application-test-84f7cb555–747hs
Bunun sonucunda events kısmında alınan hataya ulaştım. Podlar disk pressure hatasından dolayı ayağa kalkamıyordu. Fakat disk pressure’a ne yol açıyordu?
Hatanın kökeninde yatan sebebin tespiti
Disk pressure hatasını görünce ilk yaptığım şey Rancher master ve node’larda df -h çalıştırmak oldu. Bunun sonucunda bütün node’larda %85 doluluk olduğunu gördüm. Bu hatayı araştırdığımda aşağıdaki URL’e ulaştım:
Sayfada yazdığı üzere kubelet’in default bazı değerleri olduğunu gördüm:
The
kubelet
has the following default hard eviction threshold:
memory.available<100Mi
nodefs.available<10%
nodefs.inodesFree<5%
imagefs.available<15%
Bizim durumumuzda imagefs.available değeri %15'ten az olduğu için Kubernetes Cluster’ı eviction sürecine başlamıştı ve çalışmaz hale gelmişti. Rancher’ın çökme sebebini bu şekilde keşfettik. Fakat hala ortada bir problem vardı. Bu disk doluluğuna yol açacak bir şey bulunmuyordu.
Hatanın kökenindeki sebebinin ortadan kaldırılması
Bu disk doluluğunun sebebini araştırmak için öncelikle / dizininde du -sh çalıştırarak doluluğun nereden kaynaklandığını öğrenmek istedim. df -h çalıştırınca disk %85 dolu gözükmesine rağmen / dizininde çalıştırdığım du -sh bana diskin sadece %20 civarında dolu olduğunu gösterdi. Bunun üzerine bunun sebebini araştırdığımda aşağıdaki linkteki cevaba ulaştım:
Söylendiği üzere lsof +L1 komutunu çalıştırdığımda gerçekten de Filebeat tarafından oluşturulmuş böyle bir process olduğunu ve 50GB civarı bir dosyayı açtığını gördüm. Yani pod’lar ölmüş olsa ve log dosyaları silinmiş olsa dahi Filebeat tarafından açık kalan process yüzünden disk doluluğu sabit kalmıştı. Bütün node’larda bu process’i öldürdüm. Bununla birlikte sorunu tamamen çözene kadar da Filebeat servisini durdurdum. Neden böyle bir durum oluştuğunu anlamak için node’larda belli aralıklarla du -sh çalıştırmaya devam ettim. Bir süre sonra /var/lib/docker/containers dizinindeki bir container’in düzenli olarak boyutunun arttığını gördüm. Bu container’ın logunu takip ettiğimde sürekli olarak bir sql hatası bastığını gördüm. Fakat hata ölümcül olmadığı için pod açık kalmıştı ve neredeyse dakikada 1GB’a yakın log dosyası basıyordu. Bu hızda oluşan log dosyasını da Filebeat Elasticsearch’e göndermek isteyince dosya giderek büyüyor ve sorun tekrarlıyordu. Hemen Rancher üzerinden bu deployment’ı durdurdum. Yazılımcı arkadaşlarla iletişime geçerek uygulamadaki sorunun çözülmesini sağladım. Bu noktada Rancher ile ilgili bir problemimiz kalmadı.
Ekstra
Bununla birlikte Kibana üzerinden index’leri de kontrol ettim. Index’leri listelediğimde 30 Haziran tarihinde gelen index’in 50GB’a ulaştığını gördüm. Index pattern’ı refresh etmek istediğimde ise bana aşağıdaki gibi bir hata veriyordu:
Config: Error 403 Forbidden: blocked by: [FORBIDDEN/12/index read-only / allow delete (api)];
Bunun sebebi ise Elasticsearch’ün disk üzerinde belli bir doluluğa ulaşınca index’leri otomatik read-only hale getirmesiymiş. Bunu çözmek için öncelikle 50GB olan index’i sildim. Ardından da aşağıdaki curl komutu ile read-only durumunu kaldırdım.
curl -u elastic -XPUT -H “Content-Type: application/json” http://localhost:9200/_all/_settings -d ‘{“index.blocks.read_only_allow_delete”: null}’
Bu sayede Elasticsearch üzerindeki hatadan kurtulmuş olduk.
Sonuç
Bu olaydan çıkardığımız ders ise bütün sunucuları monitoring araçları ve uygulamaları hata takibi araçları ile takip etmenin ne kadar gerekli olduğu diyebilirim. Normalde bütün ortamlarımızda monitoring yapmamıza rağmen Ar-Ge amaçlı kullandığımız bir ortam olduğu için buraya monitoring araçlarını kurmamıştık. Eğer burada da monitoring yapıyor olsaydık, örneğin disk doluluğunun giderek arttığıyla ilgili bir bildirim alırdık ve bununla birlikte işler bu noktaya gelmeden hızlıca farkedebilir ve müdahale edebilirdik.