Triển khai ứng dụng Java Khởi động mùa xuân cho Kubernetes trên Google Kubernetes Engine

1. Trước khi bắt đầu

Kubernetes là một dự án nguồn mở, có thể chạy trên nhiều môi trường, từ máy tính xách tay cho đến cụm đa nút có khả năng hoạt động cao, từ đám mây công cộng đến triển khai tại chỗ và từ thực thể máy ảo (VM) cho đến kim loại trần.

Trong lớp học lập trình này, bạn sẽ triển khai một ứng dụng web khởi động bằng Java đơn giản cho Kubernetes trên GKE, với mục tiêu là chạy ứng dụng web của bạn như một ứng dụng được sao chép trên Kubernetes. Bạn sẽ lấy đoạn mã mà bạn phát triển trên máy, biến đoạn mã đó thành hình ảnh vùng chứa Docker rồi chạy hình ảnh đó trên GKE.

Bạn sẽ dùng GKE, một dịch vụ Kubernetes được quản lý toàn diện trên Google Cloud, để có thể tập trung nhiều hơn vào việc trải nghiệm Kubernetes thay vì thiết lập cơ sở hạ tầng cơ bản.

Nếu bạn muốn chạy Kubernetes trên máy cục bộ (chẳng hạn như máy tính xách tay phát triển), hãy tìm hiểu Minikube. Ứng dụng này cung cấp cách thiết lập đơn giản cho cụm Kubernetes một nút nhằm phục vụ mục đích phát triển và kiểm thử. Bạn có thể dùng Minikube để tham gia lớp học lập trình nếu muốn.

Lớp học lập trình này sẽ sử dụng mã mẫu trong hướng dẫn Xây dựng ứng dụng bằng Spring Boot.

Điều kiện tiên quyết

  • Làm quen với các công cụ và ngôn ngữ lập trình Java
  • Có kiến thức về các trình chỉnh sửa văn bản tiêu chuẩn của Linux, chẳng hạn như Vim, Emacs và nano

Bạn sẽ thực hiện

  • Đóng gói một ứng dụng Java đơn giản dưới dạng vùng chứa Docker.
  • Tạo cụm Kubernetes trên GKE.
  • Triển khai ứng dụng Java cho Kubernetes trên GKE.
  • Mở rộng quy mô dịch vụ và triển khai bản nâng cấp.
  • Truy cập vào Trang tổng quan, một giao diện người dùng Kubernetes dựa trên nền tảng web.

Bạn cần có

  • Một dự án trên Google Cloud
  • Một trình duyệt, chẳng hạn như Google Chrome

2. Thiết lập và yêu cầu

Thiết lập môi trường theo tiến độ riêng

  1. Đăng nhập vào Google Cloud Console rồi tạo dự án mới hoặc sử dụng lại dự án hiện có. Nếu chưa có tài khoản Gmail hoặc Google Workspace, bạn phải tạo một tài khoản.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Tên dự án là tên hiển thị của những người tham gia dự án này. Đây là một chuỗi ký tự không được API của Google sử dụng. Bạn luôn có thể cập nhật ứng dụng.
  • Mã dự án là duy nhất trong tất cả các dự án Google Cloud và không thể thay đổi (không thể thay đổi sau khi đã đặt). Cloud Console sẽ tự động tạo một chuỗi duy nhất; thường bạn không quan tâm đến sản phẩm đó là gì. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham khảo Mã dự án của mình (thường được xác định là PROJECT_ID). Nếu không thích mã đã tạo, bạn có thể tạo một mã nhận dạng ngẫu nhiên khác. Ngoài ra, bạn có thể thử cách riêng của mình để xem có thể sử dụng hay không. Bạn không thể thay đổi mã này sau bước này và mã vẫn giữ nguyên trong thời gian dự án.
  • Đối với thông tin của bạn, có giá trị thứ ba, Project Number (Số dự án), mà một số API sử dụng. Tìm hiểu thêm về cả ba giá trị này trong tài liệu này.
  1. Tiếp theo, bạn sẽ phải bật tính năng thanh toán trong Cloud Console để sử dụng API/tài nguyên trên đám mây. Việc chạy qua lớp học lập trình này sẽ không tốn nhiều chi phí. Để tắt các tài nguyên nhằm tránh phát sinh việc thanh toán ngoài hướng dẫn này, bạn có thể xoá các tài nguyên bạn đã tạo hoặc xoá dự án. Người dùng mới của Google Cloud đủ điều kiện tham gia chương trình Dùng thử miễn phí 300 USD.

Kích hoạt Cloud Shell

  1. Trong Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell 853e55310c205094.pngs.

55efc1aaa7a4d3ad.pngS

Nếu đây là lần đầu tiên khởi động Cloud Shell, bạn sẽ thấy một màn hình trung gian mô tả về Cloud Shell. Nếu bạn nhìn thấy màn hình trung gian, hãy nhấp vào Tiếp tục.

9c92662c6a846a5c.pngS

Quá trình cấp phép và kết nối với Cloud Shell chỉ mất vài phút.

9f0e51b578fecce5.pngs

Máy ảo này được tải tất cả các công cụ phát triển cần thiết. Dịch vụ này cung cấp thư mục gốc có dung lượng ổn định 5 GB và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Nhiều (nếu không nói là) tất cả công việc của bạn trong lớp học lập trình này đều có thể thực hiện bằng trình duyệt.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy mình đã được xác thực và dự án được đặt thành mã dự án.

  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:
gcloud auth list

Kết quả lệnh

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn:
gcloud config list project

Kết quả lệnh

[core]
project = <PROJECT_ID>

Nếu chưa, bạn có thể thiết lập chế độ này bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Kết quả lệnh

Updated property [core/project].

3. Lấy mã nguồn

Sau khi Cloud Shell chạy, bạn có thể sử dụng dòng lệnh để sao chép mã nguồn mẫu trong thư mục gốc.

$ git clone https://github.com/spring-guides/gs-spring-boot.git
$ cd gs-spring-boot/complete

4. Chạy ứng dụng cục bộ

  1. Đảm bảo đặt JAVA_HOME về đúng phiên bản:
$ export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
  1. Bạn có thể khởi động ứng dụng Spring Boot như bình thường bằng trình bổ trợ Spring Boot.
$ ./mvnw -DskipTests spring-boot:run
  1. Sau khi ứng dụng khởi động, nhấp vào Web Preview 1a94d5bd10bfc072.pngStrong thanh công cụ Cloud Shell và chọn Xem trước trên cổng 8080.

6252b94905f3f7bd.pngS

Một tab trong trình duyệt của bạn mở ra và kết nối với máy chủ bạn vừa khởi động.

9b6c29059957bd0.jpeg

5. Đóng gói ứng dụng Java dưới dạng vùng chứa Docker

Tiếp theo, bạn cần chuẩn bị ứng dụng để chạy trên Kubernetes. Bước đầu tiên là xác định vùng chứa và nội dung của vùng chứa đó.

  1. Tạo tệp JAR có thể triển khai cho ứng dụng.
$ ./mvnw -DskipTests package
  1. Bật Artifact Registry API để lưu trữ hình ảnh vùng chứa mà bạn sẽ tạo.
$ gcloud services enable artifactregistry.googleapis.com
  1. Tạo một kho lưu trữ Docker mới nếu chưa có. Bạn phải tạo một kho lưu trữ trước khi có thể đẩy hình ảnh bất kỳ vào kho lưu trữ đó:
$ gcloud artifacts repositories create codelabrepo     --repository-format=docker --location=us-central1 
  1. Hình ảnh của bạn sẽ có định dạng:

{LOCATION}-docker.pkg.dev/{PROJECT-ID}/{REPOSITORY}/{IMAGE-NAME}

Ví dụ: nếu bạn đã tạo kho lưu trữ ở vị trí us-central1 có tên là codelabrepo và bạn muốn đặt tên cho hình ảnh là hello-java:v1, hình ảnh sẽ là:

us-central1-docker.pkg.dev/{PROJECT-ID}/codelabrepo/hello-java:v1

  1. Sử dụng Jib để tạo hình ảnh vùng chứa rồi đẩy hình ảnh đó vào Artifact Registry.
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format="value(core.project)"`

$ ./mvnw -DskipTests com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/codelabrepo/hello-java:v1
  1. Bạn có thể thấy hình ảnh vùng chứa trong bảng điều khiển bằng cách chuyển đến trang Hình ảnh của Artifacts Registry trong Cloud Console. Bạn hiện đã có một hình ảnh Docker trên toàn dự án mà Kubernetes có thể truy cập và sắp xếp như bạn thấy sau vài phút.
  2. (Không bắt buộc) Sau khi hoàn tất (sẽ mất chút thời gian để tải xuống và giải nén mọi thứ), hãy kiểm thử hình ảnh bằng lệnh sau. Thao tác này sẽ chạy vùng chứa Docker dưới dạng trình nền trên cổng 8080 từ hình ảnh vùng chứa mới tạo của bạn. Nếu bạn gặp vấn đề về quyền, trước tiên, hãy chạy gcloud auth configure-docker us-central1-docker.pkg.dev:
$ docker run -ti --rm -p 8080:8080 \
  us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. Một lần nữa, hãy tận dụng tính năng xem trước trên web của Cloud Shell.

6252b94905f3f7bd.pngS

  1. Bạn sẽ thấy trang mặc định trong thẻ mới. Sau khi xác minh rằng ứng dụng đang chạy cục bộ trong vùng chứa Docker, bạn có thể dừng vùng chứa đang chạy bằng cách nhấn Control+C.

6. Tạo cụm

Bạn đã sẵn sàng tạo cụm GKE. Một cụm bao gồm một máy chủ API Kubernetes do Google quản lý và một tập hợp các nút worker. Các nút worker là máy ảo Compute Engine.

  1. Trước tiên, hãy đảm bảo rằng bạn đã bật các tính năng API có liên quan.
$ gcloud services enable compute.googleapis.com container.googleapis.com
  1. Tạo một cụm có 2 nút n1-standard-1 (sẽ mất vài phút để hoàn tất).
$ gcloud container clusters create hello-java-cluster \
  --num-nodes 2 \
  --machine-type n1-standard-1 \
  --zone us-central1-c

Cuối cùng, bạn sẽ thấy cụm đã tạo.

Creating cluster hello-java-cluster...done.
Created [https://container.googleapis.com/v1/projects/...].
kubeconfig entry generated for hello-dotnet-cluster.
NAME                  ZONE            MASTER_VERSION  
hello-java-cluster  us-central1-c  ...

Giờ đây, bạn sẽ có một cụm Kubernetes hoạt động đầy đủ do GKE cung cấp.

758c7fca14f70623.pngS

Đã đến lúc triển khai ứng dụng trong vùng chứa của bạn cho cụm Kubernetes! Từ giờ trở đi, bạn sẽ sử dụng dòng lệnh kubectl (đã thiết lập trong môi trường Cloud Shell). Phần còn lại của lớp học lập trình này yêu cầu phiên bản ứng dụng và máy chủ của Kubernetes từ 1.2 trở lên. kubectl version sẽ cho bạn thấy phiên bản hiện tại của lệnh.

7. Triển khai ứng dụng trên Kubernetes

  1. Việc triển khai Kubernetes có thể tạo, quản lý và mở rộng quy mô của nhiều phiên bản ứng dụng bằng hình ảnh vùng chứa mà bạn đã tạo. Triển khai một thực thể của ứng dụng cho Kubernetes bằng lệnh kubectl run.
$ kubectl create deployment hello-java --image=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1
  1. Để xem phiên bản triển khai đã tạo, bạn chỉ cần chạy lệnh sau:
$ kubectl get deployments

NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   1         1         1            1           37s
  1. Để xem các phiên bản ứng dụng được tạo bằng quá trình triển khai, hãy chạy lệnh sau:
$ kubectl get pods

NAME                         READY     STATUS    RESTARTS   AGE
hello-java-714049816-ztzrb   1/1       Running   0          57s

Tại thời điểm này, bạn nên chạy vùng chứa dưới sự kiểm soát của Kubernetes, nhưng vẫn phải làm cho vùng chứa có thể tiếp cận với thế giới bên ngoài.

8. Cho phép lưu lượng truy cập bên ngoài

Theo mặc định, chỉ IP nội bộ trong cụm đó mới có thể truy cập vào Nhóm đó. Để có thể truy cập vùng chứa hello-java từ bên ngoài mạng ảo Kubernetes, bạn phải hiển thị Nhóm dưới dạng một dịch vụ của Kubernetes.

  1. Trong Cloud Shell, bạn có thể hiển thị Nhóm trên Internet công cộng bằng cách tạo dịch vụ Tải cân bằng tải Kubernetes.
$ kubectl create service loadbalancer hello-java --tcp=8080:8080

Xin lưu ý rằng bạn sẽ trực tiếp hiển thị hoạt động triển khai chứ không phải Nhóm. Điều đó sẽ khiến dịch vụ cuối cùng cân bằng lưu lượng truy cập trên tất cả các Nhóm được triển khai quản lý (trong trường hợp này, bạn chỉ cần một Nhóm, nhưng bạn sẽ thêm các bản sao khác sau này).

Kubernetes Master tạo trình cân bằng tải và các quy tắc chuyển tiếp Compute Engine, nhóm mục tiêu và quy tắc tường lửa có liên quan để giúp bạn có thể sử dụng dịch vụ hoàn toàn từ bên ngoài Google Cloud.

  1. Để tìm địa chỉ IP có thể truy cập công khai của dịch vụ, bạn chỉ cần yêu cầu kubectl liệt kê tất cả dịch vụ cụm.
$ kubectl get services

NAME         CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
hello-java   10.3.253.62    aaa.bbb.ccc.ddd  8080/TCP    1m
kubernetes   10.3.240.1     <none>           443/TCP    5m
  1. Bây giờ, bạn có thể truy cập dịch vụ bằng cách trỏ trình duyệt của bạn tới http://<EXTERNAL_IP>:8080.

9. Mở rộng quy mô dịch vụ

Một trong những tính năng mạnh mẽ mà Kubernetes cung cấp là dễ dàng mở rộng quy mô ứng dụng. Giả sử đột nhiên bạn cần thêm dung lượng cho ứng dụng của mình. Bạn chỉ cần yêu cầu trình kiểm soát sao chép quản lý số lượng bản sao mới cho các phiên bản ứng dụng.

$ kubectl scale deployment hello-java --replicas=3

deployment "hello-java" scaled

$ kubectl get deployment
NAME         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
hello-java   3         3         3            3           22m

Hãy lưu ý phương pháp khai báo. Thay vì bắt đầu hoặc dừng các thực thể mới, bạn sẽ khai báo số lượng thực thể sẽ chạy mọi lúc. Vòng lặp điều chỉnh của Kubernetes chỉ cần đảm bảo rằng thông tin thực tế khớp với yêu cầu của bạn và thực hiện hành động nếu cần.

10. Ra mắt bản nâng cấp cho dịch vụ của bạn

Tại một số thời điểm, ứng dụng mà bạn triển khai phát hành công khai sẽ yêu cầu sửa lỗi hoặc bổ sung tính năng. Kubernetes có thể giúp bạn triển khai phiên bản mới vào giai đoạn phát hành công khai mà không ảnh hưởng đến người dùng.

  1. Mở trình soạn thảo mã bằng cách nhấp vào Mở trình chỉnh sửa 2109d75686c889a.png.trong trình đơn Cloud Shell.
  2. Chuyển đến src/main/java/com/example/springboot/HelloController.java rồi cập nhật giá trị của phản hồi.
package com.example.springboot;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Google Kubernetes Engine!";
    }
}
  1. Sử dụng Jib để tạo và đẩy phiên bản mới của hình ảnh vùng chứa. Việc tạo và đẩy hình ảnh được cập nhật sẽ nhanh hơn nhiều vì bạn tận dụng tối đa việc lưu vào bộ nhớ đệm.
$ ./mvnw -DskipTests package com.google.cloud.tools:jib-maven-plugin:build -Dimage=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

Bạn đã sẵn sàng để Kubernetes cập nhật bộ điều khiển sao chép lên phiên bản mới một cách suôn sẻ!

  1. Để thay đổi nhãn hình ảnh cho vùng chứa đang chạy, bạn cần chỉnh sửa phương thức triển khai hello-java hiện tại và thay đổi hình ảnh từ us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v1

đến us-central1-docker.pkg.dev/PROJECT_ID/codelabrepo/hello-java:v2

  1. Bạn có thể dùng lệnh kubectl set image để yêu cầu Kubernetes triển khai phiên bản mới của ứng dụng trên toàn bộ cụm tại mỗi thời điểm bằng bản cập nhật định kỳ.
$ kubectl set image deployment/hello-java hello-java=us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

deployment "hello-java" image updated
  1. Hãy kiểm tra lại http://EXTERNAL_IP:8080 để xem liệu trình này đang trả về phản hồi mới.

11. Khôi phục

Rất tiếc! Bạn có mắc lỗi với phiên bản mới của ứng dụng không? Có thể phiên bản mới đã gặp lỗi và bạn cần nhanh chóng khôi phục phiên bản này. Với Kubernetes, bạn có thể dễ dàng khôi phục về trạng thái trước đó. Khôi phục ứng dụng bằng cách chạy lệnh sau:

$ kubectl rollout undo deployment/hello-java

Bạn sẽ thấy phản hồi cũ khi kiểm tra lại http://EXTERNAL_IP:8080.

12. Xin chúc mừng

Bạn đã tìm hiểu cách xây dựng và triển khai một ứng dụng web mới dựa trên Java cho Kubernetes trên GKE.

Dọn dẹp

$ gcloud container clusters delete hello-java-cluster --zone us-central1-c

$ gcloud container images delete us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v1 us-central1-docker.pkg.dev/$GOOGLE_CLOUD_PROJECT/codelabrepo/hello-java:v2

Tìm hiểu thêm