1. Genel Bakış
Jenkins, mevcut en popüler sürekli entegrasyon çözümlerinden biridir. Yazılım geliştirme sürecinin insan kaynaklı olmayan temel kısımlarını otomatikleştirmek için kullanılır. Jenkins'i Google Cloud'da Kubernetes'e dağıtıp GKE eklentisini kullanarak, gerektiğinde derleme yürütücülerini hızlı ve otomatik olarak ölçeklendirebiliyoruz. Cloud Storage ile birlikte, minimum çabayla bir uygulama oluşturup test edebiliyoruz.
Yapacaklarınız
- Jenkins'i Kubernetes kümesine dağıtma
- Jenkins'in yürütücü düğümleri olarak kapsüller oluşturup yok etmesini sağlamak için Jenkins GKE eklentisini dağıtın ve yapılandırın.
- Örnek SpringBoot uygulaması oluşturma ve test etme
- Google Container Registry'de kapsayıcı oluşturma ve yayınlama
- Örnek uygulamayı bir hazırlama ve üretim GKE ortamına dağıtma
Gerekenler
- Faturalandırmanın ayarlandığı bir Google Cloud projesi. Hesabınız yoksa hesap oluşturmanız gerekir.
2. Hazırlanma
Bu codelab, yerel kurulum veya yapılandırma olmadan tamamen Google Cloud Platform'da çalıştırılabilir.
Cloud Shell
Bu codelab boyunca, Cloud Shell üzerinden komut satırını kullanarak farklı bulut kaynaklarını ve hizmetlerini sağlayıp yöneteceğiz.
API'leri etkinleştirme
Projemizde etkinleştirmemiz gereken API'ler şunlardır:
- Compute Engine API: Sanal makineler oluşturur ve çalıştırır.
- Kubernetes Engine API: Container tabanlı uygulamalar oluşturur ve yönetir.
- Cloud Build API: Google Cloud'un sürekli entegrasyon ve sürekli teslim platformu
- Service Management API: Hizmet üreticilerinin Google Cloud Platform'da hizmet yayınlamasına olanak tanır.
- Cloud Resource Manager API: Google Cloud kaynak kapsayıcılarının meta verilerini oluşturur, okur ve günceller.
Aşağıdaki gcloud komutuyla gerekli API'leri etkinleştirin:
gcloud services enable compute.googleapis.com \
container.googleapis.com \
cloudbuild.googleapis.com \
servicemanagement.googleapis.com \
cloudresourcemanager.googleapis.com \
--project ${GOOGLE_CLOUD_PROJECT}
GCS paketi oluşturma
Test çalışmamızı yüklemek için bir GCS paketi gerekir. Benzersizliği sağlamak için adında proje kimliğimizin bulunduğu bir paket oluşturalım:
gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket/
3. Kubernetes kümeleri oluşturma
Küme oluşturma
Ardından, çalışan düğümleri olarak gönderilecek pod'lar da dahil olmak üzere Jenkins sistemimizi barındıracak bir GKE kümesi oluşturacağız. --scopes işaretiyle belirtilen ek kapsam, Jenkins'in Cloud Source Repositories ve Container Registry'ye erişmesine olanak tanır. Cloud Console'da aşağıdakileri çalıştırın:
gcloud container clusters create jenkins-cd \ --machine-type n1-standard-2 --num-nodes 1 \ --zone us-east1-d \ --scopes "https://www.googleapis.com/auth/source.read_write,cloud-platform" \ --cluster-version latest
Ayrıca örnek uygulamamızın hazırlık ve üretim derlemelerini barındırmak için 2 küme dağıtalım:
gcloud container clusters create staging \ --machine-type n1-standard-2 --num-nodes 1 \ --zone us-east1-d \ --cluster-version latest
gcloud container clusters create prod \ --machine-type n1-standard-2 --num-nodes 2 \ --zone us-east1-d \ --cluster-version latest
Doğrula
Kümeler oluşturulduktan sonra gcloud container clusters list ile çalıştıklarını doğrulayabiliriz.
Çıkışın STATUS sütununda RUNNING olmalıdır:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS jenkins-cd us-east1-d 1.15.9-gke.9 34.74.77.124 n1-standard-2 1.15.9-gke.9 2 RUNNING prod us-east1-d 1.15.9-gke.9 35.229.98.12 n1-standard-2 1.15.9-gke.9 2 RUNNING staging us-east1-d 1.15.9-gke.9 34.73.92.228 n1-standard-2 1.15.9-gke.9 2 RUNNING
4. Helm ile Jenkins'i dağıtma
Helm'i yükleme
Kümemize Jenkins'i yüklemek için Kubernetes'e yönelik bir uygulama paketi yöneticisi olan Helm'i kullanacağız. Başlamak için Jenkins'i dağıtmak üzere kullanacağımız Kubernetes manifestlerini içeren projeyi indirin:
git clone https://github.com/GoogleCloudPlatform/continuous-deployment-on-kubernetes.git ~/continuous-deployment-on-kubernetes
Mevcut çalışma dizininizi proje dizini olarak değiştirin:
cd ~/continuous-deployment-on-kubernetes/
Kendinize küme yöneticisi rolü izinleri vermek için bir küme rolü bağlaması oluşturun:
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
Kimlik bilgilerini alarak Jenkins kümenize bağlanın:
gcloud container clusters get-credentials jenkins-cd --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
Ayrıca Helm ikili dosyasını Cloud Console'unuza indirin:
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.1-linux-amd64.tar.gz
Dosyanın sıkıştırmasını açın ve içerdiği helm dosyasını mevcut çalışma dizininize kopyalayın:
tar zxfv helm-v2.14.1-linux-amd64.tar.gz && \ cp linux-amd64/helm .
Tiller, Kubernetes kümesinde çalışan Helm'in sunucu tarafıdır. tiller adlı bir hizmet hesabı oluşturalım:
kubectl create serviceaccount tiller \ --namespace kube-system
Ayrıca, değişiklik yapabilmesi için cluster-admin küme rolüne bağlayın:
kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:tiller
Şimdi Helm'i başlatabilir ve depoyu güncelleyebiliriz:
./helm init --service-account=tiller && \ ./helm repo update
Doğrula
Helm'in ./helm version ile kullanıma hazır olduğunu onaylayın. Bu işlem, istemcinin ve sunucunun sürüm numaralarını döndürmelidir:
Client: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Jenkins'i yükleme
Helm, kümemize yüklendiğine göre Jenkins'i yüklemeye hazırız:
./helm install stable/jenkins -n cd \ -f jenkins/values.yaml \ --version 1.2.2 --wait
Doğrula
Kapsülleri kontrol edelim:
kubectl get pods
Çıkışta, RUNNING durumunda olan Jenkins pod'umuz gösterilmelidir:
NAME READY STATUS RESTARTS AGE cd-jenkins-7c786475dd-vbhg4 1/1 Running 0 1m
Jenkins hizmetinin düzgün şekilde oluşturulduğunu onaylayın:
kubectl get svc
Çıkış şu şekilde görünmelidir:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cd-jenkins ClusterIP 10.35.241.170 <none> 8080/TCP 2m27s cd-jenkins-agent ClusterIP 10.35.250.57 <none> 50000/TCP 2m27s kubernetes ClusterIP 10.35.240.1 <none> 443/TCP 75m
Jenkins yüklemesinde, oluşturucu aracıları oluşturmak için Kubernetes eklentisi kullanılacaktır. Bu işlemler, gerektiğinde Jenkins ana sunucusu tarafından otomatik olarak başlatılır. İşleri bittiğinde otomatik olarak sonlandırılırlar ve kaynakları, kümenin kaynak havuzuna geri eklenir.
Jenkins'e bağlanma
Jenkins, kümemizde çalışıyor ancak kullanıcı arayüzüne erişmek için Cloud Shell'den bağlantı noktası yönlendirme ayarlayalım:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/component=jenkins-master" -l "app.kubernetes.io/instance=cd" -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8080:8080 >> /dev/null &
Yükleme sırasında bir yönetici şifresi oluşturuldu. Şimdi de geri alalım:
printf $(kubectl get secret cd-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
Cloud Shell'in üst kısmında Web Önizlemesi simgesini
tıklayın ve "8080 numaralı bağlantı noktasında önizle"yi seçin.

Kullanıcı adı için admin, şifre için de önceki adımda döndürülen şifreyi girebileceğimiz bir Jenkins oturum açma ekranı görmemiz gerekir:

Oturum aç'ı tıkladığımızda Jenkins'in ana sayfasına yönlendirilmeliyiz.

5. GKE eklentisini yükleyip yapılandırma
Google Kubernetes Engine eklentisi, Jenkins'te oluşturulan dağıtımları GKE'de çalışan Kubernetes kümelerimizde yayınlamamıza olanak tanır. Projenizde IAM izinleriyle ilgili yapılması gereken bazı yapılandırmalar var. Bu yapılandırmayı Terraform kullanarak dağıtacağız.
İlk olarak GKE eklenti projesini indirin:
git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin
Otomatik IAM İzinleri Yapılandırması
Mevcut çalışma dizininizi, daha önce klonladığımız GKE projesinin rbac dizini olarak değiştirin:
cd ~/google-kubernetes-engine-plugin/docs/rbac/
gcp-sa-setup.tf, bu rolü vermek için bir GCP hizmet hesabının yanı sıra sınırlı izinlere sahip özel bir GCP IAM rolü oluşturacak bir Terraform yapılandırma dosyasıdır. Dosyada proje, bölge ve hizmet hesabı adı değişkenleri için değerler gerekir. Bu değerleri, önce aşağıdaki ortam değişkenlerini tanımlayarak sağlarız:
export TF_VAR_project=${GOOGLE_CLOUD_PROJECT}
export TF_VAR_region=us-east1-d
export TF_VAR_sa_name=kaniko-role
Terraform'u başlatın, bir plan oluşturun ve uygulayın:
terraform init terraform plan -out /tmp/tf.plan terraform apply /tmp/tf.plan && rm /tmp/tf.plan
Hizmet hesabının, Cloud Storage paketimize kaydetmek için depolama yöneticisi izinlerine sahip olması gerekir:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \
--role 'roles/storage.admin'
Ayrıca, ardışık düzenimizin dağıtım aşamaları için kapsayıcı izinleri de gerekir:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member \
serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com --role 'roles/container.developer'
Artık gke robot dağıtıcıyı kullanarak GKE eklentisi için küme izinlerini ayarlamak üzere Helm'i kullanabiliriz. Çalışma dizininizi GKE projesinin Helm dizini olarak değiştirin:
cd ~/google-kubernetes-engine-plugin/docs/helm/
Ve sağlanan Helm grafiğini kullanarak yükleyin:
export TARGET_NAMESPACE=kube-system && \ envsubst < gke-robot-deployer/values.yaml | helm install ./gke-robot-deployer --name gke-robot-deployer -f -
6. Jenkins'i yapılandırma
Hizmet Hesabı Anahtarları
Hizmet hesabının düzgün çalışması için özel anahtar dosyası oluşturup bunu Kubernetes Gizli Anahtarı olarak eklememiz gerekir. Öncelikle, aşağıdaki gcloud komutuyla dosyayı oluşturun:
gcloud iam service-accounts keys create /tmp/kaniko-secret.json --iam-account kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
Bu dosyayla Kubernetes gizli anahtar deposunda bir gizli anahtar oluştururuz:
kubectl create secret generic jenkins-int-samples-kaniko-secret --from-file=/tmp/kaniko-secret.json
Cloud Shell'in 3 nokta menüsünden Dosyayı İndir öğesine erişerek JSON dosyasını yerel diskinize indirin:

Dosya yolunu girin /tmp/kaniko-secret.json ve İndir'i tıklayın.
Jenkins sayfasına geri dönün. Sol taraftaki bölmede Credentials (Kimlik Bilgileri) ve ardından System'i (Sistem) tıklayın.


Sayfanın Sistem başlıklı bölümünde,sol tarafta Global kimlik bilgileri'ni ve ardından Kimlik bilgileri ekle'yi tıklayın:


Tür açılır listesinde Özel anahtardan Google hizmet hesabı'nı seçin. Ad olarak "kaniko-role" girin, ardından önceki adımlarda oluşturulan JSON anahtarınızı yükleyin ve Tamam'ı tıklayın.

Ortam Değişkenleri
Çok dallı ardışık düzeni oluşturmadan önce Jenkins'te tanımlamamız gereken bazı ortam değişkenleri vardır. Bunları şöyle sıralayabiliriz:
- JENK_INT_IT_ZONE: Kubernetes kümesinin bölgesi. Örneğimizde
us-east1-d - JENK_INT_IT_PROJECT_ID: Bu Jenkins örneğine barındıran GCP proje kimliğini ifade eder.
- JENK_INT_IT_STAGING: "staging" kümemizin adı. Gösterim amacıyla
stagingolarak ayarlanmıştır. - JENK_INT_IT_PROD: "prod" kümemizin adı. Bu demoda
prod - JENK_INT_IT_BUCKET: Önceki adımda oluşturulan Google Cloud Storage paketi
- JENK_INT_IT_CRED_ID: Önceki adımda JSON kullanılarak oluşturulan kimlik bilgilerini ifade eder. Değer,
kaniko-roleolarak verdiğimiz adla eşleşmelidir.
Bunları eklemek için Manage Jenkins'e (Jenkins'i Yönet) gidin:

Ardından Sistemi Yapılandır'ı tıklayın:

Global properties (Genel özellikler) adlı bir bölüm bulunur. Environment variables (Ortam değişkenleri) kutusunu işaretlediğimizde Add (Ekle) düğmesi gösterilir. Bu düğmeyi tıklayarak yukarıdaki değişkenleri anahtar/değer çiftleri olarak ekleriz:

Değişiklikleri uygulamak için sayfanın alt kısmındaki Kaydet düğmesini tıklayın.
7. Ardışık düzen oluşturma
Jenkins'te "New Item"ı (Yeni Öğe) tıklayın:

Ad için "jenkins-integration-sample" girin, proje türü olarak "Multibranch Pipeline"ı (Çok dallı işlem hattı) seçin ve Tamam'ı tıklayın:

İşlem hattı yapılandırma sayfasına yönlendiriliriz. Branch Sources (Şube Kaynakları) bölümünde Project Repository (Proje Deposu) olarak https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git adresini girin. Build Configuration (Derleme Yapılandırması) bölümünde Script Path (Komut Dosyası Yolu) olarak "gke/Jenkinsfile"ı girin.

Bu ayarları uygulamak için Kaydet'i tıklayın. Kaydettikten sonra Jenkins, deponun taranmasını ve her dal için sonraki derlemeyi başlatır. İşlem ilerledikçe Kubernetes İş Yükleri sayfasında derlemeler ilerlerken kapsüllerin oluşturulduğunu, çalıştırıldığını ve yok edildiğini görürsünüz.
Derlemeler tamamlandığında Kubernetes İş Yükleri sayfasında jenkins-integration-samples-gke adlı iki öğe görürsünüz. Bu öğelerin her biri üretim veya test kümesine karşılık gelir. Durum "Tamam" olarak görünür:

Aşağıdaki gcloud komutunu kullanarak, Google Container Registry'ye işlem hattımıza karşılık gelen bir kapsayıcı resmi yüklediğimizi görebiliriz:
gcloud container images list
İş yükünü tarayıcınızda görmek için üretim kümesinin kimlik bilgilerini alın:
gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
Ayrıca, kabuğunuzun 8081 numaralı bağlantı noktasından iş yükünüzün 8080 numaralı bağlantı noktasına yönlendirme ayarlamak için aşağıdaki komutu çalıştırın:
export POD_NAME=$(kubectl get pods -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8081:8080 >> /dev/null &
Cloud Shell'in üst kısmında Web Önizlemesi simgesini tıklayın ve "8081 numaralı bağlantı noktasında önizle"yi seçin.


8. Temizleme
Kubernetes'e Jenkins ve örnek bir çok dallı ardışık düzenin nasıl dağıtılacağını inceledik. Şimdi projemizi oluşturduğumuz kaynaklardan temizleme zamanı.
Projeyi silme
İsterseniz projenin tamamını silebilirsiniz. GCP Console'da Cloud Resource Manager sayfasına gidin:
Proje listesinde, üzerinde çalıştığımız projeyi seçip Sil'i tıklayın. Proje kimliğini girmeniz istenir. Girip Kapat'ı tıklayın.
Alternatif olarak, projenin tamamını doğrudan Cloud Shell'den gcloud ile silebilirsiniz:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Farklı faturalandırılabilir bileşenleri tek tek silmeyi tercih ediyorsanız bir sonraki bölüme geçin.
Kubernetes Kümesi
gcloud ile Kubernetes kümesinin tamamını silin:
gcloud container clusters delete jenkins-cd --zone=us-east1-d
Depolama paketleri
Yüklenen tüm dosyaları kaldırın ve gsutil ile paketimizi silin:
gsutil rm -r gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket
Google Container Registry Görüntüleri
Google Container Registry görüntüleri, görüntü özetleri kullanılarak silinir. Öncelikle aşağıdaki komutla özetleri alın:
gcloud container images list-tags gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke --format="value(digest)"
Ardından, döndürülen her özet için:
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke@sha256:<DIGEST>
9. Tebrikler!
Mükemmel! Başardınız. Jenkins'i GKE'ye dağıtmayı ve işleri Kubernetes kümelerine göndermeyi öğrendiniz.
İşlediğimiz konular
- Kubernetes kümesi dağıtıp Jenkins'i yüklemek için Helm'i kullandık.
- Jenkins'in derleme yapılarını Kubernetes kümelerine dağıtmasını sağlamak için GKE eklentisini yükleyip yapılandırdık.
- Jenkins'i, işi GKE kümelerine gönderen çok dallı bir ardışık düzen oluşturacak şekilde yapılandırdık.