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ó. Công cụ này được dùng để tự động hoá các phần không cần 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 cho Kubenetes trên Google Cloud và sử dụng trình bổ trợ GKE, chúng tôi có thể tự động và nhanh chóng mở rộng quy mô trình thực thi bản dựng khi cần. Khi kết hợp với Cloud Storage, chúng ta có thể tạo và kiểm thử ứ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 cho 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 vùng chứa dưới dạng nút thực thi
  • Tạo và kiểm thử Ứng dụng SpringBoot mẫu
  • Tạo và xuất bản vùng chứa lên Google Container Registry
  • Triển khai ứng dụng mẫu vào môi trường GKE thử nghiệm và môi trường thực tế

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 tài khoả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ẽ cấp phép và quản lý nhiều tài nguyên và dịch vụ đám mây bằng cách sử dụ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 liên tục tích hợp và liên tục phân phối của Google Cloud
  • Service Management API (API Quản lý dịch vụ) – 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 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 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 cách sử dụng mã dự án của chúng ta 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 nhóm sẽ được điều phối dưới dạng nút worker. Phạm vi bổ sung được chỉ định bằng cờ --scopes sẽ cho phép Jenkins truy cập vào Kho lưu trữ nguồn trên đám mây và Kho lưu trữ vùng chứa. 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

Hãy triển khai 2 cụm để lưu trữ các bản dựng thử nghiệm và bản dựng sản phẩm 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

Kết quả sẽ 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 của mình. Để bắt đầu, hãy tải dự án 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 hoạt động hiện tại thành thư mục dự án:

cd ~/continuous-deployment-on-kubernetes/

Tạo mối liên kết vai trò cụm để cấp cho chính 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}

Sau đó, hãy 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 hoạt động của bạn:

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 với vai trò cụm cluster-admin để có thể thực hiện 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 với ./helm version – thao tác 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

Giờ đây, khi Helm đã được cài đặt 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

Kết quả 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 bạn đã tạo dịch vụ Jenkins đúng cách:

kubectl get svc

Kết quả 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 Trình bổ trợ Kubernetes để tạo các tác nhân trình tạo. Các công cụ này sẽ được máy chủ Jenkins tự động khởi chạy khi cần. Khi công việc hoàn tất, các phiên bả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ị đã được tạo trong quá trình cài đặt. Hãy truy xuất dữ liệ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.pngrồ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 cho 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 đến trang chính của Jenkins.

9261f3e914829137.png

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

Trình bổ trợ Google Kubernetes Engine cho phép chúng ta phát hành các bản triển khai được tạo trong Jenkins cho 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

Cấu hình quyền IAM tự động

Thay đổi thư mục đang hoạt động hiện tại thành thư mục rbac của dự án GKE mà chúng ta đã nhân bản trước đó:

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

gcp-sa-setup.tf là tệp cấu hình Terraform sẽ tạo một vai trò IAM GCP tuỳ chỉnh có cá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 biến tên dự án, khu vực và tài khoản dịch vụ. Chúng ta cung cấp các giá trị đó bằng cách khai báo 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 động 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ị bộ nhớ để lưu vào bộ chứa Cloud Storage của chúng tôi:

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

Bạn cũng cần có quyền đối với 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 cách sử dụng trình triển khai robot gke. Thay đổi thư mục đang hoạt động thành thư mục helm của dự án GKE:

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

Sau đó, hãy 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 khoá 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 khoá bí mật của 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 ổ cục bộ bằng cách truy cập vào mục Tải tệp xuống trong trình đơn có biểu tượng 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ó tiêu đề Hệ thống trên trang,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ụ của Google từ khoá riêng tư. Nhập "kaniko-role" làm tên, sau đó tải khoá JSON đã 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

Chúng ta cần xác định một số biến môi trường 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 – khu vực 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 "staging" (chạy thử nghiệm) của chúng ta, để minh hoạ là staging
  • JENK_INT_IT_PROD – tên cụm "prod" của chúng tôi. Để minh hoạ, đó là prod
  • JENK_INT_IT_BUCKET – bộ chứa Google Cloud Storage được tạo ở bước trước
  • JENK_INT_IT_CRED_ID – tham chiếu đến thông tin xác thực được tạo bằng json ở bước trước. Giá trị này phải khớp với tên mà chúng ta đã đặt, kaniko-role

Để thêm các tệp này, hãy chuyển đến phần Manage Jenkins (Quản lý Jenkins):

d54f279190a07878.png

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

ce79d218b2799640.png

Sẽ có một mục có tên là Global properties (Thuộc tính toàn cục) và khi đánh dấu vào hộp Environment variables (Biến môi trường), chúng ta sẽ thấy nút Add (Thêm) để nhấp vào và thêm các biến ở trên dưới dạng cặp khoá-giá trị:

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 "Multibranch Pipeline" (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 Branch Sources (Nguồn nhánh), hãy nhập https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git làm Project Repository (Kho lưu trữ dự án). Trong phần Build Configuration (Cấu hình bản dựng), hãy nhập "gke/Jenkinsfile" làm Script Path (Đườ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à tạo bản dựng tiếp theo cho mỗi nhánh. Khi quá trình này diễn ra, bạn sẽ thấy các vùng chứa được tạo, chạy và huỷ bỏ khi các bản dựng tiến triển trên trang Kubernetes Workloads (Gánh nặng công việc trên 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 (Gánh nặng công việc trên Kubernetes) có tên jenkins-integration-samples-gke, mỗi mục tương ứng với cụm sản xuất hoặc cụm kiểm thử. Trạng thái sẽ là OK:

bdec6b1753d1ba07.png

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

gcloud container images list

Để xem khối lượng công việc trong trình duyệt, hãy lấy thông tin xác thực cho cụm sản phẩm:

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

Sau đó, hãy 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 khối lượng công việc:

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 đã tìm hiểu cách triển khai Jenkins và quy trình nhiều nhánh mẫu trên Kubernetes. Bây giờ, chúng ta cần dọn dẹp dự án của mình khỏi mọi tài nguyên đã 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 Trình quản lý tài nguyên trê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 Delete (Xoá). Bạn sẽ được nhắc nhập mã dự án. Nhập mật khẩu rồi nhấp vào Tắt.

Ngoài ra, bạn có thể xoá toàn bộ dự án ngay trong Cloud Shell bằng gcloud:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

Nếu bạn muốn xoá từng thành phần có thể 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 bộ nhớ

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

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

Hình ảnh trong Google Container Registry

Chúng ta sẽ xoá hình ảnh trong Google Container Registry bằng hàm tổng quan về hình ảnh. Trước tiên, hãy truy xuất các chuỗi đại diện 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 chuỗi đại diện đượ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 đã làm được. Bạn đã tìm hiểu cách triển khai Jenkins trên GKE và điều phối công việc đến các cụm Kubernetes.

Nội dung đã đề cập

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