Spring Cloud Config və Kubernetes ConfigMap — Detallı Müqayisə

Joshgun Huseynov
6 min readAug 31, 2021

--

Read the English version

Hər hansı bir layihə üzərində işləyən zaman bir çox mövzular bizi narahat edir, bu narahatçılıqlar Clean Code-dan başlayır və sistemin daimiliyinə (high availability) qədər gedib çıxır. Bütün bu konseptlər haqqında internetdə saysız məqalələr, “best practice”-lər olsa da digər bir nüans — konfiqurasiyanın menecmenti mövzusuna sanki nisbətən daha az toxunulur.

Ona görə də bu məqalədə hazırki dövrdə iki fərqli sahənin “nəhəng”ləri — developmentdə geniş istifadə olunan Spring Framework-un təklif etdiyi “Spring Cloud Config” və konteyner idarəetməsində populyarlaşan Kubernetes-in təklif etdiyi ConfigMap həllərini müqayisə edəcəm.

Müqayisəyə başlamadan öncə onu qeyd etmək vacibdir ki, bu tip arxitektur problemlərə hamı üçün ideal olan ortaq bir həll yolu demək olar ki, olmur və hər bir problemin həllini axtaran zaman sistemin hazırki vəziyyəti, biznes tələbləri, komanda üzvlərinin sayı, iş bölgüsü və s. kimi ümumi vəziyyəti nəzərə almaq lazımdır. Yəni bir ssenari üçün ideal sayılan həll digər layihələr üçün yararsız ola bilər. Ona görə də aşağıdakı müqayisədə çalışacam ki, hər iki texnologiyanın müsbət və mənfi tərəfini qeyd edim və hansını nə səbəbə seçdiyimi izah edim.

Ən əsası da öz təcrübəmdən gördüyüm qədərilə, hansısa bir həll və ya texnologiya hazırda məşhurdursa o demək deyil mütləq onu istifadə etmək lazımdır. Hansısa problemə lazımsız həllər gətirmək mövcud sistemi daha da qəlizləşdirməyə gətirib çıxara bilir (over-engineering problemi)

Spring Cloud Config

Spring Cloud Config hazırki vəziyyətdə həm server həm klient tərəfdə hazır həllər təklif etməklə konfiqurasiya kənarlaşdırılmasını (configuration externalization) tam dəstəkləyir və paylanmış sistemlər (distributed systems) üçün rahat mərkəzləşdirilmiş konfiqurasiya idarəetməsini təmin edir. Spring Cloud Configin qurulmasına kod səviyyəsində tam detallı toxunmayacam çünki bununla bağlı internetdə saysız məlumatlar mövcuddur. Öz istifadə etdiyim mənbələrdən bəziləri:

Gördüyümüz kimi ümumi olaraq Spring Cloud Configi tam hazır vəziyyətə gətirərkən aşağıdakı mərhələlərdən keçirik:

  • Konfiqurasiya fayllarının saxlanılması üçün Git repository yaradırıq. (Əslində bunun əvəzinə fayl sistemindən də oxumaq olar ancaq production üçün məsləhət görülən forması Git-dən oxumaqdır)
  • Spring Cloud Config Server rolunda iştirak edəcək ayrıca bir application yaradırıq və orada uyğun tənzimləmələri edirik (Spring Cloud Config Server kitabxanalarını əlavə edirik, Git repositorynin ünvanını tanıdırıq və s.). Bundan sonra application-ı Config Server kimi istifadə edə bilərik və startup vaxtı Config Server Git-dən uyğun konfiqurasiya fayllarını oxuyaraq onları REST Endpoint-lər vasitəsilə klientlər üçün əlçatan edir.
  • Öz konfiqurasiyalarını bu serverdən oxuyacaq hər bir application üçün uyğun tənzimləmələr edirik (Config Serverin ünvanını tanıdırıq, hansı profillərə uyğun konfiqləri götürəcəyimizi qeyd edirik və s.). Yuxarıda qeyd etdiyimiz kimi Config Server konfiqurasiyaları REST Endpointlər vasitəsilə expose etdiyinə görə, bundan sonra hər bir çalışan application ilkin mərhələdə öz uyğun kofiqurasiyalarını Config Serverdən oxuyacaq (və ya oxumağa çalışacaq).

İlkin mərhələdə hər şey hazır kimi görünsədə, prosesi tamamlamaq üçün bəzi əlavə işlər də görülməlidir. Məsələn, konfiqurasiya dəyişikliklərini dinamik olaraq applicationlara mənimsətməliyik, çünki digər halda applicationların yeni konfiqurasiyaları oxuması üçün hər dəfə onları restart etməyimiz lazım olacaq ki, bunun da nə üçün yaxşı ideya olmadığını məncə bilirsiniz.

Yəni növbəti addımda:

  • Konfiqurasiya dəyişikliklərinin dinamik olaraq applicationlara ötürülməsi üçün əlavə bir message broker serveri qaldırırıq (Məs.: RabbitMQ, Kafka). Bunun vasitəsilə Config Server öz klientlərinə dəyişikliklər barədə mesajlar göndərərək onların yeni dəyərləri istifadə etməsi barədə məlumatlandıracaq
  • Bu dəyişikliklərin klientlər tərəfindən qəbul olunması üçün Spring-in hazır kitabxanalarından istifadə edərək tənzimləmələr edirik (Spring Cloud Bus, Spring Boot Actuator və s.)

Bütün bu addımlardan sonra artıq Spring Cloud Config həlli vasitəsilə konfiqurasiyalarımızı kənarlaşdırırıq və nəticədə ümumi mənzərə aşağıdakı kimi görsənir:

Kubernetes ConfigMap

Kubernetesin təklif etdiyi ConfigMap obyekti də həmçinin applicationların istifadə etdiyi konfiqurasiyaları konteynerdən kənarlaşdırmaq üçün optimal yol hesab edilə bilər. Eyni zamanda bunu da qeyd etmək lazımdır ki, Spring Framework-undə də applicationların Kubernetes mühitinə rahat inteqrasiyasını təmin etmək üçün çox sayda kitabxanalar mövcuddur. Elə biz də bu kitabxanalar vasitəsilə Spring applicationun öz konfiqurasiyasını ConfigMap-dan oxumasını təmin edəcəyik.

Bu hissədə də ConfigMap və Spring Boot inteqrasiyasını detallı izah etməsəm də öz faydalandığım linkləri aşağıda qeyd edərək ümumi mənzərəni addım-addım sıralayacam:

Nəzərə alıram ki, application üçün Kubernetes mühiti daha əvvəldən qurulub və aşağıdakı addımlarda mühitin qurulmasını qeyd etmirəm:

  • Birinci addımda kubernetes client vasitəsilə clusterə qoşularaq orda bizə lazım olan ConfigMap obyektini yaradırıq və konfiqurasiya dəyişənlərini ConfigMap-a tanıdırıq. Bu dəyişənləri həm fayldan, həm qovluqdan həm də bir başa key-value cütləri formasında ConfigMap-a tanıtmaq mümkündür.
  • Daha sonra Spring applicationlarımızda uyğun kitabxanaları tanıtmaqla (Spring Boot Kubernetes Client, Spring Boot Actuator və s.) kubernetesdə yaratmış olduğumuz ConfgMap obyektlərinin adını, hansı namespace-də olduqlarını və s. tənzimləmələri edirik.

Qeyd edim ki, konfiqurasiya dəyişikliklərinin dinamik yüklənməsi üçün əlavə heç bir komponentə ehtiyac yoxdur və Spring Boot Kubernetes kitabxanası sayəsində bu proses də nəzərə alınıb. (applicationlarda uyğun konfiqurasiyaları etməklə)

Bu prosedurlardan sonra artıq applicationlarımız kubernetes mühitinə deploy olunan zaman öz konfiqurasiyalarını ConfigMap-dan oxuyur və yekun mənzərə aşağıdakı kimi olur:

Spring Cloud Config — müsbət tərəfləri

  • Əgər ekosistemimizin digər hissələrində də Spring texnologiyaları istifadə olunubsa Spring Cloud Config də digər komponentlərlə asan inteqrasiya olunacaq çünki client və server hissələr üçün artıq daha öncədən Spring tərəfindən yazılmış kitabxanalar inteqrasiyanı olduqca rahatlaşdırır
  • Konfiqurasiyaların mərkəzləşmiş idarəetməsini təmin edir. Yəni sadəcə bir Git repository yaradaraq bütün konfiqurasiyaları oradan idarə edə bilərik. (ConfigMap-da bildiyim qədər bu mümkün deyil və hər bir mühitə/serverə/clusterə ayrılıqda qoşularaq ordaki ConfigMap-lari idarə etməliyik)
  • Sensitiv məlumatları saxlamaq üçün şifrləmə/deşifrləmə imkanı təqdim edir. (ConfigMap-da açıq data saxlamaq məsləhət görülmür və ConfigMap əvəzinə Secrets obyekti istifadə olunmalıdır).
  • Daha çox developer yönümlü həlldir. Yəni hər dəfə konfiqurasiya dəyişikliyi üçün DevOps və ya serverə qoşulma imkanı olan digər üzvlərin serverə (və ya idarəetmə panelinə) qoşulmasına ehtiyac olmur, developer özü birbaşa Git-dən konfiqurasiya faylını dəyişdirə bilir.
  • Konfiqurasiya faylları Git-də saxlanıldığı üçün, həm hamısı üçün ortaq saxlanc yeri olur həm də dəyişikliklərin tarixçəsi saxlanılır.

Spring Cloud Config — mənfi tərəfləri

  • Əgər ekosistemdə Javadan (Ümumiyyətlə Spring-dən) başqa dillər istifadə olunacaqsa Spring Cloud Config inteqrasiya zamanı çətinliklər yaradacaq. Düzdür Config Server konfiqurasiyaları REST Endpointlər vasitəsilə ötürə bilir ancaq razılaşaq ki, NodeJs-də yazdığımız applicationun konfiqurasiyasını idarə etmək üçün Config Server-ə sıfırdan client yazmaq çox vaxt alacaq.
  • Əsas problemli məsələ, yuxarıdaki şəkildən də göründüyü kimi Config Serverin tam əlçatan olması üçün əlavə Git serverə, Message Broker serverinə, Config Server applicationuna ehtiyac yaranır və bu komponentlərin daimiliyini təmin etməliyik. Nəzərə alsaq ki, mövcud sistemə əlavə olunan hər bir komponent yeni bir stress nöqtəsi, bug ehtimalı və əlavə monitorinqə ehtiyac yaradır bəzi hallarda Spring Cloud Config bu səbəblərə görə işimizə yaramaya bilər.
  • Yeni komponentlərin əlavə olunması da əlavə developmentə ehtiyac yaradır və bu resurs və vaxt baxımından bəzən uyğun olmaya bilər.

Kubernetes ConfigMap — müsbət tərəfləri

  • Əgər layihədə fərqli texnologiyalar və dillər istifadə olunacaqsa ConfigMap üçün bunun heç bir fərqi yoxdur, çünki bu daha ümumi həll yoludur və kənar konfiqurasiya istifadə edən istənilən application ilə inteqrasiya oluna bilər.
  • Daha çox DevOps yönümlü həlldir. Nəzərə alsaq ki, əksər şirkətlərdə developmentdən sonrakı prosesləri sistem mühəndisləri və ya DevOps üzvləri idarə edir, kənar serverdə yerləşən application konfiqurasiyalarına da onların düzəliş etməsi bir çox hallarda daha uyğun görünür.
  • Spring Cloud Config-dən fərqli olaraq konfiqurasiyaların dinamik dəyişikliyini applicationa ötürmək üçün əlavə komponentlərə ehtiyac yoxdur və çox kiçik tənzimləmə ilə ConfigMapdaki dəyşikliyi dinamik olaraq (hot-reload) Spring Boot application-a ötürmək mümkündür.
  • Əgər kubernetes clusterimiz hazırdırsa, konfiqurasiya kənarlaşdırılması addımları və görüləcək işlər Spring Cloud Config-ə nisbətən olduqca azdır çünki ConfigMap kubernetes üçün “native” bir həlldir.

Kubernetes ConfigMap — mənfi tərəfləri

  • Yuxarıda dediyimiz kimi daha çox DevOps yönümlü həlldir və hər konfiqurasiya dəyşikliyi üçün developerə kubernetes clusterinə access vermək bəzən mümkün olmaya bilər.
  • ConfigMap sadəcə Kubernetesə aid bir komponent olduğu üçün gələcəkdə kubernetes mühitindən digər texnologiyaya daşınsaq konfiqurasiyalarımız üçün də başqa bir həll yolu tapmalı olacağıq.
  • Spring Cloud Config kimi mərkəzləşdirilmiş konfiqurasiya idarəetməsi imkanı vermir və fərqli serverlərə ayrılıqda qoşulma lazım ola bilər. Bunun ümumiyyətlə yaxşı və ya lazımsız bir cəhət olduğu əslində fərqli müzakirə mövzusudur.

Yekun

Bizim layihədə uzun müddət Spring Cloud Config istifadə etməyimizə baxmayaraq daha sonradan Kubernetesin ConfigMap imkanı haqqında detallı araşdırmadan sonra ConfigMap-a keçid etdiyimizi deyə bilərəm. Çünki bizim situasiyada Config Serverə monitorinq və daimiliyə nəzarət bəzən problemlər yarada bilirdi, məsələn RabbitMQ və ya Config Server qısa müddət ərzində əlçatan olmadıqda yeni gələn deploylar gecikirdi və komponentlər artdıqca onlara nəzarət etmək də çətinləşirdi. Buna görə bizim situasiya üçün ConfigMap daha rahat və əlverişli oldu.

Ümid edirəm yuxarıdakı müqayisələr hər iki texnologiya haqqında sizdə də ümumi fikir formalaşdırar və nə vaxtsa seçim qarşısında qalsanız qərar vermək üçün kömək olar.

Xoş günlər! :)

--

--

No responses yet