1. Tổng quan
Trong phòng thí nghiệm này, bạn sẽ tạo dịch vụ thực đơn Cymbal Eats, cung cấp các API RESTful để thêm, cập nhật, xoá và liệt kê các mục trong thực đơn. Bạn sẽ tạo một cơ sở dữ liệu Cloud SQL làm cơ sở dữ liệu phụ trợ cho dịch vụ thực đơn, dịch vụ này sẽ chạy trong Cloud Run. Vì Cloud Run không nằm trong cùng một VPC với cơ sở dữ liệu Cloud SQL, nên bạn cần định cấu hình trình kết nối Serverless VPC Access để cho phép Cloud Run giao tiếp với Cloud SQL thông qua địa chỉ IP riêng tư.

Kiến thức bạn sẽ học được
Trong phòng thí nghiệm này, bạn sẽ học cách thực hiện những việc sau:
- Định cấu hình Mạng VPC riêng tư
- Tạo Cơ sở dữ liệu Cloud SQL Postgres riêng tư
- Kết nối CloudRun với VPC riêng tư
- Triển khai một dịch vụ trên Cloud Run kết nối với cơ sở dữ liệu Cloud SQL
2. Thiết lập và yêu cầu
Thiết lập môi trường tự học
- Đăng nhập vào Google Cloud Console rồi tạo một dự án mới hoặc sử dụng lại một 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.



- Tên dự án là tên hiển thị cho những người tham gia dự án này. Đây là một chuỗi ký tự mà các API của Google không sử dụng. Bạn có thể cập nhật tên này bất cứ lúc nào.
- Mã dự án là duy nhất trên tất cả các dự án của Google Cloud và không thể thay đổi (không thể thay đổi sau khi đã đặt). Cloud Console tự động tạo một chuỗi duy nhất; thường thì bạn không cần quan tâm đến chuỗi này. Trong hầu hết các lớp học lập trình, bạn sẽ cần tham chiếu đến Mã dự án (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ã ngẫu nhiên khác. Ngoài ra, bạn có thể thử mã của riêng mình và xem mã đó có dùng được hay không. Bạn không thể thay đổi mã này sau bước này và mã sẽ giữ nguyên trong suốt thời gian diễn ra dự án. - Để bạn nắm được thông tin, có một giá trị thứ ba là 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.
- Tiếp theo, bạn cần bật tính năng thanh toán trong Cloud Console để sử dụng các API/tài nguyên trên Cloud. Việc thực hiện lớp học lập trình này sẽ không tốn nhiều chi phí, thậm chí là không tốn chi phí nào. Để tắt các tài nguyên nhằm tránh phát sinh chi phí thanh toán ngoài hướng dẫn này, bạn có thể xoá các tài nguyên đã tạo hoặc xoá toàn bộ 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í trị giá 300 USD.
Thiết lập môi trường
- Tạo các biến môi trường liên quan đến dự án và tài nguyên
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export PROJECT_NAME=$(gcloud projects describe $PROJECT_ID --format='value(name)')
export REGION=us-east1
export MENU_SERVICE_NAME=menu-service
export SERVERLESS_VPC_CONNECTOR=cymbalconnector
export DB_INSTANCE_NAME=menu-catalog
export DB_INSTANCE_PASSWORD=password123
export DB_DATABASE=menu-db
export DB_USER=menu-user
export DB_PASSWORD=menupassword123
- Sao chép kho lưu trữ và chuyển đến thư mục
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/menu-service
- Bật các dịch vụ
gcloud services enable \
sqladmin.googleapis.com \
run.googleapis.com \
vpcaccess.googleapis.com \
servicenetworking.googleapis.com
3. Định cấu hình quyền truy cập riêng tư
Quyền truy cập dịch vụ riêng tư được cung cấp dưới dạng một đường liên kết kết nối ngang hàng VPC giữa mạng VPC của bạn và mạng VPC cơ bản của Google Cloud nơi thực thể Cloud SQL của bạn được đặt. Kết nối riêng tư cho phép các phiên bản máy ảo trong mạng VPC của bạn và các dịch vụ bạn sử dụng chỉ giao tiếp thông qua địa chỉ IP nội bộ. Để truy cập vào các dịch vụ có sẵn thông qua quyền truy cập dịch vụ riêng tư, các phiên bản máy ảo không yêu cầu kết nối Internet hoặc địa chỉ IP bên ngoài.
- Phân bổ một dải địa chỉ IP
gcloud compute addresses create google-managed-services-default \
--global \
--purpose=VPC_PEERING \
--prefix-length=20 \
--network=projects/$PROJECT_ID/global/networks/default
Kết quả ví dụ
Created [https://www.googleapis.com/compute/v1/projects/cymbal-eats-2-348215/global/addresses/google-managed-services-default].
- Tạo một kết nối riêng tư.
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=google-managed-services-default \
--network=default \
--project=$PROJECT_ID
Kết quả ví dụ
Operation "operations/pssn.p24-528514492617-2f2b507f-e4e5-4d53-a4de-9ddaceb4e92f" finished successfully.
4. Thiết lập Cloud SQL
Cloud SQL là một dịch vụ cơ sở dữ liệu được quản lý toàn bộ, giúp bạn dễ dàng thiết lập, duy trì, quản lý và quản trị cơ sở dữ liệu quan hệ PostgreSQL và MySQL trong đám mây. Mỗi phiên bản Cloud SQL được hỗ trợ bởi một máy ảo (VM) chạy trên máy chủ lưu trữ Google Cloud. Tuỳ chọn tính sẵn sàng cao cũng bao gồm một máy ảo dự phòng trong một vùng khác có cùng thiết lập như máy ảo chính. Cơ sở dữ liệu được lưu giữ trên một thiết bị lưu trữ mạng có thể mở rộng và lâu dài, được gọi là đĩa liên tục, được kết nối với máy ảo. Một địa chỉ IP tĩnh được gán cho mỗi máy ảo để đảm bảo rằng địa chỉ IP mà một ứng dụng kết nối vẫn không đổi trong suốt thời gian hoạt động của phiên thể Cloud SQL.

Bạn sẽ tạo một cơ sở dữ liệu Cloud SQL Postgres có địa chỉ IP riêng tư.
Tạo cơ sở dữ liệu và người dùng
- Tạo một phiên bản Cloud SQL Postgres để sử dụng IP riêng tư
gcloud sql instances create $DB_INSTANCE_NAME \
--project=$PROJECT_ID \
--network=projects/$PROJECT_ID/global/networks/default \
--no-assign-ip \
--database-version=POSTGRES_12 \
--cpu=2 \
--memory=4GB \
--region=$REGION \
--root-password=${DB_INSTANCE_PASSWORD}
Kết quả ví dụ
Created [https://sqladmin.googleapis.com/sql/v1beta4/projects/cymbal1/instances/menu-instance]. NAME: menu-instance DATABASE_VERSION: POSTGRES_12 LOCATION: us-east1-a TIER: db-custom-2-4096 PRIMARY_ADDRESS: - PRIVATE_ADDRESS: 10.8.80.5 STATUS: RUNNABLE
- Thêm cơ sở dữ liệu vào phiên bản cơ sở dữ liệu
gcloud sql databases create $DB_DATABASE --instance=$DB_INSTANCE_NAME
Kết quả ví dụ
Created database [menu-db]. instance: menu-catalog name: menu-db project: cymbal1
- Tạo người dùng SQL
gcloud sql users create ${DB_USER} \
--password=$DB_PASSWORD \
--instance=$DB_INSTANCE_NAME
Kết quả ví dụ
Created user [menu-user].
- Lưu trữ địa chỉ IP của cơ sở dữ liệu
export DB_INSTANCE_IP=$(gcloud sql instances describe $DB_INSTANCE_NAME \
--format=json | jq \
--raw-output ".ipAddresses[].ipAddress")
- Thêm vai trò Ứng dụng Cloud SQL vào tài khoản dịch vụ Compute Engine
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
--role="roles/cloudsql.client"
Kết quả ví dụ
Updated IAM policy for project [cymbal1]. [...]
5. VPC không máy chủ
Quyền truy cập VPC không máy chủ cho phép bạn kết nối trực tiếp với mạng Virtual Private Cloud từ các môi trường không máy chủ như Cloud Run, App Engine hoặc Cloud Functions. Việc định cấu hình Quyền truy cập VPC không máy chủ cho phép môi trường không máy chủ của bạn gửi yêu cầu đến mạng VPC bằng DNS nội bộ và địa chỉ IP nội bộ (theo định nghĩa của RFC 1918 và RFC 6598). Các phản hồi cho những yêu cầu này cũng sử dụng mạng nội bộ của bạn.
Bạn sẽ tạo một trình kết nối Serverless VPC Access cho dịch vụ Cloud Run để kết nối với Cloud SQL.

- Tạo một trình kết nối Serverless VPC Access trong cùng một mạng VPC với phiên bản Cloud SQL của bạn.
gcloud compute networks vpc-access connectors create ${SERVERLESS_VPC_CONNECTOR} \
--region=${REGION} \
--range=10.8.0.0/28
Kết quả ví dụ
Created connector [cymbalconnector].
6. Đang triển khai lên Cloud Run
Bạn sẽ tạo và triển khai một hình ảnh Docker lên Cloud Run, đồng thời kết nối Cloud Run với trình kết nối Serverless VPC để truy cập vào cơ sở dữ liệu Cloud SQL.
- Biên dịch ứng dụng bằng maven
./mvnw package -DskipTests
Kết quả ví dụ
[...] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 42.864 s [INFO] Finished at: 2022-04-28T16:15:33Z [INFO] ------------------------------------------------------------------------
- Tạo hình ảnh Docker:
docker build -f src/main/docker/Dockerfile.jvm \
--tag gcr.io/$PROJECT_NAME/menu-service .
Kết quả ví dụ
[...] Successfully built 4ef5d7a3befc Successfully tagged gcr.io/cymbal1/menu-service:latest
- Đẩy hình ảnh Docker vào Container Registry:
docker push gcr.io/$PROJECT_NAME/menu-service
Kết quả ví dụ
Using default tag: latest The push refers to repository [gcr.io/cymbalsql/menu-service] 17b374963800: Pushed d9a51c06430d: Pushed fff5d2a2cfc9: Pushed f21fceb558c6: Pushed 5ffbbbf218dd: Pushed 60609ec85f86: Layer already exists f2c4302f03b8: Layer already exists latest: digest: sha256:f64cb7c288dbf4ad9b12bd210c23c5aec1048dee040450ff2d9dbdf96e83a426 size: 1789
- Triển khai dịch vụ Thực đơn:
gcloud run deploy $MENU_SERVICE_NAME \
--image=gcr.io/$PROJECT_NAME/menu-service:latest \
--region $REGION \
--allow-unauthenticated \
--set-env-vars DB_USER=$DB_USER \
--set-env-vars DB_PASS=$DB_PASSWORD \
--set-env-vars DB_DATABASE=$DB_DATABASE \
--set-env-vars DB_HOST=$DB_INSTANCE_IP \
--vpc-connector $SERVERLESS_VPC_CONNECTOR \
--project=$PROJECT_ID \
--quiet
Kết quả ví dụ
[...] Done. Service [menu-service] revision [menu-service-00002-xox] has been deployed and is serving 100 percent of traffic. Service URL: https://menu-service-g2mfphytdq-uk.a.run.app
Google khuyên bạn nên sử dụng Secret Manager để lưu trữ thông tin nhạy cảm như thông tin đăng nhập SQL. Bạn có thể truyền bí mật dưới dạng biến môi trường hoặc gắn dưới dạng một ổ đĩa bằng Cloud Run.
- Lưu trữ URL dịch vụ Thực đơn:
MENU_SERVICE_URL=$(gcloud run services describe menu-service \
--platform managed \
--region $REGION \
--format=json | jq \
--raw-output ".status.url")
- Xác minh URL dịch vụ thực đơn
echo $MENU_SERVICE_URL
Kết quả ví dụ
https://menu-service-g2mfphytdq-uk.a.run.app
7. Kiểm thử dịch vụ
- Tạo mục thực đơn mới bằng cách gửi yêu cầu POST:
curl -X POST "${MENU_SERVICE_URL}/menu" \
-H 'Content-Type: application/json' \
-d '{
"itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"itemName": "Curry Plate",
"itemPrice": 12.5,
"itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"spiceLevel": 3,
"status": "Ready",
"tagLine": "Spicy touch for your taste buds!!"
}'
Kết quả ví dụ
{
"id": 16,
"createDateTime": "2022-04-28T18:14:04.17225",
"itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"itemName": "Curry Plate",
"itemPrice": 12.5,
"itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"spiceLevel": 3,
"status": "Processing",
"tagLine": "Spicy touch for your taste buds!!",
"updateDateTime": "2022-04-28T18:14:04.172298"
}
- Thay đổi trạng thái cho món trong thực đơn bằng cách gửi yêu cầu PUT:
curl -X PUT "${MENU_SERVICE_URL}/menu/1" \
-H 'Content-Type: application/json' \
-d '{"status": "Ready"}'
Kết quả ví dụ
{
"id": 1,
"createDateTime": "2022-04-28T17:21:02.369093",
"itemImageURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"itemName": "Curry Plate",
"itemPrice": 12.50,
"itemThumbnailURL": "https://images.unsplash.com/photo-1631452180519-c014fe946bc7?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1587&q=80",
"spiceLevel": 0,
"status": "Ready",
"tagLine": "Spicy touch for your taste buds!!",
"updateDateTime": "2022-04-28T17:21:02.657636"
}
8. Xin chúc mừng!
Xin chúc mừng, bạn đã hoàn thành lớp học lập trình này!
Bước tiếp theo:
Khám phá các lớp học lập trình khác về Cymbal Eats:
- Kích hoạt Cloud Workflows bằng Eventarc
- Kích hoạt quá trình xử lý sự kiện từ Cloud Storage
- Kết nối với cơ sở dữ liệu được quản lý toàn bộ từ Cloud Run
- Bảo mật ứng dụng không máy chủ bằng Identity Aware Proxy (IAP)
- Kích hoạt các công việc của Cloud Run bằng Cloud Scheduler
- Triển khai bảo mật trên Cloud Run
- Bảo mật lưu lượng truy cập vào Cloud Run
- Kết nối với AlloyDB riêng tư từ GKE Autopilot
Dọn dẹp
Để tránh phát sinh chi phí cho tài khoản Google Cloud của bạn đối với các tài nguyên được sử dụng trong hướng dẫn này, hãy xoá dự án chứa các tài nguyên đó hoặc giữ lại dự án và xoá từng tài nguyên.
Xoá dự án
Cách dễ nhất để loại bỏ chi phí thanh toán là xoá dự án mà bạn đã tạo cho hướng dẫn này.