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 thiết yếu không 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 cho Kubernetes trên Google Cloud và sử dụng trình bổ trợ GKE, chúng tôi 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 tôi 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 vào 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à xuất bản một vùng chứa lên Google Container Registry
- Triển khai ứng dụng mẫu vào môi trường GKE dàn dựng và sản xuất
Bạn cần có
- Một dự án trên Google Cloud có 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ẽ cung cấp và quản lý nhiều tài nguyên và dịch vụ đám mây 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 cho 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ụ xuất bản 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 của 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 vùng lưu trữ GCS để tải công việc kiểm thử lên. Hãy tạo một vùng lưu trữ 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 các 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 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
Hãy triển khai 2 cụm để lưu trữ các bản dựng dàn dựng và bản dựng phát hành 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
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 có các tệp kê khai Kubernetes mà chúng ta sẽ dùng để triển khai Jenkins xuống:
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ột liên kết vai trò cụm để cấp cho chính bạn quyền của 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 đăng nhập 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 có trong đó vào thư mục đang hoạt động:
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 nó với vai trò cụm cluster-admin để có thể thực hiện các thay đổi:
kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:tiller
Giờ đây, 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
Xác minh
Xác nhận rằng Helm đã sẵn sàng hoạt động với ./helm version – lệnh này sẽ trả về số phiên bản của máy khách 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, Helm đã được cài đặt trên cụm của chúng ta, 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
Xác minh
Hãy kiểm tra các pod:
kubectl get pods
Đầu ra sẽ cho thấy pod Jenkins của chúng ta có trạng thái RUNNING:
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ả đầ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
Quy 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 vụ này sẽ được Jenkins master tự động khởi chạy khi cần. Khi hoàn thành công việc, các phiên bản này sẽ tự động kết thúc 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 tôi, 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 thông tin đó:
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
rồi chọn "Xem trước trên cổng 8080"

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:

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

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 tôi xuất bản các bản triển khai được tạo trong Jenkins vào các cụm Kubernetes đang chạy trong GKE. Bạn cần thực hiện một số cấu hình về quyền IAM trên dự án của mình. 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 đã 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 tuỳ chỉnh của GCP với 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 các biến dự án, vùng và tên tài khoản dịch vụ. Chúng ta cung cấp những 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 độ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 cấp 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'
Giờ đây, chúng ta có thể dùng Helm để thiết lập quyền cho cụm đối với 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/
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 đó làm một bí mật của 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 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 ổ đĩ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:

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 Credentials (Thông tin đăng nhập), sau đó nhấp vào System (Hệ thống).


Trong phần Hệ thống của 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:


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.

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 Jenkins trước khi tạo quy trình gồm 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 này,
us-east1-d - JENK_INT_IT_PROJECT_ID – đề cập đến mã dự án GCP lưu trữ phiên bản Jenkins này
- JENK_INT_IT_STAGING – tên cụm "dàn dựng" của chúng tôi, cho mục đích minh hoạ, tên này là
staging - JENK_INT_IT_PROD – tên cụm "prod" của chúng tôi. Để minh hoạ, hãy chọn
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 đăng nhập đượ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 tôi đã đặt,
kaniko-role
Để thêm các thông tin này, hãy chuyển đến phần Manage Jenkins (Quản lý Jenkins):

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

Sẽ có một mục có tên là Global properties (Thuộc tính chung). 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). Hãy nhấp vào nút này để thêm các biến ở trên dưới dạng cặp khoá-giá trị:

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 "New Item" (Mục mới):

Nhập "jenkins-integration-sample" cho 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:

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).

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 từng nhánh. Khi quá trình này diễn ra, bạn sẽ thấy các nhóm được tạo, chạy và huỷ khi quá trình tạo diễn ra trên trang Kubernetes Workloads (Tải Kubernetes).
Khi quá trình tạo bản dựng hoàn tất, bạn sẽ thấy 2 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 một cụm prod hoặc thử nghiệm. Trạng thái sẽ là OK:

Khi dùng lệnh gcloud sau đây, 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 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 đăng nhập cho cụm prod:
gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
Và chạy lệnh sau để thiết lập một cổng chuyển tiếp từ cổng 8081 của shell đến 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"


8. Dọn dẹp
Chúng ta đã tìm hiểu cách triển khai 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 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 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ó 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
Nhóm lưu trữ
Xoá tất cả các tệp đã tải lên và xoá nhóm của chúng tôi bằng gsutil:
gsutil rm -r gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket
Hình ảnh trong Google Container Registry
Chúng tôi sẽ xoá các hình ảnh trong Google Container Registry bằng cách sử dụng mã nhận dạng hình ảnh. Trước tiên, hãy truy xuất các mã nhận dạng 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 đã làm được. Bạn đã tìm hiểu cách triển khai Jenkins trên GKE và điều phối các 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à 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ác cấu phần phần mềm bản dựng vào 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, giúp điều phối công việc đến các cụm GKE