Cách định cấu hình dịch vụ Cloud Run để truy cập vào dịch vụ Cloud Run nội bộ bằng đầu ra VPC trực tiếp

1. Giới thiệu

Tổng quan

Để bảo mật lưu lượng truy cập mạng cho các dịch vụ và ứng dụng của mình, nhiều tổ chức sử dụng mạng Đám mây riêng ảo (VPC) trên Google Cloud với các biện pháp kiểm soát ranh giới để ngăn chặn việc đánh cắp dữ liệu. Mạng VPC là phiên bản ảo của một mạng vật lý được triển khai bên trong mạng sản xuất của Google. Mạng VPC cung cấp khả năng kết nối cho các thực thể máy ảo (VM) Compute Engine, cung cấp Bộ cân bằng tải mạng truyền qua nội bộ gốc và hệ thống proxy cho Bộ cân bằng tải ứng dụng nội bộ, kết nối với các mạng tại chỗ bằng cách sử dụng đường hầm Cloud VPN và tệp đính kèm VLAN cho Cloud Interconnect, đồng thời phân phối lưu lượng truy cập từ bộ cân bằng tải bên ngoài của Google Cloud đến các phần phụ trợ.

Không giống như máy ảo, các dịch vụ Cloud Run không được liên kết với bất kỳ mạng VPC cụ thể nào theo mặc định. Lớp học lập trình này minh hoạ cách thay đổi chế độ cài đặt lưu lượng truy cập đến (kết nối đến) sao cho chỉ lưu lượng truy cập đến từ một VPC mới có thể truy cập vào một dịch vụ Cloud Run (ví dụ: dịch vụ phụ trợ). Ngoài ra, lớp học lập trình này còn hướng dẫn bạn cách để một dịch vụ thứ hai (ví dụ: dịch vụ giao diện người dùng) truy cập vào dịch vụ Cloud Run phụ trợ thông qua một VPC.

Trong ví dụ này, dịch vụ Cloud Run phụ trợ trả về thông báo "hello world". Dịch vụ Cloud Run giao diện người dùng cung cấp một trường nhập dữ liệu trong giao diện người dùng để thu thập URL. Sau đó, dịch vụ giao diện người dùng thực hiện yêu cầu GET đến URL đó (ví dụ: dịch vụ phụ trợ), do đó, đây là yêu cầu từ dịch vụ đến dịch vụ (thay vì yêu cầu từ trình duyệt đến dịch vụ). Khi dịch vụ giao diện người dùng có thể truy cập thành công vào phần phụ trợ, thông báo "hello world" sẽ xuất hiện trong trình duyệt.

Kiến thức bạn sẽ học được

  • Cách chỉ cho phép lưu lượng truy cập từ một VPC đến dịch vụ Cloud Run
  • Cách định cấu hình lưu lượng truy cập ra trên một dịch vụ Cloud Run để giao tiếp với một dịch vụ Cloud Run chỉ có lưu lượng truy cập đến nội bộ

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

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

Kích hoạt Cloud Shell

  1. Trên Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Nếu đây là lần đầu tiên bạ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 thấy màn hình trung gian, hãy nhấp vào Tiếp tục.

d95252b003979716.png

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

7833d5e1c5d18f54.png

Máy ảo này được tải tất cả các công cụ phát triển cần thiết. Máy ảo này cung cấp một thư mục chính liên tục có dung lượng 5 GB và chạy trong Google Cloud, giúp tăng cường đáng kể hiệu suất mạng và xác thực. Bạn có thể thực hiện hầu hết, nếu không phải là tất cả, công việc trong lớp học lập trình này bằng trình duyệt.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy rằng mình đã được xác thực và dự án được đặt thành mã dự án của bạ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

Đầu ra của 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

Đầu ra của lệnh

[core]
project = <PROJECT_ID>

Nếu không, bạn có thể đặt dự án bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Đầu ra của lệnh

Updated property [core/project].

3. Tạo các dịch vụ Cloud Run

Thiết lập các biến môi trường

Bạn có thể thiết lập các biến môi trường sẽ được sử dụng trong suốt lớp học lập trình này.

REGION=<YOUR_REGION, e.g. us-central1>
FRONTEND=frontend
BACKEND=backend

Tạo dịch vụ Cloud Run phụ trợ

Trước tiên, hãy tạo một thư mục cho mã nguồn và chuyển sang thư mục đó.

mkdir -p internal-codelab/frontend internal-codelab/backend && cd internal-codelab/backend

Sau đó, hãy tạo một tệp package.json có nội dung sau:

{
    "name": "backend-service",
    "version": "1.0.0",
    "description": "",
    "scripts": {
        "start": "node index.js"
    },
    "dependencies": {
        "express": "^4.18.1"
    }
}

Tiếp theo, hãy tạo một tệp nguồn index.js có nội dung bên dưới. Tệp này chứa điểm truy cập cho dịch vụ và chứa logic chính cho ứng dụng.

const express = require('express');

const app = express();

app.use(express.urlencoded({ extended: true }));

app.get('/', function (req, res) {
    res.send("hello world");
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
    console.log(`helloworld: listening on port ${port}`);
});

Cuối cùng, hãy triển khai dịch vụ Cloud Run bằng cách chạy lệnh sau.

gcloud run deploy $BACKEND --source . --allow-unauthenticated --region $REGION

Tạo dịch vụ Cloud Run giao diện người dùng

Chuyển đến thư mục giao diện người dùng.

cd ../frontend

Sau đó, hãy tạo một tệp package.json có nội dung sau:

{
  "name": "frontend",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "axios": "^1.6.6",
    "express": "^4.18.2"
  }
}

Tiếp theo, hãy tạo một tệp nguồn index.js có nội dung bên dưới. Tệp này chứa điểm truy cập cho dịch vụ và chứa logic chính cho ứng dụng.

const express = require("express");
const app = express();
const port = 8080;
const path = require('path');
const axios = require('axios');

// serve static content (index.html) using
// built-in middleware function in Express 
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true }));

// this endpoint receives a URL in the post body
// and then makes a get request to that URL
// results are sent back to the caller
app.post('/callService', async (req, res) => {

    const url = req.body.url;
    let message = "";

    try {
        console.log("url: ", url);
        const response = await axios.get(url);
        message = response.data;

    } catch (error) {
        message = error.message;
        console.error(error.message);
    }

    res.send(`
        ${message}
        <p>
        </p>
    `);
});

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`);
});

Tạo một thư mục công khai cho tệp index.html

mkdir public
touch public/index.html

Và cập nhật index.html để chứa nội dung sau:

<html>
  <script
    src="https://unpkg.com/htmx.org@1.9.10"
    integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
    crossorigin="anonymous"
  ></script>
  <body>
    <div style="margin-top: 100px; margin-left: 100px">
      <h1>I'm the Frontend service on the Internet</h1>
      <form hx-trigger="submit" hx-post="/callService" hx-target="#message">
        <label for="url"> URL:</label>
        <input
          style="width: 308px"
          type="text"
          id="url"
          name="url"
          placeholder="The backend service URL"
          required
        />
        <button hx-indicator="#loading" type="submit">Submit</button>
        <p></p>
        <span class="htmx-indicator" id="loading"> Loading... </span>
        <div id="message" style="white-space: pre-wrap"></div>
        <p></p>
      </form>
    </div>
  </body>
</html>

Cuối cùng, hãy triển khai dịch vụ Cloud Run bằng cách chạy lệnh sau.

gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION

Gọi dịch vụ phụ trợ

Xác minh rằng bạn đã triển khai thành công 2 dịch vụ Cloud Run.

Mở URL của dịch vụ giao diện người dùng trong trình duyệt web.

Trong hộp văn bản, hãy nhập URL cho dịch vụ phụ trợ. Lưu ý rằng yêu cầu này được định tuyến từ thực thể Cloud Run giao diện người dùng đến dịch vụ Cloud Run phụ trợ, thay vì được định tuyến từ trình duyệt của bạn.

Bạn sẽ thấy thông báo "hello world".

4. Đặt dịch vụ phụ trợ chỉ cho lưu lượng truy cập đến nội bộ

Chạy lệnh gcloud sau để chỉ cho phép lưu lượng truy cập từ bên trong mạng VPC truy cập vào dịch vụ phụ trợ.

gcloud run services update $BACKEND --ingress internal --region $REGION

Để xác nhận rằng dịch vụ phụ trợ của bạn chỉ có thể nhận lưu lượng truy cập từ VPC, hãy thử lại để gọi dịch vụ phụ trợ từ dịch vụ giao diện người dùng.

Lần này, bạn sẽ thấy thông báo "Request failed with status code 404" (Yêu cầu không thành công với mã trạng thái 404)

Bạn nhận được lỗi này vì yêu cầu gửi đi của dịch vụ Cloud Run giao diện người dùng (tức là lưu lượng truy cập ra) sẽ đi ra Internet trước, vì vậy, Google Cloud không biết nguồn gốc của yêu cầu.

Trong phần tiếp theo, bạn sẽ định cấu hình dịch vụ giao diện người dùng để truy cập vào VPC, nhờ đó, Google Cloud sẽ biết yêu cầu đến từ VPC (được nhận dạng là nguồn nội bộ).

5. Định cấu hình dịch vụ giao diện người dùng để truy cập vào VPC

Trong phần này, bạn sẽ định cấu hình dịch vụ Cloud Run giao diện người dùng để giao tiếp với dịch vụ phụ trợ thông qua một VPC.

Để thực hiện việc này, bạn cần thêm lưu lượng truy cập ra trực tiếp của VPC vào các thực thể Cloud Run giao diện người dùng để cung cấp cho dịch vụ một IP nội bộ để sử dụng trong VPC. Sau đó, bạn sẽ định cấu hình lưu lượng truy cập ra sao cho tất cả các kết nối gửi đi từ dịch vụ giao diện người dùng sẽ chuyển đến VPC.

Trước tiên, hãy chạy lệnh sau để bật lưu lượng truy cập ra trực tiếp của VPC:

gcloud beta run services update $FRONTEND \
--network=default \
--subnet=default \
--vpc-egress=all-traffic \
--region=$REGION

Giờ đây, bạn có thể xác nhận rằng dịch vụ giao diện người dùng có quyền truy cập vào VPC:

gcloud beta run services describe $FRONTEND \
--region=$REGION

Bạn sẽ thấy đầu ra tương tự như

VPC access:
    Network:         default
    Subnet:          default
    Egress:          all-traffic

Bây giờ, hãy thử lại để gọi dịch vụ phụ trợ từ dịch vụ giao diện người dùng.

Lần này, bạn sẽ thấy thông báo "hello world".

Lưu ý: Dịch vụ giao diện người dùng của bạn sẽ không có quyền truy cập Internet vì tất cả lưu lượng truy cập ra đã được định tuyến đến VPC. Ví dụ: dịch vụ giao diện người dùng sẽ hết thời gian chờ nếu cố gắng truy cập vào https://curlmyip.org/.

6. Xin chúc mừng!

Xin chúc mừng bạn đã hoàn tất lớp học lập trình này!

Bạn nên xem lại tài liệu về Cloud Run và cách định cấu hình mạng riêng cho các dịch vụ Cloud Run.

Nội dung chúng ta đã đề cập

  • Cách chỉ cho phép lưu lượng truy cập từ một VPC đến dịch vụ Cloud Run
  • Cách định cấu hình lưu lượng truy cập ra trên một dịch vụ Cloud Run để giao tiếp với một dịch vụ Cloud Run chỉ có lưu lượng truy cập đến nội bộ

7. Dọn dẹp

Để tránh bị tính phí ngoài ý muốn (ví dụ: nếu các dịch vụ Cloud Run vô tình được gọi nhiều lần hơn hạn mức gọi Cloud Run hằng tháng trong gói miễn phí), bạn có thể xoá Cloud Run hoặc xoá dự án mà bạn đã tạo ở Bước 2.

Để xoá dịch vụ Cloud Run, hãy chuyển đến Cloud Run Cloud Console tại https://console.cloud.google.com/run rồi xoá các dịch vụ $FRONTEND và $BACKEND.

Nếu chọn xoá toàn bộ dự án, bạn có thể chuyển đến https://console.cloud.google.com/cloud-resource-manager, chọn dự án mà bạn đã tạo ở Bước 2 rồi chọn Xoá. Nếu xoá dự án, bạn cần thay đổi dự án trong Cloud SDK. Bạn có thể xem danh sách tất cả các dự án hiện có bằng cách chạy gcloud projects list.