Google Kubernetes Engine'de Kubernetes'e bir Spring Boot Java uygulaması dağıtma

1. Başlamadan önce

Kubernetes; dizüstü bilgisayarlardan yüksek kullanılabilirlik sağlayan çok düğümlü kümelere, herkese açık bulutlardan şirket içi dağıtımlara ve sanal makine (VM) örneklerinden bare metal'e kadar birçok farklı ortamda çalışabilen açık kaynaklı bir projedir.

Bu codelab'de, basit bir Spring Boot Java web uygulamasını GKE'deki Kubernetes'e dağıtacak ve web uygulamanızı Kubernetes'te çoğaltılmış bir uygulama olarak çalıştırmayı hedefleyeceksiniz. Makinenizde geliştirdiğiniz kodu alıp Docker container görüntüsüne dönüştürecek ve görüntüyü GKE'de çalıştıracaksınız.

Temel altyapıyı ayarlamak yerine Kubernetes deneyimine daha fazla odaklanmanızı sağlamak için Google Cloud'daki tümüyle yönetilen bir Kubernetes hizmeti olan GKE'yi kullanacaksınız.

Kubernetes'i yerel makinenizde (ör. geliştirme dizüstü bilgisayarı) çalıştırmak istiyorsanız geliştirme ve test amaçlı tek düğümlü bir Kubernetes kümesinin basit kurulumunu sunan Minikube'u inceleyin. İsterseniz Minikube'u kullanarak codelab'i inceleyebilirsiniz.

Codelab'de, Spring Boot ile Uygulama Oluşturma hakkındaki kılavuzda yer alan örnek kod kullanılacaktır.

Ön koşullar

  • Java programlama dili ve araçları hakkında bilgi sahibi olma
  • Vim, Emacs ve nano gibi standart Linux metin düzenleyicileri hakkında bilgi sahibi olmanız gerekir.

Yapacaklarınız

  • Basit bir Java uygulamasını Docker container'ı olarak paketleyin.
  • GKE'de Kubernetes kümenizi oluşturun.
  • Java uygulamanızı GKE'deki Kubernetes'e dağıtın.
  • Hizmetinizi ölçeği artırın ve yükseltme işlemini kullanıma sunun.
  • Web tabanlı bir Kubernetes kullanıcı arayüzü olan kontrol paneline erişin.

Gerekenler

2. Kurulum ve şartlar

Yönlendirmesiz ortam kurulumu

  1. Google Cloud Console'da oturum açın ve yeni bir proje oluşturun veya mevcut bir projeyi yeniden kullanın. Gmail veya Google Workspace hesabınız yoksa hesap oluşturmanız gerekir.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Proje adı, bu projenin katılımcıları için görünen addır. Google API'leri tarafından kullanılmayan bir karakter dizesidir. Bu bilgiyi istediğiniz zaman güncelleyebilirsiniz.
  • Proje kimliği, tüm Google Cloud projelerinde benzersizdir ve sabittir (ayarlandıktan sonra değiştirilemez). Cloud Console, benzersiz bir dizeyi otomatik olarak oluşturur. Genellikle bu dizenin ne olduğuyla ilgilenmezsiniz. Çoğu codelab'de proje kimliğinize (genellikle PROJECT_ID olarak tanımlanır) başvurmanız gerekir. Oluşturulan kimliği beğenmezseniz başka bir rastgele kimlik oluşturabilirsiniz. Dilerseniz kendi adınızı deneyerek kullanılabilir olup olmadığını kontrol edebilirsiniz. Bu adım tamamlandıktan sonra değiştirilemez ve proje süresince geçerli kalır.
  • Bazı API'lerin kullandığı üçüncü bir değer olan Proje Numarası da vardır. Bu üç değer hakkında daha fazla bilgiyi belgelerde bulabilirsiniz.
  1. Ardından, Cloud kaynaklarını/API'lerini kullanmak için Cloud Console'da faturalandırmayı etkinleştirmeniz gerekir. Bu codelab'i tamamlamak neredeyse hiç maliyetli değildir. Bu eğitimin ötesinde faturalandırılmayı önlemek için kaynakları kapatmak üzere oluşturduğunuz kaynakları veya projeyi silebilirsiniz. Yeni Google Cloud kullanıcıları 300 ABD doları değerinde ücretsiz deneme programından yararlanabilir.

Cloud Shell'i etkinleştirme

  1. Cloud Console'da Cloud Shell'i etkinleştir 'i 853e55310c205094.png tıklayın.

55efc1aaa7a4d3ad.png

Cloud Shell'i ilk kez başlatıyorsanız ne olduğunu açıklayan bir ara ekran gösterilir. Ara ekran gösterildiyse Devam'ı tıklayın.

9c92662c6a846a5c.png

Cloud Shell'in temel hazırlığı ve bağlanması yalnızca birkaç dakikanızı alır.

9f0e51b578fecce5.png

Bu sanal makineye, ihtiyaç duyacağınız tüm geliştirme araçları yüklenmiştir. 5 GB boyutunda kalıcı bir ana dizin bulunur ve Google Cloud'da çalışır. Bu sayede ağ performansı ve kimlik doğrulama önemli ölçüde güçlenir. Bu codelab'deki çalışmalarınızın neredeyse tamamını tarayıcıyla yapabilirsiniz.

Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin, proje kimliğinize ayarlandığını görürsünüz.

  1. Kimliğinizin doğrulandığını onaylamak için Cloud Shell'de şu komutu çalıştırın:
gcloud auth list

Komut çıkışı

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. gcloud komutunun projeniz hakkında bilgi sahibi olduğunu onaylamak için Cloud Shell'de aşağıdaki komutu çalıştırın:
gcloud config list project

Komut çıkışı

[core]
project = <PROJECT_ID>

Değilse şu komutla ayarlayabilirsiniz:

gcloud config set project <PROJECT_ID>

Komut çıkışı

Updated property [core/project].

3. Kaynak kodu alma

Cloud Shell başlatıldıktan sonra, ana dizindeki örnek kaynak kodu klonlamak için komut satırını kullanabilirsiniz.

$ git clone https://github.com/spring-guides/gs-spring-boot.git
$ cd gs-spring-boot/complete

4. Uygulamayı yerel olarak çalıştırma

  1. JAVA_HOME'un doğru sürüme ayarlandığından emin olun:
$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
  1. Spring Boot uygulamasını Spring Boot eklentisiyle normal şekilde başlatabilirsiniz.
$ ./mvnw -DskipTests spring-boot:run
  1. Uygulama başladıktan sonra Cloud Shell araç çubuğunda Web Önizlemesi'ni 1a94d5bd10bfc072.png tıklayın ve 8080 bağlantı noktasında önizle'yi seçin.

6252b94905f3f7bd.png

Tarayıcınızda bir sekme açılır ve yeni başlattığınız sunucuya bağlanır.

9b6c29059957bd0.jpeg

5. Java uygulamasını Docker container'ı olarak paketleme

Ardından, uygulamanızı Kubernetes'te çalışmaya hazırlamanız gerekir. İlk adım, kapsayıcıyı ve içeriğini tanımlamaktır.

  1. Uygulama için JAR dağıtılabilir dosyasını oluşturun.
$ ./mvnw -DskipTests package
  1. Oluşturacağınız container görüntüsünü depolamak için Artifact Registry API'yi etkinleştirin.
$ gcloud services enable artifactregistry.googleapis.com
  1. Henüz yoksa yeni bir Docker deposu oluşturun. Herhangi bir görüntüyü aktarmadan önce depo oluşturmanız gerekir:
$ gcloud artifacts repositories create codelabrepo     --repository-format=docker --location=us-central1 
  1. Resminiz şu biçimde olmalıdır:

{LOCATION}-docker.pkg.dev/{PROJECT-ID}/{REPOSITORY}/{IMAGE-NAME}

Örneğin, us-central1 konumunda codelabrepo adlı bir depo oluşturduysanız ve resminize hello-java:v1 adını vermek istiyorsanız resim şu şekilde olur:

us-central1-docker.pkg.dev/{PROJECT-ID}/codelabrepo/hello-java:v1

  1. Container görüntüsü oluşturmak ve Artifact Registry'ye aktarmak için Jib'i kullanın.
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format="value(core.project)"`

$ ./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/codelabrepo/hello-java:v1
  1. Cloud Console'da Artifacts Registry Görüntüleri sayfasına giderek kapsayıcı görüntüsünü konsolda listelenmiş olarak görebilirsiniz. Artık Kubernetes'in erişebileceği ve düzenleyebileceği proje genelinde bir Docker görüntünüz var. Bunu birkaç dakika içinde göreceksiniz.
  2. (İsteğe bağlı) Tamamlandıktan sonra (her şeyin indirilmesi ve çıkarılması biraz zaman alır) görüntüyü aşağıdaki komutla test edin. Bu komut, yeni oluşturduğunuz container görüntüsünden 8080 numaralı bağlantı noktasında bir Docker container'ını arka plan programı olarak çalıştırır. İzin sorunlarıyla karşılaşırsanız önce gcloud auth configure-docker us-central1-docker.pkg.dev komutunu çalıştırın:
$ docker run -ti --rm -p 8080:8080 \
  us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. Yine Cloud Shell'in web önizleme özelliğinden yararlanın.

6252b94905f3f7bd.png

  1. Varsayılan sayfayı yeni bir sekmede görmeniz gerekir. Uygulamanın yerel olarak bir Docker kapsayıcısında çalıştığını doğruladıktan sonra Control+C tuşuna basarak çalışan kapsayıcıyı durdurabilirsiniz.

6. Kümenizi oluşturma

GKE kümenizi oluşturmaya hazırsınız. Küme, Google tarafından yönetilen bir Kubernetes API sunucusundan ve bir dizi çalışan düğümden oluşur. Çalışma düğümleri, Compute Engine sanal makineleridir.

  1. Öncelikle, ilgili API özelliklerinin etkinleştirildiğinden emin olun.
$ gcloud services enable compute.googleapis.com container.googleapis.com
  1. İki n1-standard-1 düğümlü bir küme oluşturun (bu işlemin tamamlanması birkaç dakika sürebilir).
$ gcloud container clusters create hello-java-cluster \
  --num-nodes 2 \
  --machine-type n1-standard-1 \
  --zone us-central1-c

Sonunda, kümenin oluşturulduğunu görürsünüz.

Creating cluster hello-java-cluster...done.
Created [https://container.googleapis.com/v1/projects/...].
kubeconfig entry generated for hello-dotnet-cluster.
NAME                  ZONE            MASTER_VERSION  
hello-java-cluster  us-central1-c  ...

Artık GKE tarafından desteklenen, tam işlevli bir Kubernetes kümeniz olmalıdır.

758c7fca14f70623.png

Şimdi container mimarisine alınmış uygulamanızı Kubernetes kümesine dağıtma zamanı. Bundan sonra kubectl komut satırını (Cloud Shell ortamınızda zaten ayarlanmış) kullanacaksınız. Codelab'in geri kalanında Kubernetes istemci ve sunucu sürümünün 1.2 veya daha yeni olması gerekir. kubectl version, komutun mevcut sürümünü gösterir.

7. Uygulamanızı Kubernetes'e dağıtma

  1. Kubernetes dağıtımı, oluşturduğunuz kapsayıcı görüntüsünü kullanarak uygulamanızın birden fazla örneğini oluşturabilir, yönetebilir ve ölçeklendirebilir. kubectl run komutunu kullanarak uygulamanızın bir örneğini Kubernetes'e dağıtın.
$ kubectl create deployment hello-java --image=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. Oluşturduğunuz dağıtımı görüntülemek için aşağıdaki komutu çalıştırmanız yeterlidir:
$ kubectl get deployments

NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   1         1         1            1           37s
  1. Dağıtım tarafından oluşturulan uygulama örneklerini görüntülemek için aşağıdaki komutu çalıştırın:
$ kubectl get pods

NAME                         READY     STATUS    RESTARTS   AGE
hello-java-714049816-ztzrb   1/1       Running   0          57s

Bu noktada, kapsayıcınız Kubernetes'in kontrolü altında çalışıyor olmalıdır ancak yine de dış dünyaya erişilebilir hale getirmeniz gerekir.

8. Harici trafiğe izin ver

Varsayılan olarak, kapsüle yalnızca küme içindeki dahili IP'si üzerinden erişilebilir. hello-java kapsayıcısının Kubernetes sanal ağının dışından erişilebilir olması için kapsülü Kubernetes hizmeti olarak kullanıma sunmanız gerekir.

  1. Cloud Shell'de, Kubernetes LoadBalancer hizmeti oluşturarak kapsülü herkese açık internete sunabilirsiniz.
$ kubectl create service loadbalancer hello-java --tcp=8080:8080

Pod'u değil, dağıtımı doğrudan kullanıma sunduğunuzu unutmayın. Bu işlem, ortaya çıkan hizmetin trafiği dağıtım tarafından yönetilen tüm kapsüller arasında yük dengelemesine neden olur (bu durumda yalnızca bir kapsül vardır ancak daha sonra daha fazla kopya ekleyeceksiniz).

Kubernetes ana makinesi, hizmetin Google Cloud dışından tamamen erişilebilir olması için yük dengeleyiciyi ve ilgili Compute Engine yönlendirme kurallarını, hedef havuzlarını ve güvenlik duvarı kurallarını oluşturur.

  1. Hizmetin herkese açık olarak erişilebilen IP adresini bulmak için kubectl komutunu kullanarak tüm küme hizmetlerini listelemeniz yeterlidir.
$ kubectl get services

NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
hello-java   10.3.253.62    aaa.bbb.ccc.ddd  8080/TCP    1m
kubernetes   10.3.240.1     <none>           443/TCP    5m
  1. Artık tarayıcınızı http://<EXTERNAL_IP>:8080 adresine yönlendirerek hizmete ulaşabilirsiniz.

9. Hizmetinizi ölçeklendirme

Kubernetes'in sunduğu güçlü özelliklerden biri, uygulamanızı ölçeklendirmenin ne kadar kolay olduğudur. Örneğin, uygulamanız için aniden daha fazla kapasiteye ihtiyacınız olduğunu varsayalım. Bu durumda, uygulamanızın örnekleri için yeni bir kopya sayısı yönetmesini çoğaltma denetleyicisine söylemeniz yeterlidir.

$ kubectl scale deployment hello-java --replicas=3

deployment "hello-java" scaled

$ kubectl get deployment
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   3         3         3            3           22m

Bildirimsel yaklaşıma dikkat edin. Yeni örnekleri başlatmak veya durdurmak yerine, her zaman kaç örneğin çalışması gerektiğini belirtirsiniz. Kubernetes uzlaştırma döngüleri, gerçekliğin isteğinizle eşleştiğinden emin olur ve gerekirse işlem yapar.

10. Hizmetinizde yükseltme yayınlama

Üretime dağıttığınız uygulamada bir noktada hata düzeltmeleri veya ek özellikler gerekebilir. Kubernetes, kullanıcılarınızı etkilemeden yeni bir sürümü üretime dağıtmanıza yardımcı olabilir.

  1. Cloud Shell menüsünde Open editor 'ı (Düzenleyiciyi aç) 2109d75686c889a.png tıklayarak kod düzenleyiciyi açın.
  2. src/main/java/com/example/springboot/HelloController.java simgesine gidin ve yanıtın değerini güncelleyin.
package com.example.springboot;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Google Kubernetes Engine!";
    }
}
  1. Container görüntüsünün yeni bir sürümünü oluşturmak ve aktarmak için Jib'i kullanın. Önbelleğe almadan tam olarak yararlandığınız için güncellenen görüntüyü oluşturma ve gönderme işlemi çok daha hızlı olmalıdır.
$ ./mvnw -DskipTests package com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

Kubernetes'in replikasyon denetleyicinizi uygulamanın yeni sürümüne sorunsuz bir şekilde güncellemesine hazırsınız.

  1. Çalışan kapsayıcınızın resim etiketini değiştirmek için mevcut hello-java dağıtımını düzenlemeniz ve resmi us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v1

Bitiş: us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v2

  1. kubectl set image komutunu kullanarak Kubernetes'ten, uygulamanızın yeni sürümünü periyodik güncellemelerle kümenin tamamına tek seferde bir örnek olacak şekilde dağıtmasını isteyebilirsiniz.
$ kubectl set image deployment/hello-java hello-java=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

deployment "hello-java" image updated
  1. Yeni yanıtı döndürdüğünü görmek için http://EXTERNAL_IP:8080 simgesini tekrar kontrol edin.

11. Geri çek

Hata! Uygulamanın yeni sürümünde hata mı yaptınız? Belki de yeni sürümde bir hata vardır ve hızlıca geri almanız gerekir. Kubernetes ile önceki duruma kolayca geri dönebilirsiniz. Aşağıdaki komutu çalıştırarak uygulamayı geri çekin:

$ kubectl rollout undo deployment/hello-java

http://EXTERNAL_IP:8080 simgesini tekrar işaretlediğinizde eski yanıtı görürsünüz.

12. Tebrikler

GKE'de Kubernetes'e yeni bir Java tabanlı web uygulaması oluşturup dağıtmayı öğrendiniz.

Temizleme

$ gcloud container clusters delete hello-java-cluster --zone us-central1-c

$ gcloud container images delete us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1 us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

Daha fazla bilgi