Pipeline Multi-cabang Jenkins di GKE

1. Ringkasan

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

Yang akan Anda lakukan

  • Men-deploy Jenkins ke cluster Kubernetes
  • Deploy dan konfigurasi plugin Jenkins GKE untuk memungkinkan Jenkins membuat dan menghancurkan pod sebagai node eksekutor
  • Membangun 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 telah disiapkan. Jika belum memilikinya, Anda harus membuatnya.

2. Mempersiapkan

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

Cloud Shell

Selama 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 - Membangun 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}

Buat bucket GCS

Kita akan memerlukan bucket GCS untuk mengupload pekerjaan pengujian. Mari buat bucket menggunakan project ID kita dalam nama untuk memastikan keunikan:

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

3. Membuat cluster Kubernetes

Buat Cluster

Selanjutnya, kita akan membuat cluster GKE yang akan menghosting sistem Jenkins kita, termasuk pod yang akan dikirim sebagai worker node. Cakupan tambahan yang ditunjukkan oleh tanda --scopes akan memungkinkan Jenkins mengakses Cloud Source Repositories dan Container Registry. Di Konsol Cloud, 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

Kita juga akan men-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 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

Instal Helm

Kita akan menggunakan Helm, pengelola paket aplikasi untuk Kubernetes, guna menginstal Jenkins di cluster kita. Untuk memulai, download project yang mencakup 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}

Lalu, download biner Helm ke Konsol Cloud Anda:

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

Buka kompresi 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 buat akun layanan bernama tiller:

kubectl create serviceaccount tiller \
--namespace kube-system

Kemudian, 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 memperbarui repo:

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

28b45298e1e82748.png Verifikasi

Konfirmasi bahwa Helm siap digunakan dengan ./helm version - perintah 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"}

Instal Jenkins

Setelah Helm diinstal di cluster, kita siap 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 kita 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 ini akan diluncurkan secara otomatis oleh master Jenkins sesuai kebutuhan. Setelah menyelesaikan tugasnya, node builder akan otomatis dihentikan dan resource-nya akan ditambahkan kembali ke kumpulan resource cluster.

Terhubung ke Jenkins

Jenkins berjalan di cluster kita, 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.pnglalu pilih 'Preview on 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 Sign in, kita akan diarahkan ke halaman utama Jenkins.

9261f3e914829137.png

5. Menginstal dan mengonfigurasi plugin GKE

Plugin Google Kubernetes Engine memungkinkan kami 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 untuk memberikan peran tersebut. File ini memerlukan nilai untuk variabel project, region, dan nama 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 kami:

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

Selain itu, 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 chart 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 baik, kita perlu 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 sisi kiri, klik Credentials, lalu System.

6c140f7e6bb82f8.png

3b874912cdc8019b.png

Di bagian halaman berjudul Sistem, Klik Kredensial global, lalu Tambahkan kredensial 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 - merujuk ke project ID GCP yang menghosting instance Jenkins ini
  • JENK_INT_IT_STAGING - nama cluster'staging' kami, untuk tujuan demonstrasi, cluster ini adalah staging
  • JENK_INT_IT_PROD - nama cluster 'prod' kami. Untuk tujuan demonstrasi, nilainya adalah prod
  • JENK_INT_IT_BUCKET - bucket Google Cloud Storage yang dibuat pada langkah sebelumnya
  • JENK_INT_IT_CRED_ID - merujuk 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, Konfigurasi Sistem:

ce79d218b2799640.png

Akan ada bagian bernama Properti global, dan saat kita mencentang kotak untuk Variabel lingkungan, kita akan mendapatkan tombol Tambahkan 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 menyimpan, Jenkins akan memulai pemindaian repositori dan build berikutnya untuk setiap cabang. Saat progresnya berjalan, Anda akan melihat pod dibuat, dijalankan, dan dihancurkan saat build berjalan di halaman Kubernetes Workloads.

Setelah build selesai, Anda akan menemukan dua item di halaman Kubernetes Workloads yang bernama jenkins-integration-samples-gke, yang masing-masing sesuai dengan cluster produksi atau pengujian. Status akan menunjukkan 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 workload di browser Anda, dapatkan kredensial untuk cluster prod:

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

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

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, lalu pilih 'Preview on port 8081'

1b19b5b56f1bae7.png

e80e995e71763bb2.png

8. Pembersihan

Kita telah mempelajari cara men-deploy Jenkins dan contoh pipeline multibranch di Kubernetes. Sekarang saatnya menghapus semua resource yang telah kita buat dari project.

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 kami 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 mengirimkan tugas ke cluster Kubernetes.

Yang telah kita bahas

  • Kami men-deploy Cluster Kubernetes dan menggunakan Helm untuk menginstal Jenkins
  • Kami menginstal dan mengonfigurasi plugin GKE untuk memungkinkan Jenkins men-deploy artefak build ke cluster Kubernetes
  • Kami mengonfigurasi Jenkins untuk menyiapkan pipeline multibranch yang mengirimkan pekerjaan ke cluster GKE