K8s FullStack(Spring Boot — Nodejs)Deploy Hands-On

Hasan Kadir Demircan
5 min readMay 11, 2020

--

Merhaba github adresimde bulunan TodoApp uygulamamızı dockerize etmiştik. Buradan o yazıma ulaşabilirsiniz.

Şimdi ise TodoApp uygulamamızı localde geliştirmelerimizi/testlerimizi yaparken kullanmamızı sağlayan minikube ile dağıtacağız.

Aws üzerinde tek ec2 instance üzerine kurup uygulamamı dağıtacağım, aynı işlemleri sanal sunucuda digitalocean’da da yaparak takip edebilirsiniz. Fakat localde de rahatlıkla yapabilirsiniz :)

Local için buradaki adımları takip edebilirsiniz, tabii ki docker önceden kurulu olduğunu varsayıyorum :)

Aws EC2 Minikube Kurulumu

AMI: Ubuntu Server 18.04 LTS (HVM), SSD Volume Type

Type: t3.xlarge (4 CPU, 16GB Memory)

Tags:

  • Key: Name
  • Value: K8s

Security Group : SSH, 0.0.0.0/0 Custom & All Traffic Anywhere

Şeklinde ec2 instance oluşturuyoruz.

Windows makineden bağlanmak için MobaXterm baya kullanışlı.

Ec2-Minikube.md

Adımlarını yaptıktan sonra minikube hazır olacak,

Test için kubectl get all komutunu kullanabiliriz.

kubectl get all

Şimdi TodoApp uygulamamızı clone yapıyoruz.

MySQL Deploy

ilk önce backend uygulamamız için veritabanı ayarlarını yapmamız gerekmektedir

storage.yaml

Burada yapmamız gereken PersistentVolumeClaim(pvc) ve PersistentVolume(pv) oluşturmak.

PersistentVolume,

  • PersistentVolume(pv), cluster’daki bir depolama parçasıdır.
  • Kalıcı volume lifecycle, Pod lifecycle’dan bağımsızdır.
  • Pod’ların yeniden başlatılmasında, crash olmasında veri kaybını korur.

PersistentVolumeClaim,

  • PersistentVolume, PersistentVolumeClaim(pvc) tarafından kullanılır.
  • PersistentVolume depolaması istemek için bir PersistentVolueClaim oluştururuz.
  • PVC’ler belirli bir boyut ve erişim modları ister.
  • ReadWriteOnce, birimin tek bir node tarafından okuma yazma olarak mount edilebileceği anlamına gelir.
  • pvc ve pv bire bir eşleşmesi gerekir, bu yüzden pv 10 gb kullanıyorsa, pvc 3gb kullanıyorsa. pvc kapasitesi 10 gb’dır.)
  • storageClassName ile pvc-pv bağlantısı kurulur.

pvc ve pv hakkında daha fazla bilgi için K8s Persistence Volumes Nedir? inceleyip örneklere bakabilirsiniz.

Deployment,

deployment
  • Uygulamalarımızı bir cluster üzerinde dağıtabilmek için deployment yapılandırmasına ihtiyacımız vardır.
  • Uygulamalarımızın instance’larını nasıl oluşturacağımızı ve güncelleyeceğimizi bildirmektedir. (docker image seçimi vs..)

Service,

service
  • Deployment ile oluşturduğumuz pod’lara erişmek için bir ilke tanımlar.
  • Service tarafından hedeflenen pod’lar kümesi LabalSelector ile belirlenir.
  • Service bir dizi pod için trafiği yönlendirir ve uygulamayı etkilemeden k8'lerde ölmesine ve çoğalmasına izin verir.(service’ler pod’ları ortak bir port üzerinden expose eder.) Böylece eğer bir node/port çalışmıyorsa bu alanları dahili olarak yeniden oluşturuyorsa uygulama zarar görmez.
  • Unique IP adresleri bir service ile dış cluster’a maruz kalmaz. ServiceSpec içerisinde bir tür belirtilerek hizmetler farklı şekillerde verilebilir.(ClusterIP, NodePort, LoadBalancer, ExternalName)

Deployment ve Service hakkında daha fazla bilgi için K8s Deployment Nedir? ve K8s Service Nedir? inceleyip örneklere bakabilirsiniz.

Şimdi de MySQL Deployment ve Service işlemlerine bakalım,

mysql-stack.yaml

Deployment alanında,

  • metadata name alanı deployment’ımız için verdiğimiz isimdir. (pod ismi.)
  • label için verdiğimiz isim service ile dışarıya mysql’i açtığımızda pod ile matchleşmesi içindir.
  • spec container içerisinde gördüğünüz üzere mysql:5.7 image’i dockerHub’dan çekmektedir.
  • env içerisinde MySQL env’ları veriyoruz fakat burada en önemli şey şifre ve password’ı direkt içerisine vermiyoruz sadece value-key veriyoruz.(bunun için kubectl create secret komutu kullanacağız uygulamamızı ayağa kaldırırken.)
  • VolumeMounts ile verilerimiz pod crash olduğunda kaybolmaması için bir yer veriyoruz.

Service alanında ise,

  • metada name ile Service’in ismini belirliyoruz. Bu isimler şu yüzden önemli, spring boot uygulamamızdan service’e erişmek için bu ismi kullanacağız. (Örn: jdbc:mysql://todo-app-mysql:3306)
  • Selector ile deployment’a verdiğimiz ismi veriyoruz.
  • Type değerini ClusterIP yaptık çünkü veritabanı içeride kullanılacak bir uygulamadır dışarıdan başkalarının veritabanına erişmesini istemiyoruz.

Spring Boot(api) Deployment

api.yaml

Deployment alanında,

  • MySQL Deployment ve Service ile çok benzerlik göstermektedir.
  • Aslında 1 tanede olsa 1000 tane de configlerimiz çok benzerdir.
  • Burada fark spec içerisinde replicas gelmektedir. Bunu veritabanında da yapabilirdik.
  • Replicas ile eğer pod’lardan biri crash olursa bir diğeri ayakta olarak bağlantı kesilmesini önlemektedir. Aynı zamanda loadbalance ile de gelen trafiği yönetebilmek için kullanılmaktadır.
  • Selector matchLabels ve metadata labels isimleri ikisinde de api olduğunu göreceğiz çünkü replicaset’im ve pod’larım birbirlerini tanıyabilsin diye aynı isimlendirmeyi yapmaktayız.
  • env ‘da api uygulamasında bulunan application-product.properties içerisinde veritabanı bilgilerini parametre olarak aldığımı göreceksiniz. Bu parametleri burada veriyoruz.

Service alanında ise,

  • Selector ile pod’umuzu seçiyoruz.(Pod’umuzda bulunan metadata bilgileri ile aynı olmalı ki service pod’a erişebilsin.)
  • port bilgilerini giriyoruz.
  • api’mize sadece ui erişeceği için ClusterIP yapıyoruz.

Ui Deployment

ui.yaml

Deployment alanında,

  • pod ismini ui yapıyoruz.
  • Uygulama içerisinde product env çalışmasını istediğim için env olarak veriyorum.

Service alanında,

  • Selector ile pod ismini seçiyorum.
  • Type NodePort yapıyorum ve dışarıdan erişilmesi için bir nodePort veriyorum. NodePort ile ui’a dışarıdan erişilebilecektir.
  • Böylelikle dışarıdan 31000 portuna gelen istek içeride 8082 portuna yönlendirilecek.

Full Deploy and Test

Projemizi önceden oluşturduğumuz ec2 instance’a clone yapmıştık.

Şimdi k8s klasörü içerisine girelim.

  • Hatırlarsanız MySQL yaml dosyasını oluştururken bazı secretKeyRef’ler vermiştik.
  • Veritabanı kimlik bilgilerini saklamak için K8s secret kullanıyoruz.
  • Secret, K8s parolaları, token, ssh key gibi bilgileri saklayıp yönetmemizi sağlamaktadır.

Bu secretKey’leri manuel olarak oluşturuyoruz.

secret.txt

Bu komutları yazalım ve böylelikle oluşacak veritabanımız için url, username, password bilgilerini oluşturmuş oluyoruz.

Aşağıdaki komut ile k8s klasörü içerisinde bulunan tüm yaml dosyaları çalıştırılır.

kubectl apply -f .

Bu işlemi yaptıktan sonra ekran görüntüsü aşağıdaki gibi olacaktır,

kubectl apply -f .

Aşağıdaki komut ile tüm pod,service,replicaset, deployment’ları listeleyelim.

kubectl get all
kubectl get all

Gördüğümüz gibi tüm sistem ayağa kalktı.

api için replicaset 2 vermiştik ve bu yüzden 2 tane pod ayağa kalktı.

İlk önce ec2 publicip:31000 adresine girelim ve ui’ın açıldığını görelim.

publicip:31000

Şimdi de pod içerisinde log’lar nasıl izlenir ona bakalım,

kubectl logs -f <podName>

Bu işlemi yaptıktan sonra ui’dan CREATE ACCOUNT deyip bir kayıt oluşturalım.

Daha sonra logları görüntülediğimizde,

ui pod log

Burada gözümüze çarpan şey api-service:8080 olabilir bildiğimiz gibi api.yaml oluştururken service metadata name olarak vermiştik. Böylelikle ip’ler değişken olabileceği için service name kullanışlı olmaktadır.

Son olarak api’mizin log’una bakalım.

api pod log

ve uygulamamızı minikube üzerinde dağıtmış olduk.

Başka yazılarda görüşmek üzere :)

--

--

Hasan Kadir Demircan
Hasan Kadir Demircan

No responses yet