Di chuyển trang web nguyên khối sang dịch vụ vi mô trên Google Kubernetes Engine

1. Giới thiệu

Tại sao nên di chuyển từ một ứng dụng nguyên khối sang một cấu trúc vi dịch vụ? Việc chia một ứng dụng thành các dịch vụ vi mô có những ưu điểm sau; hầu hết những ưu điểm này đều xuất phát từ việc các dịch vụ vi mô được liên kết lỏng lẻo.

  • Bạn có thể kiểm thử và triển khai các vi dịch vụ một cách độc lập. Đơn vị triển khai càng nhỏ thì việc triển khai càng dễ dàng.
  • Bạn có thể triển khai các thành phần này bằng nhiều ngôn ngữ và khung. Đối với mỗi vi dịch vụ, bạn có thể thoải mái chọn công nghệ phù hợp nhất cho trường hợp sử dụng cụ thể của dịch vụ đó.
  • Các nhóm khác nhau có thể quản lý những ứng dụng này. Ranh giới giữa các dịch vụ vi mô giúp bạn dễ dàng chỉ định một nhóm cho một hoặc nhiều dịch vụ vi mô.
  • Bằng cách chuyển sang các dịch vụ vi mô, bạn sẽ giảm bớt sự phụ thuộc giữa các nhóm. Mỗi nhóm chỉ cần quan tâm đến các API của những vi dịch vụ mà họ phụ thuộc vào. Nhóm không cần phải nghĩ về cách triển khai các vi dịch vụ đó, về chu kỳ phát hành của chúng, v.v.
  • Bạn có thể dễ dàng thiết kế để dự phòng cho trường hợp thất bại. Khi có ranh giới rõ ràng giữa các dịch vụ, bạn sẽ dễ dàng xác định được việc cần làm nếu một dịch vụ ngừng hoạt động.

Một số nhược điểm khi so sánh với các ứng dụng nguyên khối là:

  • Vì một ứng dụng dựa trên vi dịch vụ là một mạng lưới gồm nhiều dịch vụ thường tương tác theo những cách không rõ ràng, nên độ phức tạp tổng thể của hệ thống có xu hướng tăng lên.
  • Không giống như nội bộ của một hệ thống nguyên khối, các dịch vụ vi mô giao tiếp qua mạng. Trong một số trường hợp, điều này có thể được xem là một mối lo ngại về bảo mật. Istio giải quyết vấn đề này bằng cách tự động mã hoá lưu lượng truy cập giữa các vi dịch vụ.
  • Có thể khó đạt được mức hiệu suất tương tự như khi sử dụng phương pháp nguyên khối do độ trễ giữa các dịch vụ.
  • Hành vi của hệ thống không phải do một dịch vụ duy nhất gây ra mà do nhiều dịch vụ và hoạt động tương tác của chúng. Do đó, bạn sẽ khó hiểu được cách hệ thống của mình hoạt động trong quá trình sản xuất (khả năng quan sát của hệ thống). Istio cũng là một giải pháp cho vấn đề này.

Trong phòng thí nghiệm này, chúng ta sẽ chạy các vi dịch vụ trong Google Kubernetes Engine (GKE). Kubernetes là một nền tảng để quản lý, lưu trữ, mở rộng quy mô và triển khai các vùng chứa. Bộ chứa là một cách đóng gói và chạy mã di động. Chúng rất phù hợp với mẫu vi dịch vụ, trong đó mỗi vi dịch vụ có thể chạy trong vùng chứa riêng.

Trong phòng thí nghiệm này, chúng ta sẽ triển khai một ứng dụng nguyên khối hiện có vào một cụm Google Kubernetes Engine, sau đó chia ứng dụng đó thành các vi dịch vụ!

Sơ đồ kiến trúc của các dịch vụ vi mô

Chúng ta sẽ bắt đầu bằng cách chia ứng dụng nguyên khối thành 3 dịch vụ vi mô, mỗi lần một dịch vụ. Các vi dịch vụ bao gồm Đơn đặt hàng, Sản phẩm và Giao diện người dùng. Chúng tôi tạo một hình ảnh Docker cho từng vi dịch vụ bằng Cloud Build, mà chúng tôi kích hoạt từ bên trong Cloud Shell. Sau đó, chúng ta sẽ triển khai và hiển thị các vi dịch vụ trên Google Kubernetes Engine (GKE) bằng một LoadBalancer thuộc loại dịch vụ Kubernetes. Chúng tôi sẽ thực hiện việc này cho từng dịch vụ trong khi đồng thời tái cấu trúc chúng ra khỏi monolith. Trong quá trình này, cả ứng dụng nguyên khối và các vi dịch vụ của chúng tôi sẽ chạy cho đến khi chúng tôi có thể xoá ứng dụng nguyên khối.

636a2d58588b2b87.png

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

  • Cách phân tách một ứng dụng nguyên khối thành các dịch vụ vi mô
  • Cách tạo một cụm Google Kubernetes Engine
  • Cách tạo một hình ảnh Docker
  • Cách triển khai hình ảnh Docker vào Kubernetes

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

  • Một tài khoản Google Cloud Platform có quyền quản trị để tạo dự án hoặc một dự án có vai trò Chủ sở hữu dự án
  • Có kiến thức cơ bản về Docker và Kubernetes

2. Thiết lập môi trường

Thiết lập môi trường theo tốc độ của riêng bạn

Nếu chưa có Tài khoản Google (Gmail hoặc Google Apps), bạn phải tạo một tài khoản. Đăng nhập vào bảng điều khiển Google Cloud Platform ( console.cloud.google.com) rồi tạo một dự án mới:

53dad2cefdae71da.png

Ảnh chụp màn hình từ 2016-02-10 12:45:26.png

Hãy nhớ mã dự án, một tên duy nhất trên tất cả các dự án trên Google Cloud (tên ở trên đã được sử dụng và sẽ không hoạt động đối với bạn, xin lỗi!). Sau này trong lớp học lập trình này, chúng ta sẽ gọi nó là PROJECT_ID.

Tiếp theo, bạn cần bật tính năng thanh toán trong Developers Console để sử dụng các tài nguyên của Google Cloud và bật Container Engine API.

Việc thực hiện lớp học lập trình này sẽ không tốn của bạn quá vài đô la, nhưng có thể tốn nhiều hơn nếu bạn quyết định sử dụng nhiều tài nguyên hơn hoặc nếu bạn để các tài nguyên đó chạy (xem phần "dọn dẹp" ở cuối tài liệu này). Giá của Google Kubernetes Engine được ghi lại tại đây.

Người dùng mới của Google Cloud Platform đủ điều kiện dùng thử miễn phí trị giá 300 USD.

Google Cloud Shell

Mặc dù bạn có thể vận hành Google Cloud và Kubernetes từ xa trên máy tính xách tay, nhưng trong lớp học lập trình này, chúng ta sẽ sử dụng Google Cloud Shell, một môi trường dòng lệnh chạy trên đám mây.

Máy ảo dựa trên Debian này được trang bị tất cả các công cụ phát triển mà bạn cần. Nền tảng này cung cấp một thư mục chính 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à hoạt động xác thực. Điều này có nghĩa là bạn chỉ cần một trình duyệt (có, trình duyệt này hoạt động trên Chromebook) cho lớp học lập trình này.

  1. Để kích hoạt Cloud Shell từ Bảng điều khiển Cloud, bạn chỉ cần nhấp vào Kích hoạt Cloud Shell fEbHefbRynwXpq1vj2wJw6Dr17O0np8l-WOekxAZYlZQIORsWQE_xJl-cNhogjATLn-YxLVz8CgLvIW1Ncc0yXKJsfzJGMYgUeLsVB7zSwz7p6ItNgx4tXqQjag7BfWPcZN5kP-X3Q (mất vài phút để cung cấp và kết nối với môi trường).

I5aEsuNurCxHoDFjZRZrKBdarPPKPoKuExYpdagmdaOLKe7eig3DAKJitIKyuOpuwmrMAyZhp5AXpmD_k66cBuc1aUnWlJeSfo_aTKPY9aNMurhfegg1CYaE11jdpSTYNNIYARe01A

Screen Shot 2017-06-14 at 10.13.43 PM.png

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

gcloud auth list

Đầu ra của lệnh

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

Đầu ra của lệnh

[core]
project = <PROJECT_ID>

Nếu vì lý do nào đó mà dự án chưa được thiết lập, bạn chỉ cần đưa ra lệnh sau:

gcloud config set project <PROJECT_ID>

Bạn đang tìm PROJECT_ID? Kiểm tra mã nhận dạng bạn đã dùng trong các bước thiết lập hoặc tìm mã nhận dạng đó trong trang tổng quan của Cloud Console:

R7chO4PKQfLC3bvFBNZJALLTUiCgyLEq_67ECX7ohs_0ZnSjC7GxDNxWrJJUaoM53LnqABYamrBJhCuXF-J9XBzuUgaz7VvaxNrkP2TAn93Drxccyj2-5zz4AxL-G3hzxZ4PsM5HHQ

Cloud Shell cũng đặt một số biến môi trường theo mặc định, có thể hữu ích khi bạn chạy các lệnh trong tương lai.

echo $GOOGLE_CLOUD_PROJECT

Đầu ra của lệnh

<PROJECT_ID>
  1. Cuối cùng, hãy đặt cấu hình dự án và vùng mặc định.
gcloud config set compute/zone us-central1-f

Bạn có thể chọn nhiều múi giờ khác nhau. Để biết thêm thông tin, hãy xem phần Khu vực và vùng.

3. Sao chép kho lưu trữ nguồn

Chúng tôi sử dụng một ứng dụng nguyên khối hiện có của một trang web thương mại điện tử ảo, với một trang chào mừng đơn giản, một trang sản phẩm và một trang nhật ký đơn hàng. Chúng ta chỉ cần sao chép nguồn từ kho lưu trữ git, để có thể tập trung vào việc chia nhỏ nguồn thành các vi dịch vụ và triển khai vào Google Kubernetes Engine (GKE).

Chạy các lệnh sau để sao chép kho lưu trữ git vào phiên bản Cloud Shell của bạn và chuyển sang thư mục thích hợp. Chúng ta cũng sẽ cài đặt các phần phụ thuộc NodeJS để có thể kiểm thử ứng dụng nguyên khối trước khi triển khai. Có thể mất vài phút để tập lệnh này chạy.

cd ~
git clone https://github.com/googlecodelabs/monolith-to-microservices.git
cd ~/monolith-to-microservices
./setup.sh

Thao tác này sẽ sao chép kho lưu trữ Github của chúng tôi, chuyển sang thư mục và cài đặt các phần phụ thuộc cần thiết để chạy ứng dụng của chúng tôi trên thiết bị. Có thể mất vài phút để tập lệnh này chạy.

4. Tạo một cụm GKE

Giờ đây, bạn đã có môi trường phát triển đang hoạt động, chúng ta cần một cụm Kubernetes để triển khai ứng dụng nguyên khối và cuối cùng là các vi dịch vụ của mình! Trước khi có thể tạo một cụm, chúng ta cần đảm bảo rằng các API thích hợp đã được bật. Chạy lệnh sau để bật API vùng chứa để chúng ta có thể sử dụng Google Kubernetes Engine:

gcloud services enable container.googleapis.com

Giờ đây, chúng ta đã sẵn sàng tạo cụm! Chạy lệnh bên dưới để tạo một cụm GKE có tên là fancy-cluster với 3 nút.

gcloud container clusters create fancy-cluster --num-nodes 3

Có thể mất vài phút để tạo cụm. Sau khi lệnh hoàn tất, hãy chạy lệnh sau và xem 3 phiên bản máy ảo worker của cụm:

gcloud compute instances list

Kết quả:

NAME                                          ZONE        MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
gke-fancy-cluster-default-pool-ad92506d-1ng3  us-east4-a  n1-standard-1               10.150.0.7   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4fvq  us-east4-a  n1-standard-1               10.150.0.5   XX.XX.XX.XX    RUNNING
gke-fancy-cluster-default-pool-ad92506d-4zs3  us-east4-a  n1-standard-1               10.150.0.6   XX.XX.XX.XX    RUNNING

Bạn cũng có thể xem cụm Kubernetes và thông tin liên quan trong bảng điều khiển Google Cloud. Nhấp vào nút trình đơn ở trên cùng bên trái, di chuyển xuống Kubernetes Engine rồi nhấp vào Cụm. Bạn sẽ thấy cụm có tên là fancy-cluster.

795c794b03c5d2b0.png

6b394dfb8a6031f2.png

Xin chúc mừng! Bạn vừa tạo cụm Kubernetes đầu tiên!

5. Triển khai Monolith hiện có

Vì trọng tâm của phòng thí nghiệm này là hướng dẫn cách chia một ứng dụng nguyên khối thành các dịch vụ vi mô, nên chúng ta cần thiết lập và chạy một ứng dụng nguyên khối. Chạy tập lệnh sau để triển khai một ứng dụng nguyên khối vào cụm GKE của chúng tôi cho mục đích của phòng thí nghiệm này:

cd ~/monolith-to-microservices
./deploy-monolith.sh

Truy cập vào The Monolith

Để tìm địa chỉ IP ngoài cho ứng dụng đơn khối của chúng ta, hãy chạy lệnh sau.

kubectl get service monolith

Bạn sẽ thấy kết quả tương tự như dưới đây:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
monolith     10.3.251.122    203.0.113.0     80:30877/TCP     3d

LƯU Ý: Bạn cần cung cấp một bộ cân bằng tải và IP bên ngoài cho việc này, vì vậy, quá trình này sẽ mất một khoảng thời gian. Nếu đầu ra của bạn liệt kê IP ngoài là

<pending> Vui lòng đợi vài phút rồi thử lại.

Sau khi xác định địa chỉ IP ngoài cho monolith, hãy sao chép địa chỉ IP đó. Trỏ trình duyệt của bạn đến URL này (chẳng hạn như http://203.0.113.0) để kiểm tra xem bạn có thể truy cập vào monolith hay không.

9ed25c3f0cbe62fa.png

Bạn sẽ thấy trang chào mừng của trang web nguyên khối giống như hình ảnh ở trên. Trang chào mừng là một trang tĩnh sẽ được Frontend microservice phân phát sau này. Giờ đây, bạn đã có thể chạy hoàn toàn ứng dụng nguyên khối trên Kubernetes!

6. Di chuyển đơn đặt hàng sang dịch vụ vi mô

Giờ đây, khi trang web nguyên khối hiện có đang chạy trên GKE, chúng ta có thể bắt đầu chia mỗi dịch vụ thành một vi dịch vụ. Thông thường, nỗ lực lập kế hoạch sẽ diễn ra trên những dịch vụ cần chia thành các phần nhỏ hơn, thường là xung quanh các phần cụ thể của ứng dụng, chẳng hạn như miền kinh doanh. Để minh hoạ, chúng tôi đã tạo một ví dụ đơn giản và chia mỗi dịch vụ thành các miền kinh doanh, Đơn đặt hàng, Sản phẩm và Giao diện người dùng. Mã này đã được di chuyển và chúng tôi sẽ tập trung vào việc xây dựng và triển khai các dịch vụ trên Google Kubernetes Engine (GKE).

Tạo vi dịch vụ Đơn đặt hàng mới

Dịch vụ đầu tiên mà chúng ta sẽ tách ra là dịch vụ Đơn đặt hàng. Chúng ta sẽ sử dụng cơ sở mã riêng biệt được cung cấp và tạo một vùng chứa Docker riêng biệt cho dịch vụ này.

Tạo vùng chứa Docker bằng Google Cloud Build

Vì chúng tôi đã di chuyển cơ sở mã cho bạn, nên bước đầu tiên sẽ là tạo một vùng chứa Docker cho dịch vụ Đặt hàng bằng Google Cloud Build.

Thông thường, bạn sẽ phải thực hiện theo hai bước, bao gồm việc tạo một vùng chứa Docker và đẩy vùng chứa đó vào một sổ đăng ký để lưu trữ hình ảnh mà GKE sẽ kéo từ đó. Nhưng chúng ta có thể làm cho cuộc sống dễ dàng hơn, chúng ta có thể sử dụng Google Cloud Build để tạo vùng chứa Docker và đưa hình ảnh vào Google Cloud Container Registry chỉ bằng một lệnh! Điều này cho phép chúng ta đưa ra một lệnh duy nhất để tạo và di chuyển hình ảnh sang sổ đăng ký vùng chứa. Để xem quy trình tạo tệp docker và đẩy tệp theo cách thủ công, bạn có thể truy cập vào đây.

Google Cloud Build sẽ nén các tệp trong thư mục và di chuyển các tệp đó vào một bộ chứa Google Cloud Storage. Sau đó, quy trình xây dựng sẽ lấy tất cả các tệp trong vùng chứa và sử dụng tệp Docker để chạy quy trình xây dựng Docker. Vì chúng ta đã chỉ định cờ --tag với máy chủ lưu trữ là gcr.io cho hình ảnh Docker, nên hình ảnh Docker kết quả sẽ được chuyển đến Google Cloud Container Registry.

Chạy các lệnh sau để tạo vùng chứa Docker và đẩy vùng chứa đó vào Google Container Registry:

cd ~/monolith-to-microservices/microservices/src/orders
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/orders:1.0.0 .

Quá trình này sẽ mất vài phút, nhưng sau khi hoàn tất, sẽ có đầu ra trong thiết bị đầu cuối tương tự như sau:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ID                                    CREATE_TIME                DURATION  SOURCE                                                                                  IMAGES                              STATUS
1ae295d9-63cb-482c-959b-bc52e9644d53  2019-08-29T01:56:35+00:00  33S       gs://<PROJECT_ID>_cloudbuild/source/1567043793.94-abfd382011724422bf49af1558b894aa.tgz  gcr.io/<PROJECT_ID>/orders:1.0.0  SUCCESS

Để xem nhật ký bản dựng hoặc theo dõi quy trình theo thời gian thực, bạn có thể truy cập vào bảng điều khiển Google Cloud. Nhấp vào nút trình đơn ở trên cùng bên trái rồi di chuyển xuống Công cụ → Cloud Build và nhấp vào Nhật ký. Tại đây, bạn có thể xem danh sách tất cả các bản dựng trước đây của mình. Chỉ nên có 1 bản dựng mà bạn vừa tạo.

4c753ede203255f6.png

Nếu nhấp vào mã bản dựng, bạn có thể xem tất cả thông tin chi tiết về bản dựng đó, bao gồm cả đầu ra nhật ký.

Trên trang chi tiết bản dựng, bạn có thể xem hình ảnh vùng chứa đã được tạo bằng cách nhấp vào tên hình ảnh trong phần thông tin bản dựng.

6e88ed1643dfe629.png

Triển khai vùng chứa lên GKE

Giờ đây, chúng ta đã tạo vùng chứa cho trang web và chuyển vùng chứa đó sang Google Container Registry, đã đến lúc triển khai cho Kubernetes!

Kubernetes biểu thị các ứng dụng dưới dạng Pod, là những đơn vị biểu thị một vùng chứa (hoặc nhóm các vùng chứa được liên kết chặt chẽ). Pod là đơn vị triển khai nhỏ nhất trong Kubernetes. Trong hướng dẫn này, mỗi Pod chỉ chứa vùng chứa vi dịch vụ của bạn.

Để triển khai và quản lý các ứng dụng trên một cụm GKE, bạn phải giao tiếp với hệ thống quản lý cụm Kubernetes. Thông thường, bạn sẽ thực hiện việc này bằng cách sử dụng công cụ dòng lệnh kubectl trong Cloud Shell.

Trước tiên, chúng ta sẽ tạo một tài nguyên Deployment. Deployment quản lý nhiều bản sao của ứng dụng (gọi là bản sao) và lên lịch để các bản sao này chạy trên từng nút trong cụm. Trong trường hợp này, Deployment sẽ chỉ chạy một Pod của ứng dụng. Các hoạt động triển khai đảm bảo điều này bằng cách tạo một ReplicaSet. ReplicaSet chịu trách nhiệm đảm bảo số lượng bản sao được chỉ định luôn chạy.

Lệnh kubectl create deployment bên dưới khiến Kubernetes tạo một Deployment có tên là orders trên cụm của bạn với 1 bản sao.

Chạy lệnh sau để triển khai ứng dụng của bạn:

kubectl create deployment orders --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/orders:1.0.0

Xác minh quá trình triển khai

Để xác minh rằng bạn đã tạo thành công Deployment, hãy chạy lệnh sau. Có thể mất một chút thời gian để trạng thái của pod chuyển thành Running:

kubectl get all

Kết quả:

NAME                            READY   STATUS    RESTARTS   AGE
pod/monolith-779c8d95f5-dxnzl   1/1     Running   0          15h
pod/orders-5bc6969d76-kdxkk     1/1     Running   0          21s
NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
service/kubernetes   ClusterIP      10.39.240.1     <none>         443/TCP        19d
service/monolith     LoadBalancer   10.39.241.130   34.74.209.57   80:30412/TCP   15h
NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/monolith   1/1     1            1           15h
deployment.apps/orders     1/1     1            1           21s
NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/monolith-779c8d95f5   1         1         1       15h
replicaset.apps/orders-5bc6969d76     1         1         1       21s

Đầu ra này cho chúng ta thấy một số điều. Chúng ta có thể thấy Deployment hiện tại, ReplicaSet với số lượng nhóm mong muốn là 1 và Pod đang chạy. Có vẻ như mọi thứ đã được tạo thành công!

Hiển thị vùng chứa GKE

Chúng tôi đã triển khai ứng dụng của mình trên GKE, nhưng không có cách nào để truy cập vào ứng dụng đó bên ngoài cụm. Theo mặc định, các vùng chứa mà bạn chạy trên GKE không thể truy cập được từ Internet vì chúng không có địa chỉ IP ngoài. Bạn phải hiển thị rõ ràng ứng dụng của mình cho lưu lượng truy cập từ Internet thông qua tài nguyên Service. Dịch vụ cung cấp khả năng hỗ trợ mạng và IP cho các Pod của ứng dụng. GKE tạo một IP ngoài và một Trình cân bằng tải ( chịu phí) cho ứng dụng của bạn.

Khi triển khai dịch vụ Đơn đặt hàng, chúng tôi đã hiển thị dịch vụ này trên cổng 8081 nội bộ thông qua một bản triển khai Kubernetes. Để cung cấp dịch vụ này ra bên ngoài, chúng ta cần tạo một dịch vụ Kubernetes thuộc loại LoadBalancer để định tuyến lưu lượng truy cập từ cổng 80 bên ngoài đến cổng 8081 bên trong cho dịch vụ Đơn đặt hàng. Chạy lệnh sau để hiển thị trang web của bạn trên Internet:

kubectl expose deployment orders --type=LoadBalancer --port 80 --target-port 8081

Truy cập vào Dịch vụ

GKE chỉ định địa chỉ IP ngoài cho tài nguyên Dịch vụ chứ không phải tài nguyên Triển khai. Nếu muốn biết IP bên ngoài mà GKE đã cung cấp cho ứng dụng của bạn, bạn có thể kiểm tra Dịch vụ bằng lệnh kubectl get service:

kubectl get service orders

Kết quả:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
orders       10.3.251.122    203.0.113.0     80:30877/TCP     3d

Sau khi xác định địa chỉ IP ngoài cho ứng dụng của bạn, hãy sao chép địa chỉ IP đó. Hãy lưu lại để dùng cho bước tiếp theo khi chúng ta thay đổi monolith để trỏ đến dịch vụ Đơn đặt hàng mới!

Định cấu hình lại Monolith

Vì đã xoá dịch vụ Đơn đặt hàng khỏi ứng dụng nguyên khối, nên chúng ta sẽ phải sửa đổi ứng dụng nguyên khối để trỏ đến dịch vụ vi mô Đơn đặt hàng bên ngoài mới.

Khi phân tách một ứng dụng nguyên khối, chúng ta sẽ xoá các đoạn mã khỏi một cơ sở mã duy nhất thành nhiều đoạn mã và triển khai chúng riêng biệt. Vì vi dịch vụ đang chạy trên một máy chủ khác, nên chúng ta không thể tham chiếu các URL dịch vụ dưới dạng đường dẫn tuyệt đối nữa, mà cần phải định tuyến đến địa chỉ máy chủ mới của vi dịch vụ Đặt hàng. Xin lưu ý rằng thao tác này sẽ cần một khoảng thời gian ngừng hoạt động đối với dịch vụ nguyên khối để cập nhật URL cho từng dịch vụ đã được tách ra. Bạn nên tính đến điều này khi lên kế hoạch di chuyển các vi dịch vụ và ứng dụng nguyên khối sang môi trường sản xuất trong quá trình di chuyển vi dịch vụ.

Chúng ta cần cập nhật tệp cấu hình trong ứng dụng nguyên khối để trỏ đến địa chỉ IP của các vi dịch vụ Đơn đặt hàng mới. Sử dụng trình chỉnh sửa nano để thay thế URL cục bộ bằng địa chỉ IP của vi dịch vụ Đơn đặt hàng mới. Chạy lệnh sau để chỉnh sửa

cd ~/monolith-to-microservices/react-app
nano .env.monolith

Khi trình chỉnh sửa mở ra, tệp của bạn sẽ có dạng như sau:

REACT_APP_ORDERS_URL=/service/orders
REACT_APP_PRODUCTS_URL=/service/products

Thay thế REACT_APP_ORDERS_URL bằng định dạng mới trong khi thay thế bằng địa chỉ IP của vi dịch vụ Đơn đặt hàng để khớp với định dạng bên dưới:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=/service/products

Nhấn CTRL+O, nhấn ENTER, rồi nhấn CTRL+X để lưu tệp trong trình chỉnh sửa nano.

Bạn có thể kiểm thử vi dịch vụ mới bằng cách chuyển đến URL mà bạn vừa đặt trong tệp này. Trang web này sẽ trả về một phản hồi JSON từ vi dịch vụ Đơn đặt hàng của chúng tôi.

Tiếp theo, chúng ta sẽ cần tạo lại giao diện người dùng nguyên khối và lặp lại quy trình xây dựng để tạo vùng chứa cho nguyên khối và triển khai lại vào cụm GKE. Chạy các lệnh sau để hoàn tất các bước này:

Tạo lại tệp cấu hình Monolith

npm run build:monolith

Tạo vùng chứa Docker bằng Google Cloud Build

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0 .

Triển khai vùng chứa lên GKE

kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:2.0.0

Bạn có thể xác minh rằng ứng dụng hiện đang truy cập vào vi dịch vụ Đơn đặt hàng mới bằng cách chuyển đến ứng dụng nguyên khối trong trình duyệt và chuyển đến trang Đơn đặt hàng. Tất cả mã đơn đặt hàng phải có hậu tố là -MICROSERVICE như minh hoạ dưới đây:

1cdd60bb0d4d1148.png

7. Di chuyển sản phẩm sang dịch vụ vi mô

Tạo vi dịch vụ sản phẩm mới

Chúng ta có thể tiếp tục tách các dịch vụ bằng cách di chuyển dịch vụ Sản phẩm tiếp theo. Chúng ta sẽ làm theo quy trình tương tự như bước trước. Chạy các lệnh sau để tạo một vùng chứa Docker, triển khai vùng chứa và hiển thị vùng chứa đó thông qua một dịch vụ Kubernetes.

Tạo vùng chứa Docker bằng Google Cloud Build

cd ~/monolith-to-microservices/microservices/src/products
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/products:1.0.0 .

Triển khai vùng chứa lên GKE

kubectl create deployment products --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/products:1.0.0

Hiển thị vùng chứa GKE

kubectl expose deployment products --type=LoadBalancer --port 80 --target-port 8082

Tìm IP công khai của dịch vụ Sản phẩm theo cách tương tự như cách chúng ta đã làm cho dịch vụ Đơn đặt hàng bằng lệnh sau:

kubectl get service products

Kết quả:

NAME         CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
products     10.3.251.122    203.0.113.0     80:30877/TCP     3d

Lưu địa chỉ IP cho bước tiếp theo khi chúng tôi định cấu hình lại monolith để trỏ đến vi dịch vụ Sản phẩm mới.

Định cấu hình lại Monolith

Sử dụng trình chỉnh sửa nano để thay thế URL cục bộ bằng địa chỉ IP của các vi dịch vụ Sản phẩm mới:

cd ~/monolith-to-microservices/react-app
nano .env.monolith

Khi trình chỉnh sửa mở ra, tệp của bạn sẽ có dạng như sau:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=/service/products

Thay thế REACT_APP_PRODUCTS_URL bằng định dạng mới trong khi thay thế bằng địa chỉ IP của vi dịch vụ Sản phẩm để khớp với định dạng bên dưới:

REACT_APP_ORDERS_URL=http://<ORDERS_IP_ADDRESS>/api/orders
REACT_APP_PRODUCTS_URL=http://<PRODUCTS_IP_ADDRESS>/api/products

Nhấn CTRL+O, nhấn ENTER, rồi nhấn CTRL+X để lưu tệp trong trình chỉnh sửa nano.

Bạn có thể kiểm thử vi dịch vụ mới bằng cách chuyển đến URL mà bạn vừa đặt trong tệp này. Trang web phải trả về một phản hồi JSON từ vi dịch vụ Sản phẩm của chúng tôi.

Tiếp theo, chúng ta sẽ cần tạo lại giao diện người dùng nguyên khối và lặp lại quy trình xây dựng để tạo vùng chứa cho nguyên khối và triển khai lại vào cụm GKE. Chạy các lệnh sau để hoàn tất các bước này:

Tạo lại tệp cấu hình Monolith

npm run build:monolith

Tạo vùng chứa Docker bằng Google Cloud Build

cd ~/monolith-to-microservices/monolith
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:3.0.0 .

Triển khai vùng chứa lên GKE

kubectl set image deployment/monolith monolith=gcr.io/${GOOGLE_CLOUD_PROJECT}/monolith:3.0.0

Bạn có thể xác minh rằng ứng dụng của mình hiện đang truy cập vào vi dịch vụ Sản phẩm mới bằng cách chuyển đến ứng dụng nguyên khối trong trình duyệt và chuyển đến trang Sản phẩm. Tất cả tên sản phẩm phải có tiền tố là MS- như minh hoạ dưới đây:

5389b29f4b8c7c69.png

8. Di chuyển giao diện người dùng sang dịch vụ vi mô

Bước cuối cùng trong quy trình di chuyển là chuyển mã Giao diện người dùng sang một vi dịch vụ và tắt ứng dụng nguyên khối! Sau khi hoàn tất bước này, chúng ta sẽ di chuyển thành công monolith sang cấu trúc vi dịch vụ!

Tạo vi dịch vụ mới cho giao diện người dùng

Hãy làm theo quy trình tương tự như hai bước cuối cùng để tạo một vi dịch vụ giao diện người dùng mới.

Trước đây, khi xây dựng lại monolith, chúng tôi đã cập nhật cấu hình để trỏ đến monolith của mình, nhưng giờ đây, chúng tôi cần sử dụng cùng một cấu hình cho vi dịch vụ Frontend. Chạy các lệnh sau để sao chép tệp cấu hình URL của các vi dịch vụ vào cơ sở mã của vi dịch vụ Giao diện người dùng:

cd ~/monolith-to-microservices/react-app
cp .env.monolith .env
npm run build

Sau khi hoàn tất, chúng tôi sẽ làm theo quy trình tương tự như các bước trước. Chạy các lệnh sau để tạo một vùng chứa Docker, triển khai vùng chứa và hiển thị vùng chứa đó thông qua một dịch vụ Kubernetes.

Tạo vùng chứa Docker bằng Google Cloud Build

cd ~/monolith-to-microservices/microservices/src/frontend
gcloud builds submit --tag gcr.io/${GOOGLE_CLOUD_PROJECT}/frontend:1.0.0 .

Triển khai vùng chứa lên GKE

kubectl create deployment frontend --image=gcr.io/${GOOGLE_CLOUD_PROJECT}/frontend:1.0.0

Hiển thị vùng chứa GKE

kubectl expose deployment frontend --type=LoadBalancer --port 80 --target-port 8080

Xoá Monolith

Giờ đây, khi tất cả các dịch vụ của chúng tôi đang chạy dưới dạng các vi dịch vụ, chúng tôi có thể xoá ứng dụng nguyên khối của mình! Xin lưu ý rằng trong quá trình di chuyển thực tế, việc này cũng sẽ kéo theo các thay đổi về DNS, v.v. để các tên miền hiện có của chúng ta trỏ đến các vi dịch vụ giao diện người dùng mới cho ứng dụng. Chạy các lệnh sau để xoá monolith:

kubectl delete deployment monolith
kubectl delete service monolith

Kiểm thử công việc

Để xác minh mọi thứ đều hoạt động, địa chỉ IP cũ của bạn từ dịch vụ nguyên khối sẽ không hoạt động và địa chỉ IP mới của bạn từ dịch vụ giao diện người dùng sẽ lưu trữ ứng dụng mới. Để xem danh sách tất cả các dịch vụ và địa chỉ IP, hãy dùng lệnh sau:

kubectl get services

Kết quả đầu ra sẽ có dạng như sau:

NAME         TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
frontend     LoadBalancer   10.39.246.135   35.227.21.154    80:32663/TCP   12m
kubernetes   ClusterIP      10.39.240.1     <none>           443/TCP        18d
orders       LoadBalancer   10.39.243.42    35.243.173.255   80:32714/TCP   31m
products     LoadBalancer   10.39.250.16    35.243.180.23    80:32335/TCP   21m

Sau khi xác định địa chỉ IP ngoài cho vi dịch vụ Giao diện người dùng, hãy sao chép địa chỉ IP đó. Chuyển trình duyệt của bạn đến URL này (chẳng hạn như http://203.0.113.0) để kiểm tra xem giao diện người dùng của bạn có thể truy cập được hay không. Trang web của bạn sẽ giống như trước khi chúng tôi chia nhỏ ứng dụng nguyên khối thành các vi dịch vụ!

9. Dọn dẹp

Khi đã sẵn sàng, cách dễ nhất để dọn dẹp tất cả hoạt động đã thực hiện là xoá Dự án. Việc xoá dự án sẽ xoá tất cả tài nguyên đã được tạo trong Lớp học lập trình này để đảm bảo không phát sinh các khoản phí định kỳ không mong muốn. Thực thi lệnh sau trong Cloud Shell, trong đó PROJECT_ID là mã dự án đầy đủ chứ không chỉ là tên dự án.

gcloud projects delete [PROJECT_ID]

Xác nhận xoá bằng cách nhập "Y" khi được nhắc.

10. Xin chúc mừng!

Bạn đã phân tách thành công ứng dụng nguyên khối thành các vi dịch vụ và triển khai chúng trên Google Kubernetes Engine!

Các bước tiếp theo

Hãy xem các lớp học lập trình sau đây để tìm hiểu thêm về Kubernetes:

Tài nguyên khác