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.

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:


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.
- Để 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
(mất vài phút để cung cấp và kết nối với môi trường).
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:
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>
- 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.


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.

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.

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.

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:

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:

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:
- Triển khai, mở rộng quy mô và cập nhật trang web của bạn trên Google Kubernetes Engine
- Tạo một bot Slack bằng Node.js trên Kubernetes
- Phân phối liên tục đến Kubernetes bằng Spinnaker
- Triển khai một ứng dụng Java vào Kubernetes trên Google Kubernetes Engine
Tài nguyên khác
- Docker – https://docs.docker.com/
- Kubernetes – https://kubernetes.io/docs/home/
- Google Kubernetes Engine (GKE) – https://cloud.google.com/kubernetes-engine/docs/
- Google Cloud Build – https://cloud.google.com/cloud-build/docs/
- Google Container Registry – https://cloud.google.com/container-registry/docs/
- Di chuyển các ứng dụng nguyên khối sang các dịch vụ vi mô – https://cloud.google.com/solutions/migrating-a-monolithic-app-to-microservices-gke