Hepsiburada.com Storefront Takımı Kubernetes Geçişi

Yusuf Can
hepsiburadatech
Published in
6 min readFeb 5, 2019

Sizlere bu yazımda Hepsiburada storefront takımının Docker swarm’dan Kubernetese nasıl geçiş yapıldığını anlatmaya çalışacağım. Daha öncesinde bu geçişi Search ekibi tamamlamıştı, takımın önünde güzel bir örnek vardı ve bu işi tamamlarken onların izinden gitmeye çalıştık. Efsane cuma sonrası bir road map belirleyerek bu geçiş sürecini atlattık. Sırasıyla tüm road mapi görebilirsiniz.

1) Kubernetes Cluster Kurulumu

Test, QA , Preprod ve Production clusterlarını kurmak için Kubespray kullandık. Kubespray, Ansible ile cloud ortamlarına veya kendi sunucularımıza Kubernetes clusterı kurmamızı sağlayan bir tool olarak düşünebiliriz. Bir adet lightweight test clusterı kurulumundan sonra bu cluster için pipeline hazırlayarak entegrasyona devam ettik. Kubespray konfigurasyonlarını gitte tutarsanız herhangi bir sebeple clusterın gitmesi durumunda aynı konfigurasyonla tekrar cluster kurabilirsiniz.

2) Kubernetes için Pipeline Hazırlanması

Daha öncesinde CI-CD toolu olarak goCD kullanılıyordu. Benim şahsi fikrim en bilinen ve en fazla kullanılan CI-CD toolunu kullanmadan başka bir tool kullanılmamalısı yönünde.
Bunun için Jenkins önerisinde bulundum ve takım olarak Jenkinsi denemeye karar verdik. Aralarındaki en önemli 2 fark Jenkinsin communitiysinin ve plugin desteğinin çok daha fazla olması. Pluginler yapılması gereken işleri çok rahatlatıyor ve ekstradan efor harcamanın önüne geçiyor.

Geçişini yapacağımız uygulamanın Dockerfile’ında biraz değişiklikler yapıp declaretive pipeline yöntemi ile uygulamaya Jenkinsfile ekledik. Ortaya çıkan image’ları var olan nexusa pushladık.
Uygulamanın nasıl build edilip pushlandığını aşağıdaki kod blogundan görebilirsiniz. (branchName parametresinin kullanılma amacı istenilen branch’ın deploy edilip test edilebilmesi içindir. )

stage(‘Building Docker image’) { steps{ sh “docker build -t ${dockerImage}:${branchName}-${env.BUILD_NUMBER} -t ${dockerImage}:latest .” } } stage(‘Push Docker Image’) { steps { script {

withDockerRegistry([ credentialsId: “${dockerRepoCredentialId}”, url: “https://${dockerRepository}” ]) {

sh “docker push ${dockerImage}:${branchName}-${env.BUILD_NUMBER}” sh “docker push ${dockerImage}:latest” } }

}

3) Kubernetese Deployment Yapılması

Uygulamayı Jenkins’te build edip ortaya çıkan image’ı nexusa pushladıktan bir sonraki adım cluster’a deployment yapılması. Kubernetese deploymentı Jenkins üzerinden Ansible aracılığı ile deploy etmeye karar verdik. Bunun sebebi jinja templateler ile tüm yml’ları parametrik hale getirebilmektir. Bunun en önemli faydası sürekli kubernetes yml’ları ile uğraşmak yerine Jenkinsfile’daki parametreleri değiştirirek ekstradan yml dosylarıyla uğraşmayı en aza indirmek.

Deployment için Ansible’ın k8s_raw modulünü kullandık.

https://docs.ansible.com/ansible/2.5/modules/k8s_raw_module.html

stage(‘Deploy to Test Kubernetes Environment’) { steps { script { sh “”” sudo ansible-playbook kubernetes/test/deploymentMain.yml –extra-vars “version=$BUILD_NUMBER branch=$branchName action=present type=deployment ReplicaCount=$podNumber” “”” } }

}

Yukarıdaki Jenkinsfile bölümünde deployment için çalıştırılması gereken scripti görebilirsiniz.

Uygulamayı clustera deploy ettik. Uygulamanın dışarıdan istek alabilmesi için Kubernetesin calico network pluginini kullanarak nodePort ile uygulamanın dışarıya açılmasını sağladık. Artık hangi load balancer sistemi kullanılacaksa (NetScaler,Nginx vs) Ip ve NodePort yardımı ile uygulamanın istek almasını sağlayabiliriz.

4) Blue-Green Production Deploymentları

Daha öncesinde production ortamları blue ve green olarak ikiye bölünmüş durumdaydı. Bunun avantajları olmakla birlikte artık container cluster yapısı ile yavaş yavaş anlamını yitirdiğini düşünüyorum. Bunun bana göre en önemli sebeplerinden biri var olan sunucuları bölmek ve productiona deployment yapılacağı sırada yayından alınan grubun kullanılmaması. Blue-Green deploymentlar sayesinde production ortamında testlet yapılıyor en hatasız şekilde geçişler yapılabiliniyor fakat en yoğun günlerde productiona deployment yapılacağı zaman acaba yayından alırsak yükü kaldırabilir mi sorusuyla karşı karşıya kalıyoruz. Biz bu durumu Kubernetes ortamında istediğimiz kadar versiyonu productiona gönderip uygulamanın service labellarını değiştirerek yapmaya çalıştık. Artık blue greeen deployment yok istediğimiz versiyonları productiona deploy edip istediğimiz versiyonlar arasında geçiş yapabiliyoruz. Aşağıdaki ekran görüntüsüyle production deploymentını özetlemeye çalıştım.

Production’a ilk Deployment

Yukarıda A uygulaması ilk defa clustera deploy edildi ve nodePort ile uygulamaya istek gelmesi sağlandı.

Aşağıdaki görselde A uygulamasının 2. versiyonu deploy edildi fakat uygulamaya bind olmuş herhangi bir servis olmadığından dolayı uygulama devre dışı. Hatta bir adet fake service yaratarak deploy edilen uygulamanın yeni versiyonunu test edebiliriz.

Production’a A uygulamasının yeni versiyonu deploy edildi.

A uygulamasının servisinin labelı değiştirilerek yeni versiyona istek gelmesi sağlandı.

A uygulamasının 2. versiyonu deploy edildi ve uygulamanın service label’ı değiştirildi

Yukarıda gösterdiğim örneklerle istediğimiz kadar versiyon deploy edip test edebiliriz. Bu label değiştirme özelliği ile birlikte productiona deploymentlar daha az korkutucu oluyor. Herhangi bir hata durumunda istediğimiz versiyona geri dönebiliyoruz.

Bu yukarıdaki durum Kubernetesin en güzel özelliklerinden olan rollingupdate tamamen aykırı olmakla birlikte deploymentları daha az hatalı yapılmasını sağlıyor.

5) Deploy Edilen Uygulamaların Logları

Uygulama loglarını takip edebilmek için daha öncesinde ELK stack kullanılıyordu. Zaten hali hazırda var olan sistemi değiştirmek yerine Kubernetese deploy edilen uygulamanın loglarını ELK stack ile monitor etmeye devam ettik.

Uygulama loglarını görebilmemiz için kube-gelfi Kubernetes clusterına deploy edip logları görmeye başladık. (Eğer kube-gelf confiğinde sadece uygulama loglarını çekicek şekilde düzeltme yapmazsanız Kubernetes clusterında var olan tüm logları göndereceğiniz için ELK’yı indirebilirsiniz.)

6) Kubernetes Clustser Monitoring

Kubernetes clusterını monitoring için clustera promethues deploy edip grafanada görüntüledik. Monitoringi daha rahat yapabilmemiz için ekstradan node-exporter deploymentıda gerçekleştirdik. Ayrıca alert tanımlamak için prometheus alert manager deploymentı yaptık. Düşen alertleri oluşturduğumuz slack kanalına gönderdik.

Prometheus ve Alert Manager : https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/prometheus

Prometheus Node Exporter :

https://github.com/prometheus/node_exporter

7) Application Monitoring

Kubernetes clusterına deploy ettiğimiz uygulamaları monitoring için uygulamalara App Metrics ekleyerek gerçekleştirdik. App Metrics sayesinde uygulamaların response time’larını , dakikada aldığı istek sayısını, saniyede aldığı istek sayısını, uygulamalada oluşan hataları monitor edebiliyoruz.

App Metrics : https://www.app-metrics.io/web-monitoring/aspnet-core/

8) Kubernetes Horizontal Pod Autoscaler

Tüm işlemlerden sonra geriye uygulamara autoscale eklemek kalıyor. Autoscale eklememizin amacı ani yük artışlarında uygulamanın pod sayısının arttırarak yükü olabildiğince çok dağıtmak. Bunun için Kubernetes Clusterına custom metrics api server kurulumu gerçekleştirdik ve prometheustan çekebildiğimiz tüm sorgularla uygulamamızı scale edebilcek duruma geldik.

Şuanki durumda sistemin yük almadığı durumlarda pod sayısı 5’e kadar inerken yük altında 50 poda kadar çıkıp yükü rahat bir şekilde kaldırabiliyoruz.

Custom-Metrics-Apiserver:

https://github.com/kubernetes-incubator/custom-metrics-apiserver

9) Ansible-Awx

Ansible Awx ile var olan sunucular üzerinde ansible scriptleriyle joblar çalıştırıyoruz.

Bu jobları sıralarsak :

  • Jenkins workspace silme
  • Jenkin üzerindeki Docker Image ve Docker Containerları silme
  • Jenkins üzerinde çalışan otomasyon testleri sonucunda oluşan screenshotları silme
  • Kubernetes üzerinde aynı anda Test,Qa,Preprod ve Production ortamlarına deployment yapma.(Application deploymetı değil örn: Nginx)

Aşağıdaki ekran görüntüsünde Kubernetes geçişi ile storefront takımının devops diagram’ını görebilirsiniz.

Şuana kadar geçişi yapılan uygulamalar ile birlikte dakikada 100klara ulaşan transactionlarla uygulamalarımızı Kubernetes Clusterında stabil şekilde host edebiliyoruz.

Özetle Storefront takımının kubernetese nasıl geçiş yaptığını anlatmaya çalıştım. Daha öncesinde geçişi tamamlamış olan Search ekibine yardımlarından dolayı teşekkür ederim.

Okuduğunuz için teşekkürler.

Yusuf Can

--

--