Pipeline Multi-cabang Jenkins di GKE

1. Ringkasan

Jenkins adalah salah satu solusi continuous integration yang paling populer. Alat ini digunakan untuk mengotomatiskan bagian non-manusia yang penting dari proses pengembangan software. Dengan men-deploy Jenkins ke Kubenetes di Google Cloud dan menggunakan plugin GKE, kami dapat menskalakan eksekutor build dengan cepat dan otomatis sesuai kebutuhan. Dikombinasikan dengan Cloud Storage, kita dapat mem-build dan menguji aplikasi dengan upaya minimal.

Yang akan Anda lakukan

  • Men-deploy Jenkins ke cluster Kubernetes
  • Men-deploy dan mengonfigurasi plugin GKE Jenkins agar Jenkins dapat membuat dan menghancurkan pod sebagai node eksekutor
  • Mem-build dan menguji Aplikasi SpringBoot contoh
  • Membangun dan memublikasikan container ke Google Container Registry
  • Men-deploy aplikasi contoh ke lingkungan GKE staging dan produksi

Yang Anda butuhkan

  • Project Google Cloud dengan penagihan yang disiapkan. Jika belum memilikinya, Anda harus membuatnya.

2. Mempersiapkan

Codelab ini dapat berjalan sepenuhnya di Google Cloud Platform tanpa penginstalan atau konfigurasi lokal.

Cloud Shell

Di sepanjang codelab ini, kita akan menyediakan dan mengelola berbagai resource dan layanan cloud menggunakan command line melalui Cloud Shell.

Mengaktifkan API

Berikut adalah API yang perlu kita aktifkan di project:

  • Compute Engine API - Membuat dan menjalankan virtual machine
  • Kubernetes Engine API - Mem-build dan mengelola aplikasi berbasis container
  • Cloud Build API - Platform continuous integration dan continuous delivery Google Cloud
  • Service Management API - Memungkinkan produsen layanan memublikasikan layanan di Google Cloud Platform
  • Cloud Resource Manager API - Membuat, membaca, dan memperbarui metadata untuk penampung resource Google Cloud

Aktifkan API yang diperlukan dengan perintah gcloud berikut:

gcloud services enable compute.googleapis.com \
container.googleapis.com \
cloudbuild.googleapis.com \
servicemanagement.googleapis.com \
cloudresourcemanager.googleapis.com \
--project ${GOOGLE_CLOUD_PROJECT}

Membuat bucket GCS

Kita memerlukan bucket GCS untuk mengupload pekerjaan pengujian. Mari kita buat bucket menggunakan project ID dalam namanya untuk memastikan keunikannya:

gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket/ 

3. Membuat cluster Kubernetes

Membuat Cluster

Selanjutnya, kita akan membuat cluster GKE yang akan menghosting sistem Jenkins, termasuk pod yang akan dikirim sebagai node pekerja. Cakupan tambahan yang ditunjukkan oleh flag --scopes akan memungkinkan Jenkins mengakses Cloud Source Repositories dan Container Registry. Di Cloud Console, jalankan perintah berikut:

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

Mari kita juga deploy 2 cluster untuk menghosting build staging dan produksi aplikasi contoh:

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

28b45298e1e82748.png Verifikasi

Setelah cluster dibuat, kita dapat mengonfirmasi bahwa cluster tersebut berjalan dengan gcloud container clusters list

Output harus memiliki RUNNING di kolom STATUS:

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. Men-deploy Jenkins dengan Helm

Menginstal Helm

Kita akan menggunakan Helm, pengelola paket aplikasi untuk Kubernetes, untuk menginstal Jenkins di cluster. Untuk memulai, download project yang menyertakan manifes Kubernetes yang akan kita gunakan untuk men-deploy Jenkins:

git clone https://github.com/GoogleCloudPlatform/continuous-deployment-on-kubernetes.git ~/continuous-deployment-on-kubernetes

Ubah direktori kerja Anda saat ini ke direktori project:

cd ~/continuous-deployment-on-kubernetes/

Buat binding peran cluster untuk memberi diri Anda izin peran admin cluster:

kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)

Hubungkan ke cluster jenkins Anda dengan mendapatkan kredensialnya:

gcloud container clusters get-credentials jenkins-cd --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}

Dan download biner Helm ke Konsol Cloud Anda:

wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.1-linux-amd64.tar.gz

Ekstrak file dan salin file helm yang disertakan ke direktori kerja Anda saat ini:

tar zxfv helm-v2.14.1-linux-amd64.tar.gz && \
cp linux-amd64/helm .

Tiller adalah sisi server Helm yang berjalan di cluster Kubernetes. Mari kita buat akun layanan bernama tiller:

kubectl create serviceaccount tiller \
--namespace kube-system

Lalu, ikat ke peran cluster cluster-admin agar dapat melakukan perubahan:

kubectl create clusterrolebinding tiller-admin-binding \
--clusterrole=cluster-admin \
--serviceaccount=kube-system:tiller

Sekarang kita dapat melakukan inisialisasi Helm dan mengupdate repo:

./helm init --service-account=tiller && \
./helm repo update

28b45298e1e82748.png Verifikasi

Pastikan Helm siap digunakan dengan ./helm version - tindakan ini akan menampilkan nomor versi klien dan server:

Client: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}

Menginstal Jenkins

Setelah Helm diinstal di cluster, kita siap untuk menginstal Jenkins:

./helm install stable/jenkins -n cd \
-f jenkins/values.yaml \
--version 1.2.2 --wait

28b45298e1e82748.png Verifikasi

Mari kita periksa pod:

kubectl get pods

Output akan menampilkan pod Jenkins dengan status RUNNING:

NAME                          READY     STATUS    RESTARTS   AGE
cd-jenkins-7c786475dd-vbhg4   1/1       Running   0          1m

Pastikan layanan Jenkins telah dibuat dengan benar:

kubectl get svc

Outputnya kurang lebih akan seperti ini:

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

Penginstalan Jenkins akan menggunakan Plugin Kubernetes untuk membuat agen builder. Node tersebut akan otomatis diluncurkan oleh master Jenkins sesuai kebutuhan. Setelah tugasnya selesai, node builder akan otomatis dihentikan dan resource-nya akan ditambahkan kembali ke kumpulan resource cluster.

Menghubungkan ke Jenkins

Jenkins berjalan di cluster, tetapi untuk mengakses UI, mari kita siapkan penerusan port dari Cloud Shell:

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 &

Sandi admin dibuat selama penginstalan. Mari kita ambil:

printf $(kubectl get secret cd-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo

Di bagian atas Cloud Shell, klik ikon Pratinjau Web 7ddf5a65fd556dd6.pngdan pilih 'Pratinjau di port 8080'

1d614c831a621cff.png

Kita akan melihat layar login untuk Jenkins tempat kita dapat memasukkan admin untuk nama pengguna dan sandi yang ditampilkan pada langkah sebelumnya:

9cba23e856cbc84f.png

Saat mengklik Login, kita akan diarahkan ke halaman utama Jenkins.

9261f3e914829137.png

5. Menginstal dan mengonfigurasi plugin GKE

Plugin Google Kubernetes Engine memungkinkan kita memublikasikan deployment yang dibuat dalam Jenkins ke cluster Kubernetes yang berjalan dalam GKE. Ada beberapa konfigurasi yang perlu dilakukan dengan izin IAM di project Anda. Kita akan men-deploy konfigurasi tersebut menggunakan Terraform.

Pertama, download project plugin GKE:

git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin

Konfigurasi Izin IAM Otomatis

Ubah direktori kerja Anda saat ini ke direktori rbac project GKE yang kita clone sebelumnya:

cd ~/google-kubernetes-engine-plugin/docs/rbac/

gcp-sa-setup.tf adalah file konfigurasi Terraform yang akan membuat peran IAM GCP kustom dengan izin terbatas beserta akun layanan GCP yang akan diberi peran tersebut. File ini memerlukan nilai untuk variabel nama project, region, dan akun layanan. Kita memberikan nilai tersebut dengan mendeklarasikan variabel lingkungan berikut terlebih dahulu:

export TF_VAR_project=${GOOGLE_CLOUD_PROJECT}
export TF_VAR_region=us-east1-d
export TF_VAR_sa_name=kaniko-role

Lakukan inisialisasi Terraform, buat rencana, dan terapkan:

terraform init
terraform plan -out /tmp/tf.plan
terraform apply /tmp/tf.plan && rm /tmp/tf.plan

Akun layanan akan memerlukan izin admin penyimpanan untuk menyimpan ke bucket Cloud Storage:

gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \
--role 'roles/storage.admin'

Izin container juga diperlukan untuk tahap deployment pipeline kita:

gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member \
serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com --role 'roles/container.developer'

Sekarang kita dapat menggunakan Helm untuk menyiapkan izin cluster bagi plugin GKE menggunakan deployer robot gke. Ubah direktori kerja Anda ke direktori helm project GKE:

cd ~/google-kubernetes-engine-plugin/docs/helm/

Lalu, instal menggunakan diagram Helm yang disediakan:

export TARGET_NAMESPACE=kube-system && \
envsubst < gke-robot-deployer/values.yaml | helm install ./gke-robot-deployer --name gke-robot-deployer -f -

6. Mengonfigurasi Jenkins

Kunci Akun Layanan

Agar akun layanan berfungsi dengan benar, kita harus membuat file kunci pribadi dan menambahkannya sebagai secret Kubernetes. Pertama, buat file dengan perintah gcloud berikut:

gcloud iam service-accounts keys create /tmp/kaniko-secret.json --iam-account kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

Kita akan membuat kunci rahasia di secret store kubernetes dengan file tersebut:

kubectl create secret generic jenkins-int-samples-kaniko-secret --from-file=/tmp/kaniko-secret.json 

Download file json ke disk lokal Anda dengan mengakses item Download File dari menu 3 titik Cloud Shell:

c40378e72013b843.png

Masukkan jalur file /tmp/kaniko-secret.json, lalu klik Download.

Kembali ke halaman Jenkins, di panel samping kiri, klik Credentials, lalu System.

6c140f7e6bb82f8.png

3b874912cdc8019b.png

Di bagian halaman yang berjudul System, klik Global credentials, lalu Add credentials di sebelah kiri:

4350c0e68561119b.png

3d3526551cdae8b.png

Di menu dropdown Kind, pilih Google Service Account from private key. Masukkan 'kaniko-role' sebagai nama, lalu upload kunci JSON yang dibuat pada langkah sebelumnya dan klik OK.

b0502213408e730e.png

Variabel Lingkungan

Ada beberapa variabel lingkungan yang perlu kita tentukan di Jenkins sebelum membuat pipeline multi-cabang. Bagian-bagian tersebut adalah:

  • JENK_INT_IT_ZONE - zona cluster Kubernetes. Dalam kasus kita, us-east1-d
  • JENK_INT_IT_PROJECT_ID - mengacu pada project ID GCP yang menghosting instance Jenkins ini
  • JENK_INT_IT_STAGING - nama cluster'staging' kami, untuk tujuan demonstrasi, nama cluster ini adalah staging
  • JENK_INT_IT_PROD - nama cluster 'prod' kami. Untuk tujuan demonstrasi, parameternya adalah prod
  • JENK_INT_IT_BUCKET - bucket Google Cloud Storage yang dibuat pada langkah sebelumnya
  • JENK_INT_IT_CRED_ID - mengacu pada kredensial yang dibuat menggunakan json di langkah sebelumnya. Nilai harus cocok dengan nama yang kita berikan, kaniko-role

Untuk menambahkannya, buka Manage Jenkins:

d54f279190a07878.png

Kemudian Konfigurasikan Sistem:

ce79d218b2799640.png

Akan ada bagian bernama Global properties, dan saat mencentang kotak Environment variables, kita akan mendapatkan tombol Add yang akan kita klik untuk menambahkan variabel di atas sebagai pasangan nilai kunci:

81aa222a2b17b2cc.png

Klik tombol Simpan di bagian bawah halaman untuk menerapkan perubahan.

7. Menyiapkan pipeline

Di Jenkins, klik 'New Item':

8d1270ce4d7b6a8a.png

Masukkan 'jenkins-integration-sample' untuk nama dan pilih 'Multibranch Pipeline' sebagai jenis project, lalu klik OK:

eb071ecfbb4d775b.png

Kita akan dialihkan ke halaman konfigurasi pipeline. Di bagian Branch Sources, masukkan https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git sebagai Project Repository. Di bagian Build Configuration, masukkan 'gke/Jenkinsfile' sebagai Script Path.

5135bd6b0374508c.png

Klik Simpan untuk Menerapkan setelan ini. Setelah disimpan, Jenkins akan memulai pemindaian repositori dan build berikutnya untuk setiap cabang. Seiring berjalannya waktu, Anda akan melihat pod dibuat, dijalankan, dan dihancurkan seiring progres build di halaman Workload Kubernetes.

Setelah build selesai, Anda akan menemukan dua item di halaman Workload Kubernetes bernama jenkins-integration-samples-gke, masing-masing sesuai dengan cluster produksi atau pengujian. Status akan bertuliskan OK:

bdec6b1753d1ba07.png

Dengan menggunakan perintah gcloud berikut, kita akan melihat bahwa kita telah mengupload image container ke Google Container Registry yang sesuai dengan pipeline kita:

gcloud container images list

Untuk melihat beban kerja di browser, dapatkan kredensial untuk cluster produksi:

gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}

Lalu, jalankan perintah berikut untuk menyiapkan penerusan port dari port 8081 shell ke port 8080 beban kerja:

export POD_NAME=$(kubectl get pods -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8081:8080 >> /dev/null &

Di bagian atas Cloud Shell, klik ikon Pratinjau Web dan pilih 'Pratinjau di port 8081'

1b19b5b56f1bae7.png

e80e995e71763bb2.png

8. Pembersihan

Kita telah mempelajari cara men-deploy Jenkins dan contoh pipeline multi-cabang di Kubernetes. Sekarang saatnya membersihkan project dari resource apa pun yang telah kita buat.

Menghapus Project

Jika mau, Anda dapat menghapus seluruh project. Di GCP Console, buka halaman Cloud Resource Manager:

Dalam daftar project, pilih project yang sedang kita kerjakan lalu klik Delete. Anda akan diminta untuk mengetikkan ID project. Masukkan dan klik Shut Down.

Atau, Anda dapat menghapus seluruh project langsung dari Cloud Shell menggunakan gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Jika Anda lebih suka menghapus berbagai komponen yang dapat ditagih satu per satu, lanjutkan ke bagian berikutnya.

Cluster Kubernetes

Hapus seluruh cluster Kubernetes dengan gcloud:

gcloud container clusters delete jenkins-cd --zone=us-east1-d

Bucket Penyimpanan

Hapus semua file yang diupload dan hapus bucket dengan gsutil:

gsutil rm -r gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket

Gambar Google Container Registry

Kita akan menghapus image Google Container Registry menggunakan ringkasan image. Pertama, ambil ringkasan dengan perintah berikut:

gcloud container images list-tags gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke --format="value(digest)"

Kemudian, untuk setiap ringkasan yang ditampilkan:

gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke@sha256:<DIGEST>

9. Selamat!

Asyik! Anda berhasil. Anda telah mempelajari cara men-deploy Jenkins di GKE dan mengirim tugas ke cluster Kubernetes.

Yang telah kita bahas

  • Kita telah men-deploy Cluster Kubernetes dan menggunakan Helm untuk menginstal Jenkins
  • Kita telah menginstal dan mengonfigurasi plugin GKE untuk memungkinkan Jenkins men-deploy artefak build ke cluster Kubernetes
  • Kita mengonfigurasi Jenkins untuk menyiapkan pipeline multicabang yang mengirim tugas ke cluster GKE