Quy trình nhiều nhánh Jenkins trên GKE

1. Tổng quan

Jenkins là một trong những giải pháp tích hợp liên tục phổ biến nhất hiện có. Giải pháp này được dùng để tự động hoá các phần thiết yếu không phải do con người thực hiện trong quy trình phát triển phần mềm. Bằng cách triển khai Jenkins lên Kubernetes trên Google Cloud và sử dụng trình bổ trợ GKE, chúng ta có thể nhanh chóng và tự động mở rộng quy mô trình thực thi bản dựng khi cần. Kết hợp với Cloud Storage, chúng ta có thể tạo và kiểm thử một ứng dụng mà không tốn nhiều công sức.

Bạn sẽ thực hiện

  • Triển khai Jenkins lên một cụm Kubernetes
  • Triển khai và định cấu hình trình bổ trợ Jenkins GKE để cho phép Jenkins tạo và huỷ các pod dưới dạng nút thực thi
  • Tạo và kiểm thử một ứng dụng SpringBoot mẫu
  • Tạo và phát hành một vùng chứa lên Google Container Registry
  • Triển khai ứng dụng mẫu lên môi trường GKE phát hành công khai và môi trường GKE phát hành thử nghiệm

Bạn cần có

  • Một dự án Google Cloud đã thiết lập thông tin thanh toán. Nếu chưa có, bạn sẽ phải tạo một dự án.

2. Thiết lập

Lớp học lập trình này có thể chạy hoàn toàn trên Google Cloud Platform mà không cần cài đặt hoặc định cấu hình cục bộ.

Cloud Shell

Trong suốt lớp học lập trình này, chúng ta sẽ cung cấp và quản lý các tài nguyên và dịch vụ đám mây khác nhau bằng dòng lệnh thông qua Cloud Shell.

Bật API

Dưới đây là các API mà chúng ta cần bật trên dự án:

  • Compute Engine API – Tạo và chạy máy ảo
  • Kubernetes Engine API – Tạo và quản lý các ứng dụng dựa trên vùng chứa
  • Cloud Build API – Nền tảng tích hợp liên tục và phân phối liên tục của Google Cloud
  • Service Management API – Cho phép nhà sản xuất dịch vụ phát hành dịch vụ trên Google Cloud Platform
  • Cloud Resource Manager API – Tạo, đọc và cập nhật siêu dữ liệu cho các vùng chứa tài nguyên Google Cloud

Bật các API bắt buộc bằng lệnh gcloud sau:

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

Tạo một bộ chứa GCS

Chúng ta sẽ cần một bộ chứa GCS để tải công việc kiểm thử lên. Hãy tạo một bộ chứa bằng mã dự án trong tên để đảm bảo tính duy nhất:

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

3. Tạo cụm Kubernetes

Tạo cụm

Tiếp theo, chúng ta sẽ tạo một cụm GKE lưu trữ hệ thống Jenkins, bao gồm cả các pod sẽ được gửi đi dưới dạng nút trình thực thi. Phạm vi bổ sung được chỉ định bằng cờ --scopes sẽ cho phép Jenkins truy cập vào Cloud Source Repositories và Container Registry. Trong Cloud Console, hãy chạy lệnh sau:

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

Chúng ta cũng hãy triển khai 2 cụm để lưu trữ các bản dựng phát hành thử nghiệm và bản dựng phát hành công khai của ứng dụng mẫu:

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 Xác minh

Sau khi tạo các cụm, chúng ta có thể xác nhận rằng các cụm đang chạy bằng gcloud container clusters list

Đầu ra phải có RUNNING trong cột 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. Triển khai Jenkins bằng Helm

Cài đặt Helm

Chúng ta sẽ sử dụng Helm, một trình quản lý gói ứng dụng cho Kubernetes, để cài đặt Jenkins trên cụm. Để bắt đầu, hãy tải dự án xuống. Dự án này bao gồm các tệp kê khai Kubernetes mà chúng ta sẽ dùng để triển khai Jenkins:

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

Thay đổi thư mục đang làm việc hiện tại thành thư mục dự án:

cd ~/continuous-deployment-on-kubernetes/

Tạo một liên kết vai trò cụm để cấp cho bạn quyền vai trò quản trị viên cụm:

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

Kết nối với cụm Jenkins bằng cách lấy thông tin xác thực của cụm:

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

Và tải tệp nhị phân Helm xuống Cloud Console:

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

Giải nén tệp và sao chép tệp helm đi kèm vào thư mục đang làm việc hiện tại:

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

Tiller là phía máy chủ của Helm chạy trên cụm Kubernetes. Hãy tạo một tài khoản dịch vụ có tên là tiller:

kubectl create serviceaccount tiller \
--namespace kube-system

Và liên kết tài khoản này với vai trò cụm cluster-admin để tài khoản có thể thực hiện các thay đổi:

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

Bây giờ, chúng ta có thể khởi chạy Helm và cập nhật kho lưu trữ:

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

28b45298e1e82748.png Xác minh

Xác nhận rằng Helm đã sẵn sàng hoạt động bằng ./helm version – lệnh này sẽ trả về số phiên bản của ứng dụng và máy chủ:

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

Cài đặt Jenkins

Sau khi cài đặt Helm trên cụm, chúng ta đã sẵn sàng cài đặt Jenkins:

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

28b45298e1e82748.png Xác minh

Hãy kiểm tra các pod:

kubectl get pods

Đầu ra sẽ hiển thị pod Jenkins của chúng ta với trạng thái ĐANG CHẠY:

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

Xác nhận rằng dịch vụ Jenkins đã được tạo đúng cách:

kubectl get svc

Đầu ra sẽ có dạng như sau:

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

Quá trình cài đặt Jenkins sẽ sử dụng Kubernetes Plugin để tạo các tác nhân trình tạo. Các tác nhân này sẽ được Jenkins master tự động khởi chạy khi cần. Khi hoàn tất công việc, các tác nhân này sẽ tự động bị chấm dứt và tài nguyên của chúng sẽ được thêm lại vào nhóm tài nguyên của cụm.

Kết nối với Jenkins

Jenkins đang chạy trên cụm của chúng ta, nhưng để truy cập vào giao diện người dùng, hãy thiết lập tính năng chuyển tiếp cổng từ 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 &

Mật khẩu quản trị viên đã được tạo trong quá trình cài đặt. Hãy truy xuất mật khẩu đó:

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

Ở đầu Cloud Shell, hãy nhấp vào biểu tượng Xem trước trên web 7ddf5a65fd556dd6.png rồi chọn "Xem trước trên cổng 8080"

1d614c831a621cff.png

Chúng ta sẽ thấy màn hình đăng nhập cho Jenkins, nơi chúng ta có thể nhập admin làm tên người dùng và mật khẩu được trả về ở bước trước:

9cba23e856cbc84f.png

Khi nhấp vào Đăng nhập , chúng ta sẽ được chuyển hướng đến trang chính của Jenkins.

9261f3e914829137.png

5. Cài đặt và định cấu hình trình bổ trợ GKE

Google Kubernetes Engine Plugin cho phép chúng ta phát hành các bản triển khai được tạo trong Jenkins lên các cụm Kubernetes chạy trong GKE. Bạn cần thực hiện một số cấu hình với quyền IAM trên dự án. Chúng ta sẽ triển khai cấu hình đó bằng Terraform.

Trước tiên, hãy tải dự án trình bổ trợ GKE xuống:

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

Định cấu hình quyền IAM tự động

Thay đổi thư mục đang làm việc hiện tại thành thư mục rbac của dự án GKE mà chúng ta đã sao chép trước đó:

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

gcp-sa-setup.tf là một tệp cấu hình Terraform sẽ tạo một vai trò IAM GCP tuỳ chỉnh có quyền bị hạn chế cùng với một tài khoản dịch vụ GCP để cấp vai trò đó. Tệp này yêu cầu các giá trị cho các biến dự án, vùng và tên tài khoản dịch vụ. Chúng ta cung cấp các giá trị đó bằng cách khai báo trước các biến môi trường sau:

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

Khởi chạy Terraform, tạo một kế hoạch và áp dụng kế hoạch đó:

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

Tài khoản dịch vụ sẽ cần có quyền quản trị viên bộ nhớ để lưu vào bộ chứa 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'

Tài khoản này cũng cần có quyền vùng chứa cho các giai đoạn triển khai của quy trình:

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

Bây giờ, chúng ta có thể sử dụng Helm để thiết lập quyền cụm cho trình bổ trợ GKE bằng trình triển khai robot gke. Thay đổi thư mục đang làm việc thành thư mục helm của dự án GKE:

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

Và cài đặt bằng biểu đồ Helm được cung cấp:

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

6. Định cấu hình Jenkins

Khoá tài khoản dịch vụ

Để tài khoản dịch vụ hoạt động đúng cách, chúng ta cần tạo một tệp khoá riêng tư và thêm tệp đó dưới dạng bí mật Kubernetes. Trước tiên, hãy tạo tệp bằng lệnh gcloud sau:

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

Chúng ta sẽ tạo một khoá bí mật trong kho bí mật Kubernetes bằng tệp đó:

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

Tải tệp json xuống ổ đĩa cục bộ bằng cách truy cập vào mục Tải tệp xuống trong trình đơn 3 dấu chấm của Cloud Shell:

c40378e72013b843.png

Nhập đường dẫn tệp /tmp/kaniko-secret.json rồi nhấp vào Tải xuống.

Quay lại trang Jenkins, trên ngăn bên trái, hãy nhấp vào Thông tin xác thực,sau đó nhấp vào Hệ thống.

6c140f7e6bb82f8.png

3b874912cdc8019b.png

Trong phần của trang có tiêu đề Hệ thống,hãy nhấp vào Thông tin xác thực chung rồi nhấp vào Thêm thông tin xác thực ở bên trái:

4350c0e68561119b.png

3d3526551cdae8b.png

Trong trình đơn thả xuống Loại, hãy chọn Tài khoản dịch vụ Google từ khoá riêng tư. Nhập "kaniko-role" làm tên, sau đó tải khoá JSON mà bạn đã tạo ở các bước trước lên rồi nhấp vào OK.

b0502213408e730e.png

Biến môi trường

Có một số biến môi trường mà chúng ta cần xác định cho Jenkins trước khi tạo quy trình nhiều nhánh. Các loại chiến dịch phụ đó là:

  • JENK_INT_IT_ZONE – vùng của cụm Kubernetes. Trong trường hợp của chúng ta là us-east1-d
  • JENK_INT_IT_PROJECT_ID – đề cập đến mã dự án GCP lưu trữ thực thể Jenkins này
  • JENK_INT_IT_STAGING – tên cụm "phát hành thử nghiệm" của chúng ta, cho mục đích minh hoạ, tên này là staging
  • JENK_INT_IT_PROD – tên cụm "phát hành công khai" của chúng ta. Cho mục đích minh hoạ, tên này là prod
  • JENK_INT_IT_BUCKET – bộ chứa Google Cloud Storage được tạo ở bước trước
  • JENK_INT_IT_CRED_ID – đề cập đến thông tin xác thực được tạo bằng tệp json ở bước trước. Giá trị phải khớp với tên mà chúng ta đã đặt, kaniko-role

Để thêm các biến này, hãy chuyển đến Quản lý Jenkins:

d54f279190a07878.png

Sau đó, hãy chọn Định cấu hình hệ thống:

ce79d218b2799640.png

Sẽ có một phần có tên là Thuộc tính chung và khi chúng ta đánh dấu vào ô Biến môi trường, chúng ta sẽ nhận được nút Thêm mà chúng ta sẽ nhấp vào để thêm các biến ở trên dưới dạng cặp giá trị khoá:

81aa222a2b17b2cc.png

Nhấp vào nút Lưu ở cuối trang để áp dụng các thay đổi.

7. Thiết lập quy trình

Trong Jenkins, hãy nhấp vào "Mục mới":

8d1270ce4d7b6a8a.png

Nhập "jenkins-integration-sample" làm tên và chọn "Quy trình nhiều nhánh" làm loại dự án, rồi nhấp vào OK:

eb071ecfbb4d775b.png

Chúng ta sẽ được chuyển hướng đến trang cấu hình quy trình. Trong phần Nguồn nhánh , hãy nhập https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git làm Kho lưu trữ dự án. Trong phần Cấu hình bản dựng , hãy nhập "gke/Jenkinsfile" làm Đường dẫn tập lệnh.

5135bd6b0374508c.png

Nhấp vào Lưu để Áp dụng các chế độ cài đặt này. Sau khi lưu, Jenkins sẽ bắt đầu quét kho lưu trữ và bản dựng tiếp theo cho từng nhánh. Khi quá trình này diễn ra, bạn sẽ thấy các pod được tạo, chạy và huỷ khi các bản dựng tiến hành trên trang Kubernetes Workloads (Tải Kubernetes).

Khi các bản dựng hoàn tất, bạn sẽ thấy hai mục trên trang Kubernetes Workloads (Tải Kubernetes) có tên là jenkins-integration-samples-gke, mỗi mục tương ứng với cụm phát hành công khai hoặc cụm kiểm thử. Trạng thái sẽ là OK:

bdec6b1753d1ba07.png

Sử dụng lệnh gcloud sau, chúng ta sẽ thấy rằng mình đã tải một hình ảnh vùng chứa lên Google Container Registry tương ứng với quy trình:

gcloud container images list

Để xem tải trong trình duyệt, hãy lấy thông tin xác thực cho cụm phát hành công khai:

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

Và chạy lệnh sau để thiết lập tính năng chuyển tiếp cổng từ cổng 8081 của shell sang cổng 8080 của tải:

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

Ở đầu Cloud Shell, hãy nhấp vào biểu tượng Xem trước trên web rồi chọn "Xem trước trên cổng 8081"

1b19b5b56f1bae7.png

e80e995e71763bb2.png

8. Dọn dẹp

Chúng ta đã khám phá cách triển khai một Jenkins và một quy trình nhiều nhánh mẫu trên Kubernetes. Bây giờ là lúc dọn dẹp dự án của chúng ta khỏi mọi tài nguyên mà chúng ta đã tạo.

Xoá dự án

Nếu muốn, bạn có thể xoá toàn bộ dự án. Trong Bảng điều khiển GCP, hãy chuyển đến trang Cloud Resource Manager (Trình quản lý tài nguyên đám mây):

Trong danh sách dự án, hãy chọn dự án mà chúng ta đang làm việc rồi nhấp vào Xoá. Bạn sẽ được nhắc nhập mã dự án. Nhập mã đó rồi nhấp vào Tắt.

Ngoài ra, bạn có thể xoá toàn bộ dự án trực tiếp từ Cloud Shell bằng gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Nếu muốn xoá từng thành phần có tính phí, hãy chuyển sang phần tiếp theo.

Cụm Kubernetes

Xoá toàn bộ cụm Kubernetes bằng gcloud:

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

Bộ chứa lưu trữ

Xoá tất cả các tệp đã tải lên và xoá bộ chứa của chúng ta bằng gsutil:

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

Hình ảnh Google Container Registry

Chúng ta sẽ xoá hình ảnh Google Container Registry bằng cách sử dụng bản tóm tắt hình ảnh. Trước tiên, hãy truy xuất bản tóm tắt bằng lệnh sau:

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

Sau đó, đối với mỗi bản tóm tắt được trả về:

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

9. Xin chúc mừng!

Tuyệt vời! Bạn đã hoàn thành. Bạn đã tìm hiểu cách triển khai Jenkins trên GKE và gửi công việc đến các cụm Kubernetes.

Nội dung đã đề cập

  • Chúng ta đã triển khai một cụm Kubernetes và sử dụng Helm để cài đặt Jenkins
  • Chúng ta đã cài đặt và định cấu hình trình bổ trợ GKE để cho phép Jenkins triển khai các cấu phần phần mềm bản dựng lên các cụm Kubernetes
  • Chúng ta đã định cấu hình Jenkins để thiết lập một quy trình nhiều nhánh gửi công việc đến các cụm GKE