Merhaba,

Bugün, bana son günlerde en çok gelen sorulardan birini cevaplamaya çalışacağım. Kubernetes üzerinde veri tabanı çalıştırabilir miyiz? Çalıştırırsak nelere dikkat etmeliyiz? Acaba bu konuda en iyi sektör pratikleri nedir?

Bu konuda yazılan çok güzel yazılar mevcut. Tümünün linkini kaynakça bölümünde bulabilirsiniz. Kendi tecrübelerimi de ekleyerek, sektörün bu konuda çalışan duayenlerini de dikkate alarak bu yazıyı hazırladım.  Umarım faydalı bulursunuz.

Kubernetes’in yönetiminin kolay olması, sunduğu güvenlik düzeyi ve büyük işletmelere sunduğu birçok avantaj nedeniyle hızla popüler bir çözüm haline geldiğini hepimiz biliyoruz. Kubernetes’in kullanımı, uygulamaların kesinti sürelerini ortadan kaldırabilmesi ve basit, otomatik yazılım güncellemeleri ve dağıtımı sunabilmesi nedeniyle  gittikçe artmaktadır. Kubernetes mimarisi, fiziksel cihazları yönetme ihtiyacını ortadan kaldırdığı gibi  uygulamalarımız için gerekli olan bellek ve bilgi işlem kapasitesini çekirdek teknolojiyle ilgilenmeden belirlememizi sağlamaktadır. Elbette sistem ve altyapı mühendisleri yapının kurulumu, entegrasyonu, devamlılığı için gerekli çalışmaları yapmak zorunda zira sonuçta yapı bir donanım üzerinde çalışıyor. Yazılım geliştiriciler için sağladığı avantajlara vurgu yapmak için özellikle bu cümleyi kullandım.  Kubernetes’in ayrıca, ölçeklendirme ve hareketlilik için son derece faydalı olduğu da bir gerçektir.

Diğer taraftan, esneklik ve işlevselliğine rağmen, Kubernetes’in kalıcı olmayan veya kısa ömürlü depolama kullanma ihtiyacında olan uygulamalar için tasarlanma mantığına yakın olması sebebiyle; çoğu üretim yazılımı durum bilgisine sahip olduğundan ve depolama gerektirdiğinden, bu tür uygulamaların, Kubernetes üzerinde nasıl sağlıklı çalıştırılabileceğine dair soru işaretleri mevcut.

Elbette, bu endişeleri gidermek için Kubernetes, depolama yönetimi repertuarına kalıcı birimler/volümler (Persistent volume) ve depolama sınıfı (storage class) nesneleri ekledi. Kubernetes 1.5’ten bu yana StatefulSets özelliği, pod’ların başka bir sisteme taşınsalar bile benzersiz kimliklerini (unique ID) korumasını sağlamıştır. Ayrıca uygulama, uygulama verilerini, ilişkili bir kalıcı birime (persistent volume) bağlayarak kalıcı hale getirebilmektedir. Daha da önemlisi, artık Kubernetes’e bağlanan operatörlerin kullanımı sayesinde, Cassandra, PostgreSQL, MySQL, Couchbase, MongoDB gibi pek çok veri tabanlarını sorunsuz bir şekilde Kubernetes üzerinde çalıştırabiliriz.

Bir veri tabanını Kubernetes kümelerinde konumlandırmadan önce, birkaç faktörü göz önünde bulundurmamız gerekmektedir.

Hatırlamamız gereken en önemli şey, Kubernetes’in durumsuz (stateless) bir ortam olmasıdır. Bu, verilerimizin geleneksel bir depolama ortamında sakladığımız kadar kalıcı olmadığı anlamına gelir. Unutmayalım ki, “pod”lar sorunlar ortaya çıktığında kaldırılacak ve yeniden başlatılacak şekilde tasarlanmış yapılardır.

Bu nedenle, veri tabanlarının, Kubernetes’in donatıldığı yük devretme (load balancing) ve kalıcı volümlerin yönetilmesi gerektiği gibi pek çok teknolojiye yatkın olması gerekir.

Kubernetes’te veri tabanı dağıtımlarımız için, öncelikle, doğru veri tabanı çözümüyle başladığımızdan emin olmamız önemlidir. Kubernetes’teki veriler için en iyi veri tabanı, yük dengeleme ve kalıcı birimleri/volümler (persistent volumes) gibi platforma uygun bu özellikleri desteklemelidir.

Bu nedenle, ilk adımınız bu özelliklerin çalışıp çalışmadığını doğrulamak olmalıdır. Bir test veri tabanı oluşturmalı ve ardından kapsamlı bir şekilde stres testi yapmalıyız. Veri tabanını bir kez konuşlandırdığımızda mümkün olan en iyi şekilde çalıştığından emin olmamız önemlidir. Bu testler, ayrıca yapılandırmalarımızın doğru olup olmadığını doğrulamamıza da imkan sağlar.

Genellikle, Kubernetes’teki veriler için en iyi veri tabanı dağıtımı, operatörler aracılığıyla yapılır.

Ayrıca, hangi çoğaltma modlarını (replication modes) kullandığımıza da dikkat etmemiz gerekir. En iyi veri tabanı, Kubernetes’teki veriler için, hem zaman uyumlu (synchronous) hem de zaman uyumsuz çoğaltmaya (asynchronous) izin vermelidir. Elbette, ilki, yani senkron replikasyon, daha güvenilirdir ancak daha fazla kaynak tüketir, ancak ikincisi yani asenkron replikasyon daha yüksek veri kaybı riski taşır. Uygulamalarımızın, bu risklerin ne kadarını kaldırabileceğinden emin olmamız gerekir.

Kubernetes operatörleri, hem Kubernetes’in üstünde hem de API’lerinin arka planında uygulamalar geliştirir ve çalıştırır. Tek bir Kubernetes operatörü, servislerin kurulumunun otomasyonunu sağlar. Örneğin, Couchbase için Kubernetes Operator’ü yüklemek, bu servisin tüm yaşam döngüsünün yönetilmesini sağlar. Gerekli tüm paketlemeyi tek bir komutla yapma olanağı sağlar. Operatörler sayesinde, pek çok servisi kolaylıkla Kubernetes üzerinde yapılandırabiliriz.

Aslında buraya kadar yazdıklarımızdan çıkan en önemli sonuç, eğer veri tabanlarını Kubernetes ortamlarında çalıştırmak istiyorsak, Kubernetes ortamında ölçeklenebilir güvenli bir veri katmanı sağlamalıyız.

Dağıtık veri tabanı özelliklerini hatırlayalım. Biliyorsunuz, çoğu veri tabanı moturu (engine),  veriyi dağıtmak ve veriyi yüksek düzeyde kullanılabilir yapmak için pek çok özellikle gelir. Kubernetes üzerinde çalıştıracağımız veri tabanı seçiminde en azından aşağıdaki durumları göz önüne almalıyız.

Çoğaltma (Replikasyon): Veri tabanı, replikasyonu destekliyor mu? Eğer destekliyorsa, hangi tür replikasyonları destekliyor (örneğin, çift yönlü (bidirectional), işlemsel (transactional), anlık görüntü (snapshot). Bu özellikler, güvenilirliği, hata toleransını ve erişebilirliği geliştirmemize yardımcı olmaktadır.

Parçalama (Sharding): Veri tabanı, veriyi bölümlere ayırabilir mi? Verinin farklı parçalarını pod’larda tutabilir mi? Bu özellik, yedekliliği artırdığı gibi, yükü dağıtmamızı da sağlar.

Yük Devretme (Fail-Over): Veri tabanı, ana, okuma-yazma düğümünden (master node) diğer salt okunur düğümlere yük devretme ve salt okunur düğümü, ana düğüm olarak yükseltme yeteneğine sahip mi? Bu özellik,  güvenilirliği, hata toleransını ve erişilebilirliği geliştirmeye yardımcı olacaktır.

Ölçeklenebilirlik (Scalability): Veri tabanı, ölçeklemeyi destekliyor mu? Kubernetes, yatay ölçeklendirmenin önünü açar, ancak veri tabanının isteğe bağlı olarak örnek (instances) ekleme veya kaldırma işlemlerini gerçekleştirmesi gerekir. Bu, artan yükü karşılayabilmeyi veya yük azaldığında maliyetleri düşürmemize yardımcı olur.

Daha önce de ifade ettiğim gibi, pod’lar ve hesaplama düğümleri (compute nodes) doğası gereği, genellikle geçici olduğundan, Kubernetes bazı veri türleri için diğerlerinden daha uygundur. Kubernetes’de veri yoğun yapıları oluştururken, verilerin ne kadar kritik olduğunu ve ne derecede erişilebilir olması gerektiğini anlamamız çok önemlidir.

Yüksek kullanılabilirlik elde etmek için bazı veri tabanı motorları nihai tutarlılık (eventual consistency) denilen mekanizmayı kullanır. Nihai tutarlılık, belirli bir veri parçasında yeni güncellemeler yapılmazsa, eninde sonunda, tüm erişimin en son güncellenen değeri döndürmesini sağlayan bir tekniktir. Veriler sürekli güncellendiği için herhangi bir zamanda farklı düğümlerde (nereden okuduğunuza bağlı olarak) bazı tutarsızlıklar olabileceğini varsayar, ancak güncellemeler tamamlandığında, tüm düğümlerde verinin aynı kopyası olacaktır ve tüm istemci istekleri aynı verileri alacaktır. Kubernetes’te veritabanı sistemleri çalıştırdığınızda, bunun iş ihtiyacınız için kabul edilebilir olup olmadığını düşünmemiz gerekir. Örneğin, bu finansal sistemler için bir seçenek olmayabilir.

Bazı veri tabanı motorları yük devretmelerle başa çıkabilir (örneğin, verilerin birincil okuma/yazma kopyasını çalıştıran pod yeniden planlandığında veya çöktüğünde), ancak ikincil veya yedek düğümün kurtarılması ve birincil rolü üstlenmesi biraz zaman alabilir.  Bu gibi durumlarda, eski verilerin kabul edilebilir olup olmadığını iş ihtiyacınıza göre belirlemeniz gerekir.  Örneğin, hasta geçmişi kayıtlarını gösteren bir sağlık hizmeti çözümünde bu durum uygulanabilir olmayabilir.

Gördüğünüz gibi, veri tabanı seçimi, iş gereksinimlerimize bağlıdır. Geçici verilerle (örneğin önbelleğe alma katmanları), salt okunur verilerle (örnegin arama tabloları) veya kolayca yeniden oluşturulabilen verilerle (örneğin API çıktıları) ilgilenen iş yükleri Kubernetes için daha uygun olabilir.

Kubernetes bir orkestrasyon çözümü olarak,  zamanlama (scheduling), otomatik ölçeklendirme (auto-scaling) veya yük devretme (fail-over) gibi birçok yaygın operasyonel işlevi basitleştirir. Durum bilgisi olmayan iş yükleri bu modele tam olarak uysa da, veri tabanları gibi durum bilgisi olan iş yüklerinin ele alınması için endişelerimizin adreslenmesi gerekmektedir.

Dediğim gibi kalıcı birimler (persistent volume) ve depolama sınıfları (storage classes), verileri yönetmek için güvenli ve soyut bir yol sunmaktadır.

StatefulSets ve DaemonSets özellikleri, pod’ların kalıcı verilere entegre olarak bağlanmasına izin verir.

“Custom Resources” ve operatörler, veri kalıcılığına ihtiyaç duyan uygulamalar için özel bir mekanizma sağlamaktadır.

Ancak, Kubernetes’te çalıştırmak istediğimiz veri tabanı motoru için mevcut desteğin yanı sıra depolamak istediğimiz veri türünü ve verilerin kullanılabilirlik gereksinimlerini de dikkate almamız önemlidir.

Çoğaltma (replication), parçalama (sharding) ve yük devretme (fail-over) işlemlerini gerçekleştirebilen veri tabanları bu nedenle Kubernetes için daha iyi adaylardır. Benzer şekilde, kolayca ve hızlı bir şekilde yeniden oluşturulabilen veriler de Kubernetes’de barındırmak için de en iyi adaylardır.

Tüm bu konuşulanlara göre acaba veri tabanını Kubernetes’de çalıştırabilir miyim ile ilgili karar ağacı, https://cloud.google.com/blog/products/databases/to-run-or-not-to-run-a-database-on-kubernetes-what-to-consider linkinde aşağıdaki şekilde çok güzel özetlenmiş.

No alt text provided for this image

Şekil 1. Veri tabanını Kubernetes’de mi çalıştırmalıyım?

StatefulSets özelliği sayesinde, verimizi kalıcı birimlerde depolayabiliriz demiştik. Yani, pod yeniden oluşturulsa bile, verimiz hala orada olacaktır. Ek olarak, pod, StatefulSet içinde yeniden oluşturulduğunda, aynı isim korunacaktır ve bağlanacağımız son nokta değişmeyecektir. Anladığımız gibi, kalıcı veri ve tutarlı adlandırma (consistent naming), StatefulSet’in sağladığı iki önemli özelliktir.

Görece olarak Kubernetes dostu olmayan veri tabanları için, (MySQL veya PostgreSQL) gibi, Kubernetes operatörlerini kullanabilirsiniz. Veya, bu veri tabanlarına ek özellikler sağlayan projeleri de değerlendirebilirsiniz. Operatörler, bu veri tabanı yapılandırmalarınızı hızlandırır, veri tabanı bakım hizmetlerinizi yapmanızı sağlar. Örneğin, Yedekleme ve replikasyon gibi.

Operatörler, Kubernetes API aracılığıyla uygulamaya özel işlemleri ortaya çıkarmak için özel kaynakları (custom resources) ve denetleyicileri (controllers) kullanır.

PostgreSQL için Patroni gibi keşfedebileceğiniz başka projeler de var. Bu projeler operatörleri kullanır, ancak bir adım daha ileri gider. Kubernetes içindeki operasyonlara yardımcı olmak için ilgili veri tabanlarının etrafında birçok ek çözüm sağlar. Kubernetes’te MySQL veya PostgreSQL’i başarıyla dağıtmak için gereken parçalama (sharding), lider seçimi (leader election) ve yük devretme (fail-over) gibi ek özellikleri içerebilirler.

Kubernetes üzerinde veri tabanı çalıştırmak için yapılan çok projeler, çalışmalar var. Bu geliştirilen yeni teknolojiler, projeler ve çözümler, Kubernetes’de veri tabanı çalıştırmayı bir norm haline getirmeyi hedeflemektedir. Bu nedenle bizim, gelişen teknolojileri iyi takip etmemiz önemli olacaktır.

Elbette, depolama birimi üreticileri de Kubernetes üzerinde, veri tabanı verisini kalıcı olarak tutabilmemiz için CSI (Container Storage Interface) dediğimiz modern teknolojilere yoğun yatırımlar yapıyor ve geleneksel depolama birimlerine olan güvenimizi Kubernetes üzerinde kullandığımız kalıcı birimlere de taşımaya gayret gösteriyorlar.

https://cloud.netapp.com/blog/cvo-blg-kubernetes-database-how-to-deploy-manage-dbs-on-kubernetes de MSSQL’i Kubernetes üzerinde nasıl çalıştıracağımızı anlatıyor. Açıkcası, evet unix ile iş hayatıma başladım ama, Microsoft’un modern teknolojileri takip ederek dönüşümlerini hızlıca yapması beni gerçekten etkiliyor. Ubuntu, Windows ve RHEL’i destekleyen resmi SQL Server konteyner imajları mevcut.

No alt text provided for this image

Şekil 2. Durum bilgisi tutan uygulama için bir örnekleme.

Kubernetes’e, kalıcı birimler ve depolama Sınıfı nesneleri gibi depolamayı yönetmeye yardımcı olabilecek çeşitli yöntemler eklendiğini belirttim. Kubernetes’in 1.5 sürümünden itibaren, StatefulSets’i (ve ilgili, ancak daha karmaşık DaemonSets’i) sunarak podların, başka bir makineye yeniden planlansalar bile aynı benzersiz kimliği koruduğunu ifade etmiştim. Bu sayede, podları benzersiz kimlikleri aracılığıyla uzak bir kalıcı birime” bağladığımızda, uygulamanın, podlar oluşturulurken ve yok edilirken bile durumunu korumasını sağlar. Şekil 2, bir örneklemeyi görsel olarak göstermektedir.

Örneğin, Percona, Kubernetes’te yüksek düzeyde kullanılabilir, kurumsal kullanıma hazır MySQL, PostgreSQL ve MongoDB kümeleri oluşturmak ve yönetmek için operatörler sağlamaktadır. %100 açık kaynak olarak bu operatörleri sağlamaktadır.

Oracle’da MySQL için Kubernetes operatörü sağlamaktadır.

Couchbase’de, yine Kubernetes operatörü sağlamaktadır.

Oracle, Oracle Database 21c (21.3) ile başlayarak, parçalanmış (sharded) veri tabanları için Kubernetes ve Docker tabanlı dağıtımları desteklemektedir.

Evet, yazımın sonunda, özetlemem gerekirse, Kubernetes ile gelen ve ihtiyaca uygun olarak geliştirilen ek özellikler, depolama üreticilerinin CSI’a yaptıkları yatırımlar, operatörlerin ve projelerin hızla gelişmesi, Kubernetes üzerinde kritik iş uygulamalarımız için veri tabanlarını çalıştırmayı mümkün hale getiriyor. Yukarda ifade ettiğim gibi, Kubernetes üzerinde veri tabanı çalıştırmak için, depolamak istediğimiz veri türünü ve verilerin kullanılabilirlik gereksinimlerini de dikkate almamız önemlidir. Modern dünyanın yeni altyapısı olarak karşımıza çıkan Kubernetes, durum bilgisi tutmayan uygulamalardaki başarısını, görünen o ki, durum bilgisi tutan uygulalamar için de sağlamaya kararlı. Ekosistemin de bu hedefe ulaşmak amacıyla gerekli tamamlayıcı teknolojileri sağlamak için yoğun bir çaba içerisinde olduğunu görüyoruz.

Sarav Asiye Yiğit – 31 Temmuz 2022 Pazar

Kaynakça:

https://portworx.com/blog/which-databases-best-complement-kubernetes/#:~:text=Kubernetes%20Database%20Best%20Practices&text=The%20most%20important%20thing%20to,and%20restarted%20when%20problems%20arise.

https://www.containiq.com/post/should-you-run-a-database-on-kubernetes

https://cloud.google.com/blog/products/databases/to-run-or-not-to-run-a-database-on-kubernetes-what-to-consider

https://thenewstack.io/a-case-for-databases-on-kubernetes-from-a-former-skeptic/

https://spacelift.io/blog/kubernetes-best-practices

https://cloud.netapp.com/blog/cvo-blg-kubernetes-database-how-to-deploy-manage-dbs-on-kubernetes

https://softwareengineeringdaily.com/2020/09/22/what-makes-a-database-a-good-fit-to-run-in-kubernetes/

https://www.dbta.com/Webinars/1612-Running-Databases-on-Kubernetes-Considerations-and-Best-Practices.htm

https://blog.yugabyte.com/best-practices-and-recommendations-for-distributed-sql-on-kubernetes/

https://www.weave.works/blog/how-to-correctly-handle-db-schemas-during-kubernetes-rollouts

https://venturebeat.com/2022/07/02/when-why-and-how-to-run-databases-in-kubernetes/

https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/

https://www.percona.com/software/percona-kubernetes-operators

https://blogs.oracle.com/database/post/oracle-sharding-on-kubernetes-and-docker

https://portworx.com/blog/getting-started-with-the-oracle-mysql-kubernetes-operator-with-portworx-on-oci/

https://docs.couchbase.com/operator/current/install-kubernetes.html